Générer un point aléatoire à l'extérieur d'un rectangle donné dans une carte


15

introduction

Compte tenu de cette visualisation d'un terrain de jeu:

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

La carte entière sur laquelle le jeu est joué est le rectangle avec les coordonnées des coins (0,0) et (map_width, map_height). Les points éligibles pour le frai des ennemis sont l'Union

S=(UNE,B,C,)

Le défi

Écrivez du code qui renvoie un point aléatoire (x, y) qui est garanti d'être à l'intérieur de S. Votre code ne peut pas introduire de biais supplémentaire, ce qui signifie que la probabilité de chaque coordonnée est uniformément distribuée étant donné l'hypothèse que votre choix de générer de l'aléatoire (par exemple, fonction | bibliothèque | dev / urandom) est impartiale.

Les solutions les plus courtes en octets gagnent!

Contribution

Vous recevrez un total de 6 variables d'entrée entier positif dans l' ordre: map_width, map_height, W_top_left_x, W_top_left_y, W_width, W_height. Vous pouvez supposer que la surface (calculée) de toutes les régions (A, B, C, D, W) est chacune> 10, donc il n'y a pas d'espaces / régions vides.

Exemple d'entrée: 1000, 1000, 100, 100, 600, 400

L'entrée doit contenir les 6 valeurs décrites ci-dessus mais elle peut être transmise sous forme de moins d'arguments et dans n'importe quel ordre. Par exemple, le passage en (map_width, map_height)tant que tuple python est autorisé. Ce qui n'est pas autorisé, bien sûr, ce sont les paramètres calculés comme le point inférieur droit du W.

Production

2 entiers générés aléatoirement (x, y) où

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

OU

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

ce qui signifie qu'au moins une des expressions logiques ci-dessus doit être vraie.

Exemples

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

Pour plus de détails et les limitations d'entrée / sortie, veuillez vous référer aux règles d'entrée / sortie par défaut


Je pense que vous devriez déclarer explicitement que les coordonnées de sortie sont des entiers (que j'infère comme votre intention implicite).
agtoever

1
Pouvons-nous utiliser les règles d'entrée / sortie par défaut ?
Nick Kennedy

1
@agtoever il le dit dans la section "sortie"; 2 randomly generated integers (x, y)
Giuseppe

1
pouvons-nous prendre les entrées dans un ordre différent (cohérent)?
attinat

@agtoever yes la sortie doit être un nombre entier comme indiqué dans la section "sortie".
jaaq

Réponses:


7

Python 2 , 114 106 102 102 101 octets

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*

Essayez-le en ligne!


Je ne suis pas sûr mais je pense que cela devrait être [i%w, i/w] parce que la plage w*h/w=hmais x est liée à la largeur dans cet exemple et non à la hauteur.
jaaq

@jaaq Ouais, tu as raison. Fixé maintenant, merci :)
TFeld

Je viens de vérifier le contenu de la liste que vous générez et il semble que votre solution soit incorrecte. Le traçage des points montre que toutes les valeurs sont le long d'une ligne et ne remplissent pas la région entière de S comme prévu. La liste que vous générez contient également des valeurs non entières.
jaaq

@jaaq Je ne sais pas ce que tu veux dire? Les coordonnées sont toujours des entiers, et non sur une ligne ( par exemple )
TFeld

1
@jaaq En Python 2, a/best déjà la division au sol, si aet bsont des entiers (qu'ils sont ici).
TFeld

4

R , 89 73 octets

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

Essayez-le en ligne!

Prend l'entrée comme width,height,c(X,Y),c(W,H).

[0,w]×[0,h]


4

05AB1E , 23 21 20 18 17 octets

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

L'entrée est au format [map_width, map_height], [W_top_left_x, W_top_left_y], [W_width, W_height].

Merci à @Grimy pour -1 octet, et aussi pour m'avoir fait réaliser que j'avais introduit un bug après ma dernière édition.

Essayez-le en ligne , sortez 10 sorties possibles en même temps ou vérifiez toutes les coordonnées possibles . (Remarque mineure: j'ai diminué l'exemple d'entrée d'un facteur 10, car le filtre et le choix aléatoire intégré sont assez lents pour les grandes listes.)

Explication:

Les entrées map_width, map_height, [W_top_left_x, W_top_left_y], [W_width, W_height]sont désignées [Wm, Hm], [x, y], [w, h]ci-dessous:

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
Merci d'avoir ajouté la partie de vérification :) excellente solution!
jaaq

1
@jaaq Merci! J'ai moi-même utilisé le vérificateur après ma version initiale, c'est à ce moment-là que j'ai remarqué un bug que je devais corriger, car il incluait les coordonnées [map_height, 0]comme sortie aléatoire possible sans le ¨. :)
Kevin Cruijssen

*ݨ¹‰pourrait être L`â<en prenant les deux premières entrées comme [map_height, map_width]. Aussi IIpourrait être Š, à moins que quelque chose me manquait.
Grimmy

@Grimy Merci pour le L`â<. Quant à l' II+à Š+, vous êtes en effet droit que ce serait la même .. Malheureusement , je fait une erreur moi - même et il aurait dû être au ²³+lieu de II+, car il utiliserait la troisième entrée pour les deux I(comme cela prendrait deux fois les troisième entrée avec Š) après la première itération du filtre .. Donc implicitement merci de m'avoir fait réaliser que j'avais un bug. :)
Kevin Cruijssen


3

PowerShell , 85 73 octets

-12 octets grâce à mazzy

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

Essayez-le en ligne!

Belle réponse simple qui bricole un tableau composé de la plage de valeurs pour chaque dimension, puis en choisit une au hasard pour xet y. Parvient à réutiliser la plupart du code en premier traitement x, puis écraser $xavec $yet courir à nouveau.


1
vous pouvez économiser quelques octets Essayez-le en ligne!
mazzy

1
@mazzy En fait, je suis tombé sur l'optimisation de la plage, mais je l'ai appliquée à l'envers, économisant 0 octets.
Veskah


1

Gelée , 11 octets

p/’$€+2¦ḟ/X

Essayez-le en ligne!

Un lien dyadique qui prend deux arguments, [map_width, map_height], [W_width, W_height]et , W_left, W_topet retourne un point choisis au hasard répondant aux exigences.

Explication

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

L'entrée doit être sous la forme de ((map_width, W_top_left_x, W_width),(map_height, W_top_left_y, W_height))

La sortie est donnée sous la forme: [[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

Essayez-le en ligne!

Sorties aléatoires obtenues à partir de l'exemple d'entrée:

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



0

Fusain , 55 43 octets

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

Essayez-le en ligne! Le lien est vers la version détaillée du code. Explication:

NθNη

Saisissez la taille de la carte. (S'ils étaient les derniers, je pourrais entrer la hauteur en ligne pour une sauvegarde d'un octet.)

FE²N⊞υ⟦ιN⟧

Saisissez le rectangle intérieur. (Si je pouvais entrer dans la commande, left, width, top, heightje pourrais l'utiliser F²⊞υE²Npour une économie de 3 octets.)

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

Générez une liste de toutes les coordonnées sur le terrain.

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

Filtrer les entrées où les deux coordonnées se trouvent à l'intérieur du rectangle.

I‽...

Imprime un élément aléatoire de ceux qui restent.



0

Scala , 172 octets

Aléatoire? Je t'ai eu.

(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}

Une mise en œuvre amusante à laquelle je pouvais penser.
Comment ça marche : Générez une paire aléatoire dans la carte. S'il se trouve dans le rectangle intérieur, réessayez.
Essayez-le en ligne!


0

J , 54 47 45 39 octets

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

Essayez-le en ligne!

Prenez l'entrée comme une grille 3 x 2 comme:

grid_height  grid_width
inner_top    inner_left
inner_height inner_width
  • Choisissez un point aléatoire sur toute la grille: 0?@{[
  • Déplacez-le vers la gauche et vers le bas par le point supérieur gauche du rectangle intérieur: (-1&{)~
  • Revenez à l'étape 1 si l'endroit choisi se trouve dans (<*/@,0<:[)le rectangle intérieur décalé de façon similaire2{[ . Sinon, renvoyez le point aléatoire d'origine non décalé.
  • Gravez l'ensemble du processus avec un point que nous savons invalide, à savoir le point supérieur gauche du rectangle intérieur, défini par les éléments 2 et 3 de la liste d'entrée: {~&1

Une autre approche, 45 octets

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

Essayez-le en ligne!

Celui-ci est conceptuellement plus simple et ne dérange pas avec la boucle. Au lieu de cela, nous construisons une matrice de tous les nombres de 0 à (lxh), la décalons par le point de départ interne, prenons uniquement les points de la sous-grille (0, 0) à (w interne, h interne), les supprimons de l'ensemble grille après aplatissement des deux, choisissez-en un au hasard parmi le reste, et reconvertissez l'entier en un point en utilisant divmod<.@% , |~

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.