Genera un punto casuale al di fuori di un determinato rettangolo all'interno di una mappa


15

introduzione

Data questa visualizzazione di un campo da gioco:

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

L'intera mappa su cui si gioca è il rettangolo con le coordinate angolari (0,0) e (map_width, map_height). I punti che possono essere generati dai nemici sono l'Unione

S=(UN,B,C,D)

La sfida

Scrivi il codice che restituisce un punto casuale (x, y) che è garantito essere all'interno di S. Il tuo codice non può introdurre alcun bias aggiuntivo, il che significa che la probabilità di ciascuna coordinata è distribuita uniformemente dato il presupposto che la tua scelta di generare casualità (ad es. Funzione | library | dev / urandom) è imparziale.

Le soluzioni più brevi in ​​byte vincono!

Ingresso

Vi sarà dato un totale di 6 variabili di input interi positivi in ordine: map_width, map_height, W_top_left_x, W_top_left_y, W_width, W_height. Puoi presumere che l'area (calcolata) di tutte le regioni (A, B, C, D, W) sia ciascuna> 10, quindi non ci sono spazi / regioni vuoti.

Esempio di input: 1000, 1000, 100, 100, 600, 400

L'input deve contenere i 6 valori sopra descritti ma può essere passato come minor numero di argomenti e in qualsiasi ordine. Ad esempio (map_width, map_height), è consentito il passaggio come tupla di pitone. Ciò che non è permesso ovviamente sono parametri calcolati come il punto in basso a destra della W.

Produzione

2 numeri interi generati casualmente (x, y) dove

(0X<map_width)¬(W_top_left_xX<W_top_left_x+view_width)

O

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

significa che almeno una delle espressioni logiche sopra deve essere vera.

Esempi

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

Per dettagli e limitazioni per input / output, consultare le regole di input / output predefinite


Penso che dovresti dichiarare esplicitamente che le coordinate di output sono numeri interi (che deduco come tua intenzione implicita).
agtoever,


1
@agtoever lo dice nella sezione "output"; 2 randomly generated integers (x, y)
Giuseppe

1
possiamo prendere input in un ordine diverso (coerente)?
attinat

@agtoever yes l'output deve essere un numero intero come indicato nella sezione "output".
Jaaq

Risposte:


7

Python 2 , 114 106 102 101 byte

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*

Provalo online!


Non sono sicuro, ma penso che dovrebbe essere [i%w, i/w] perché l'intervallo w*h/w=hma x è legato alla larghezza in questo esempio non all'altezza.
Jaaq

@jaaq Sì, hai ragione. Risolto ora, grazie :)
TFeld

Ho appena controllato il contenuto dell'elenco generato e sembra che la tua soluzione sia errata. Tracciare i punti mostra che tutti i valori sono lungo una linea e non riempiono l'intera regione di S come previsto. Anche l'elenco che generi contiene valori non interi.
Jaaq

@jaaq Non sono sicuro di cosa intendi? Le coordinate sono sempre numeri interi e non su una linea ( ad es. )
TFeld

1
@jaaq In Python 2, a/bè già la divisione del piano, se ae bsono numeri interi (che sono qui).
TFeld

4

R , 89 73 byte

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

Provalo online!

Accetta input come width,height,c(X,Y),c(W,H).

Campioni da [0,w]×[0,h] uniformemente fino a quando non trova un punto esterno al rettangolo interno.


4

05AB1E , 23 21 20 18 17 byte

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

L'input è nel formato [map_width, map_height], [W_top_left_x, W_top_left_y], [W_width, W_height].

Grazie a @Grimy per -1 byte e anche per avermi fatto capire che ho introdotto un bug dopo l'ultima modifica.

Provalo online , invia 10 possibili uscite contemporaneamente o verifica tutte le coordinate possibili . (Nota minore: ho ridotto l'input di esempio di un fattore 10, perché il filtro e la scelta casuale incorporati non sono abbastanza lenti per le grandi liste.)

Spiegazione:

Gli ingressi map_width, map_height, [W_top_left_x, W_top_left_y], [W_width, W_height]sono indicati di [Wm, Hm], [x, y], [w, h]seguito:

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
Grazie per aver aggiunto la parte di verifica :) ottima soluzione!
Jaaq

1
@jaaq Grazie! Ho usato il verificatore da solo dopo la mia versione iniziale, che è quando ho notato un bug che ho dovuto correggere, poiché includeva le coordinate [map_height, 0]come output casuale possibile senza il ¨. :)
Kevin Cruijssen il

*ݨ¹‰potrebbe essere L`â<prendendo i primi due input come [map_height, map_width]. Inoltre IIpotrebbe essere Š, a meno che non mi sia perso qualcosa.
Grimmy,

@Grimy Grazie per il L`â<. Per quanto riguarda il II+to Š+, hai davvero ragione che sarebbe lo stesso .. Purtroppo ho fatto un errore me stesso e avrebbe dovuto essere ²³+invece di II+, poiché avrebbe usato il terzo input per entrambi I(proprio come richiederebbe due volte il terzo input con Š) dopo la prima iterazione del filtro .. Quindi implicitamente grazie per avermi fatto capire che avevo un bug. :)
Kevin Cruijssen l'


3

PowerShell , 85 73 byte

-12 byte grazie a mazzy

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

Provalo online!

Bella semplice risposta che mette insieme un array composto dall'intervallo di valori per ogni dimensione e quindi ne sceglie uno a caso per xe y. Riesce a riutilizzare la maggior parte del codice prima trasformazione x, poi sovrascrittura $xcon $yed eseguirlo nuovamente.


1
puoi risparmiare qualche byte Provalo online!
mazzy,

1
@mazzy In realtà mi sono imbattuto nell'ottimizzazione della gamma ma l'ho applicato all'indietro, risparmiando 0 byte.
Veskah,


1

Gelatina , 11 byte

p/’$€+2¦ḟ/X

Provalo online!

Un collegamento diadico che accetta due argomenti [map_width, map_height], [W_width, W_height]eW_left, W_top e restituisce un punto selezionato in modo casuale soddisfare i requisiti.

Spiegazione

   $€       | 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 byte

L'input dovrebbe essere sotto forma di ((map_width, W_top_left_x, W_width),(map_height, W_top_left_y, W_height))

L'output è dato nel modulo: [[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

Provalo online!

Uscite casuali ottenute dall'ingresso di esempio:

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



0

Carbone , 55 43 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

NθNη

Inserisci la dimensione della mappa. (Se fossero gli ultimi, potrei inserire l'altezza in linea per un salvataggio di 1 byte.)

FE²N⊞υ⟦ιN⟧

Inserisci il rettangolo interno. (Se potessi inserire nell'ordineleft, width, top, height allora potrei usare F²⊞υE²Nper un salvataggio di 3 byte.)

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

Genera un elenco di tutte le coordinate nel campo.

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

Filtra le voci in cui entrambe le coordinate si trovano all'interno del rettangolo.

I‽...

Stampa un elemento casuale di quelli rimasti.



0

Scala , 172 byte

Casualità? 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}

Un'implementazione divertente che mi viene in mente.
Come funziona : genera una coppia casuale nella mappa. Se si trova nel rettangolo interno, riprova.
Provalo online!


0

J , 54 47 45 39 byte

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

Provalo online!

Prendi input come una griglia 3 x 2 come:

grid_height  grid_width
inner_top    inner_left
inner_height inner_width
  • Scegli un punto casuale sull'intera griglia: 0?@{[
  • Spostalo a sinistra e in basso dal punto in alto a sinistra del rettangolo interno: (-1&{)~
  • Tornare al passaggio 1 se il punto scelto si trova all'interno (<*/@,0<:[)del rettangolo interno spostato in modo simile 2{[. Altrimenti restituisce il punto casuale originale, non spostato.
  • Semina l'intero processo con un punto che sappiamo non è valido, vale a dire il punto in alto a sinistra del rettangolo interno, definito dagli elementi 2 e 3 dell'elenco di input: {~&1

Un altro approccio, 45 byte

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

Provalo online!

Questo è concettualmente più semplice e non si preoccupa del looping. Invece, costruiamo una matrice di tutti i numeri da 0 a (wxh), la spostiamo dal punto iniziale interno, prendiamo solo i punti nella sottogriglia (0, 0) a (interno w, innner h), rimuovendoli dal totale griglia dopo averli appiattiti entrambi, sceglierne uno a caso dal resto e riconvertire l'intero in un punto usando divmod<.@% , |~

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.