Wygeneruj losowy punkt poza danym prostokątem na mapie


15

Wprowadzenie

Biorąc pod uwagę tę wizualizację pola gry:

(0,0)
+----------------------+(map_width, 0)
|           A          |
|-----+-----------+----|
|  D  |     W     | B  |
|-----+-----------+----|
|           C          |
+----------------------+(map_width, map_height)
(0, map_height)

Cała mapa, na której gra się, to prostokąt z współrzędnymi narożnymi (0,0) i (szerokość_kresu, wysokość_kresu). Punkty kwalifikujące się do odradzania wrogów to Unia

S.=(ZA,b,do,re)

Wyzwanie

Napisz kod, który zwraca losowy punkt (x, y), który z pewnością znajduje się w środku S. Twój kod nie może wprowadzić żadnych dodatkowych odchyleń, co oznacza, że ​​prawdopodobieństwo każdej współrzędnej rozkłada się równomiernie, przy założeniu, że twój wybór generowania losowości (np. Funkcja | biblioteka | dev / urandom) jest bezstronna.

Najkrótsze rozwiązania w bajtach wygrywają!

Wejście

Będziesz mieć łącznie 6 pozytywnych zmiennych wejściowych całkowitą w kolejności: map_width, map_height, W_top_left_x, W_top_left_y, W_width, W_height. Możesz założyć, że (obliczona) powierzchnia wszystkich regionów (A, B, C, D, W) wynosi> 10, więc nie ma pustych przestrzeni / regionów.

Przykładowe dane wejściowe: 1000, 1000, 100, 100, 600, 400

Dane wejściowe muszą zawierać 6 wartości opisanych powyżej, ale można je przekazać jako mniejszą liczbę argumentów w dowolnej kolejności. Na przykład przekazywanie (map_width, map_height)jako krotka python jest dozwolone. Oczywiście nie jest dozwolone obliczanie parametrów takich jak dolny prawy punkt W.

Wynik

2 losowo generowane liczby całkowite (x, y) gdzie

(0x<map_width)¬(W_top_left_xx<W_top_left_x+view_width)

LUB

(0y<map_height)¬(W_top_left_yy<W_top_left_y+view_height)

co oznacza, że ​​co najmniej jedno z powyższych wyrażeń logicznych musi być prawdziwe.

Przykłady

Input                                    Output(valid random samples)

1000 1000 100 100 600 400                10 10
1000 1000 100 100 600 400                800 550
1000 1000 100 100 600 400                800 10
1000 1000 100 100 600 400                10 550

Szczegółowe informacje i ograniczenia dotyczące wejścia / wyjścia znajdują się w domyślnych zasadach wejścia / wyjścia


Myślę, że powinieneś wyraźnie stwierdzić, że współrzędne wyjściowe są liczbami całkowitymi (które domyślam się jako twoja niejawna intencja).
agtoever


1
@agtoever tak mówi w sekcji „wyjście”; 2 randomly generated integers (x, y)
Giuseppe,

1
czy możemy przyjmować dane wejściowe w innej (spójnej) kolejności?
attinat

@agtoever yes wyjście musi być liczbami całkowitymi, jak podano w sekcji „output”.
jaaq,

Odpowiedzi:


7

Python 2 , 114 106 102 101 bajtów

lambda w,h,X,Y,W,H:choice([(i%w,i/w)for i in range(w*h)if(W>i%w-X>-1<i/w-Y<H)<1])
from random import*

Wypróbuj online!


Nie jestem pewien, ale myślę, że tak powinno być, [i%w, i/w] ponieważ zakres, w*h/w=hale x jest związany w tym przykładzie z szerokością, a nie z wysokością.
jaaq,

@jaaq Tak, masz rację. Naprawiono teraz, dzięki :)
TFeld

Właśnie sprawdziłem zawartość generowanej listy i wydaje się, że twoje rozwiązanie jest nieprawidłowe. Wykreślenie punktów pokazuje, że wszystkie wartości są wzdłuż linii i nie wypełniają całego regionu S zgodnie z przeznaczeniem. Również tworzona lista zawiera wartości całkowite.
jaaq,

@jaaq Nie jestem pewien, co masz na myśli? Współrzędne są zawsze liczbami całkowitymi, a nie na linii ( np. )
TFeld

1
@jaaq W Pythonie 2 a/bjest już podział na piętra, jeśli ai bsą liczbami całkowitymi (które są tutaj).
TFeld,

4

R , 89 73 bajtów

function(w,h,K,D,`*`=sample){while(all((o<-c(0:w*1,0:h*1))<=K+D&o>K))0
o}

Wypróbuj online!

Pobiera dane wejściowe jako width,height,c(X,Y),c(W,H).

[0,w]×[0,h]


4

05AB1E , 23 21 20 18 17 bajtów

L`â<ʒ²³+‹y²@«P≠}Ω

Dane wejściowe są w formacie [map_width, map_height], [W_top_left_x, W_top_left_y], [W_width, W_height].

Dzięki @Grimy za -1 bajt, a także za uświadomienie mi, że wprowadziłem błąd po mojej ostatniej edycji.

Wypróbuj online , wypisz 10 możliwych wyników jednocześnie lub sprawdź wszystkie możliwe współrzędne . (Drobna uwaga: Zmniejszyłem przykładowe dane wejściowe o współczynnik 10, ponieważ wbudowane filtry i losowy wybór są dość wolne dla dużych list).

Wyjaśnienie:

Dane wejściowe map_width, map_height, [W_top_left_x, W_top_left_y], [W_width, W_height]są określone [Wm, Hm], [x, y], [w, h]poniżej:

L          # Convert the values of the first (implicit) input to an inner list in
           # the range [1, n]: [[1,2,3,...,Wm],[1,2,3,....,Hm]]
 `         # Push both inner lists separated to the stack
  â        # Get the cartesian product of both lists, creating each possible pair
   <       # Decrease each pair by 1 to make it 0-based
           # (We now have: [[0,0],[0,1],[0,2],...,[Wm,Hm-2],[Wm,Hm-1],[Wm,Hm]])
    ʒ      # Filter this list of coordinates [Xr, Yr] by:
     ²³+   #  Add the next two inputs together: [x+w, y+h]
          #  Check for both that they're lower than the coordinate: [Xr<x+w, Yr<y+h]
     y     #  Push the coordinate again: [Xr, Yr]
      ²    #  Push the second input again: [x, y]
       @   #  Check for both that the coordinate is larger than or equal to this given 
           #  input: [Xr>=x, Yr>=y] (the w,h in the input are ignored)
     «     #  Merge it with the checks we did earlier: [Xr<x+w, Yr<y+h, Xr>=x, Yr>=y]
      P   #  And check if any of the four is falsey (by taking the product and !=1,
           #  or alternatively `ß_`: minimum == 0)
         # After the filter: pick a random coordinate
           # (which is output implicitly as result)

1
Dziękujemy za dodanie części weryfikacyjnej :) świetne rozwiązanie!
jaaq,

1
@jaaq Thanks! Sam użyłem weryfikatora po mojej początkowej wersji, kiedy zauważyłem błąd, który musiałem naprawić, ponieważ zawierał on koordynację, [map_height, 0]jak to możliwe, losowy wynik bez ¨. :)
Kevin Cruijssen

*ݨ¹‰może być L`â<przyjmowanie pierwszych dwóch danych wejściowych jako [map_height, map_width]. Mogę też IIbyć Š, chyba że coś przeoczyłem.
Grimmy,

@Grimy Dzięki za L`â< . Co do II+celu Š+, jesteś rzeczywiście prawda, że byłoby to samo .. Niestety ja sam popełnił błąd i powinno być ²³+zamiast II+, ponieważ byłoby użyć trzeciego wejścia dla obu I(podobnie jak zajęłoby dwa razy więcej trzecie wejście z Š) po pierwszej iteracji filtra .. Więc domyślnie dziękuję za uświadomienie mi, że mam błąd. :)
Kevin Cruijssen


3

PowerShell , 85 73 bajtów

-12 bajtów dzięki mazzy

param($a,$b,$x,$y,$w,$h)$a,$b|%{0..--$x+($x+$w+2)..$_|random
$x,$w=$y,$h}

Wypróbuj online!

Ładna prosta odpowiedź, która łączy tablicę z zakresu wartości dla każdego wymiaru, a następnie wybiera jedną losowo dla xi y. Prowadzi do ponownego wykorzystania najbardziej kodu z pierwszej obróbki x, a następnie zastąpieniem $xw$y i uruchamiając ponownie.


1
możesz zaoszczędzić kilka bajtów Wypróbuj online!
mazzy

1
@ mazzy Właściwie natknąłem się na optymalizację zakresu, ale zastosowałem ją wstecz, oszczędzając 0 bajtów.
Veskah


1

Galaretka , 11 bajtów

p/’$€+2¦ḟ/X

Wypróbuj online!

Dyadyczny link, który wymaga dwóch argumentów, [map_width, map_height], [W_width, W_height] a W_left, W_topi zwraca losowo wybrany punkt spełniająca wymagania.

Wyjaśnienie

   $€       | For each of member of the left argument, do the following as a monad:
p/          | - Reduce using Cartesian product (will generate [1,1],[1,2],... up to the width and height of each of the rectangles)
  ’         | - Decrease by 1 (because we want zero-indexing)
     +2¦    | Add the right argument to the second element of the resulting list
        ḟ/  | Reduce by filtering members of the second list from the first
          X | Select a random element

1

Python 2 , 100 bajtów

Dane wejściowe powinny mieć postać ((map_width, W_top_left_x, W_width),(map_height, W_top_left_y, W_height))

Dane wyjściowe są podane w postaci: [[x],[y]]

lambda C:[c(s(r(i[0]))-s(r(i[1],i[1]+i[2])),1)for i in C]
from random import*;c=sample;r=range;s=set

Wypróbuj online!

Losowe dane wyjściowe uzyskane z przykładowego wejścia:

[[72], [940]]
[[45], [591]]
[[59], [795]]
[[860], [856]]
[[830], [770]]
[[829], [790]]
[[995], [922]]
[[23], [943]]
[[761], [874]]
[[816], [923]]



0

Węgiel , 55 43 bajtów

NθNηFE²N⊞υ⟦ιN⟧I‽ΦE×θη⟦﹪ιθ÷ιθ⟧⊙υ∨‹§ιμ§λ⁰¬‹§ιμΣλ

Wypróbuj online! Link jest do pełnej wersji kodu. Wyjaśnienie:

NθNη

Podaj rozmiar mapy. (Gdyby były ostatnie, mógłbym wprowadzić wysokość w linii, aby zaoszczędzić 1 bajt.)

FE²N⊞υ⟦ιN⟧

Wprowadź wewnętrzny prostokąt. (Gdybym mógł wprowadzić kolejność left, width, top, height, mógłbym użyć F²⊞υE²Ndo zapisania 3 bajtów).

E×θη⟦﹪ιθ÷ιθ⟧

Wygeneruj listę wszystkich współrzędnych w terenie.

Φ...⊙υ∨‹§ιμ§λ⁰¬‹§ιμΣλ

Filtruj wpisy, w których obie współrzędne leżą wewnątrz prostokąta.

I‽...

Wydrukuj losowy element pozostałych.



0

Scala , 172 bajty

Losowość? Gotcha

(a:Int,b:Int,c:Int,d:Int,e:Int,f:Int)=>{var r=new scala.util.Random
var z=(0,0)
do{z=(r.nextInt(a),r.nextInt(b))}while((c to e+c contains z._1)|(d to e+d contains z._2))
z}

Zabawna implementacja, o której mogłem pomyśleć.
Jak to działa : Wygeneruj losową parę na mapie. Jeśli jest w wewnętrznym prostokącie, spróbuj ponownie.
Wypróbuj online!


0

J , 54 47 45 39 bajtów

(0?@{[)^:((-1&{)~(<*/@,0<:[)2{[)^:_{~&1

Wypróbuj online!

Weź dane jako siatkę 3 x 2, np .:

grid_height  grid_width
inner_top    inner_left
inner_height inner_width
  • Wybierz losowy punkt na całej siatce: 0?@{[
  • Przesuń go w lewo i w dół o lewy górny punkt wewnętrznego prostokąta: (-1&{)~
  • Wróć do kroku 1, jeśli wybrane miejsce znajduje się w (<*/@,0<:[)podobnie przesuniętym wewnętrznym prostokącie2{[ . W przeciwnym razie zwróć oryginalny, nieprzesunięty losowy punkt.
  • Zasiej cały proces punktem, o którym wiemy, że jest nieprawidłowy, a mianowicie lewym górnym punktem prostokąta wewnętrznego, zdefiniowanego przez elementy 2 i 3 listy wejściowej: {~&1

Inne podejście, 45 bajtów

{.#:i.@{.(?@#{])@-.&,([:<@;&i./{:){1&{|.i.@{.

Wypróbuj online!

Ten jest koncepcyjnie prostszy i nie przeszkadza w zapętlaniu. Zamiast tego tworzymy macierz wszystkich liczb od 0 do (wxh), przesuwamy ją o wewnętrzny punkt początkowy, chwytamy tylko punkty w podsieci (0, 0) do (wewnętrzna w, wewnętrzna h), usuwamy je z całości siatki po spłaszczeniu obu, wybierz jedną losowo z reszty i przekonwertuj liczbę całkowitą z powrotem na punkt za pomocą divmod<.@% , |~

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.