Erzeugen Sie einen zufälligen Punkt außerhalb eines bestimmten Rechtecks ​​innerhalb einer Karte

15

Einführung

Angesichts dieser Visualisierung eines Spielfelds:

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

Die gesamte Karte, auf der das Spiel gespielt wird, ist das Rechteck mit den Eckkoordinaten (0,0) und (map_width, map_height). Die Punkte, die für das Laichen von Feinden in Frage kommen, sind: Union

S=(A,B,C,D)

Die Herausforderung

Schreiben Sie Code, der einen zufälligen Punkt (x, y) zurückgibt, der garantiert innerhalb von S liegt. Ihr Code kann keine zusätzliche Verzerrung einführen, was bedeutet, dass die Wahrscheinlichkeit jeder Koordinate unter der Annahme, dass Sie Zufälligkeit erzeugen (z. B. Funktion), gleichmäßig verteilt ist | library | dev / urandom) ist unvoreingenommen.

Kürzeste Lösungen in Bytes gewinnen!

Eingang

Sie erhalten insgesamt 6 positive ganzzahlige Eingabevariablen in der Reihenfolge: map_width, map_height, W_top_left_x, W_top_left_y, W_width, W_height . Sie können davon ausgehen, dass die (berechnete) Oberfläche aller Regionen (A, B, C, D, W) jeweils> 10 ist, sodass keine Leerstellen / Regionen vorhanden sind.

Beispiel Eingabe: 1000, 1000, 100, 100, 600, 400

Die Eingabe muss die oben beschriebenen 6 Werte enthalten, kann jedoch als weniger Argumente und in beliebiger Reihenfolge übergeben werden. Zum Beispiel vorbei(map_width, map_height) als Python-Tupel erlaubt. Was natürlich nicht erlaubt ist, sind berechnete Parameter wie der untere rechte Punkt des W.

Ausgabe

2 zufällig generierte ganze Zahlen (x, y) wobei

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

ODER

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

Mindestens einer der obigen logischen Ausdrücke muss wahr sein.

Beispiele

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

Einzelheiten und Einschränkungen für die Ein- / Ausgabe finden Sie in den Standard-Ein- / Ausgaberegeln

jaaq
quelle
Ich denke, Sie sollten explizit angeben, dass die Ausgabekoordinaten Ganzzahlen sind (was ich als Ihre implizite Absicht schlussfolgere).
Am
1
Können wir die Standard-Eingabe- / Ausgaberegeln verwenden ?
Nick Kennedy
1
@agtoever es sagt so im Abschnitt "Ausgabe"; 2 randomly generated integers (x, y)
Giuseppe
1
Dürfen wir Eingaben in einer anderen (konsistenten) Reihenfolge vornehmen?
7.
@agtoever yes output muss eine Ganzzahl sein, wie im Abschnitt "output" angegeben.
Jaaq

Antworten:

7

Python 2 , 114 106 102 101 Bytes

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*

Probieren Sie es online!

TFeld
quelle
Ich bin mir nicht sicher, aber ich denke, es sollte sein, [i%w, i/w] weil der Bereich w*h/w=haber x auf die Breite in diesem Beispiel nicht die Höhe gebunden ist.
Jaaq
@jaaq Ja, du hast recht. Jetzt
behoben
Ich habe gerade den Inhalt der Liste überprüft, die Sie erstellen, und es scheint, dass Ihre Lösung falsch ist. Das Zeichnen der Punkte zeigt, dass sich alle Werte entlang einer Linie befinden und nicht den gesamten Bereich von S wie beabsichtigt ausfüllen. Die Liste, die Sie generieren, enthält auch nicht ganzzahlige Werte.
Jaaq
@jaaq Ich bin nicht sicher, was du meinst? Die Koordinaten sind immer ganze Zahlen und nicht auf einer Linie ( zB )
TFeld
1
@jaaq In Python 2 gibt a/bes bereits Bodenteilung , wenn aund bsind ganze Zahlen (die sie hier sind).
TFeld
4

R , 89 73 Bytes

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

Probieren Sie es online!

Übernimmt die Eingabe als width,height,c(X,Y),c(W,H).

Samples von [0,w]×[0,h] gleichmäßig, bis ein Punkt außerhalb des inneren Rechtecks ​​gefunden wird.

Giuseppe
quelle
4

05AB1E , 23 21 20 18 17 Bytes

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

Die Eingabe erfolgt im Format [map_width, map_height], [W_top_left_x, W_top_left_y], [W_width, W_height].

Dank an @Grimy für -1 Byte und auch dafür, dass ich , dass ich nach meiner letzten Bearbeitung einen Fehler eingeführt habe.

Probieren Sie es online aus und geben Sie 10 mögliche Ausgaben gleichzeitig aus oder überprüfen Sie alle möglichen Koordinaten . (Kleinere Anmerkung: Ich habe die Beispieleingabe um den Faktor 10 verringert, da der Filter und die Zufallsauswahl für große Listen ziemlich langsam sind.)

Erläuterung:

Die Eingänge map_width, map_height, [W_top_left_x, W_top_left_y], [W_width, W_height]werden wie [Wm, Hm], [x, y], [w, h]folgt bezeichnet:

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)
Kevin Cruijssen
quelle
1
Vielen Dank für das Hinzufügen des Verifizierungsteils :) Tolle Lösung!
Jaaq
1
@jaaq Danke! Ich habe den Prüfer nach meiner ersten Version selbst verwendet. Als ich einen Fehler bemerkte, den ich beheben musste, schloss er die Koordinaten [map_height, 0]als mögliche Zufallsausgabe ohne den ein ¨. :)
Kevin Cruijssen
*ݨ¹‰könnte sein, L`â<indem man die ersten beiden eingaben als [map_height, map_width]. Könnte IIauch sein Š, es sei denn ich habe etwas verpasst.
Grimmy
@ Grimy Danke für die L`â<. Wie für die II+zuŠ+Englisch: www.mjfriendship.de/en/index.php?op...=view&id=167 angeht, hast du in der Tat Recht, dass es das Gleiche wäre. Leider habe ich selbst einen Fehler gemacht und es hätte ²³+stattdessen sein müssen II+, da es den dritten Eingang für beide verwenden würde I(genau wie es das Zweifache dauern würde) dritte Eingabe mit Š) nach der ersten Iteration des Filters. Also implizit danke, dass ich gemerkt habe, dass ich einen Fehler hatte. :)
Kevin Cruijssen
3

Power , 85 73 Bytes

-12 bytes dank mazzy

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

Probieren Sie es online!

Schöne einfache Antwort, die ein Array aus den Wertebereichen für jede Dimension zusammenfügt und dann nach dem Zufallsprinzip für xund auswählt y. Leitet die meisten des Codes durch erste Bearbeitung wiederverwenden x, dann das Überschreiben $xmit $yund läuft es wieder.

Veskah
quelle
1
Sie können ein paar Bytes sparen Probieren Sie es online!
mazzy
1
@mazzy Ich bin tatsächlich über die Bereichsoptimierung gestolpert, habe sie jedoch rückwärts angewendet und dabei 0 Byte gespart.
Veskah,
1

Julia , 76 71 67 Bytes

f(w,h,a,b,c,d)=rand(setdiff((0:w-1)'.=>0:h-1,(a:a+c-1)'.=>b:b+d-1))

Probieren Sie es online!

user3263164
quelle
1

Jelly , 11 Bytes

p/’$€+2¦ḟ/X

Probieren Sie es online!

Eine dyadische Verbindung, die zwei Argumente annimmt, [map_width, map_height], [W_width, W_height] undW_left, W_top einen zufällig ausgewählten Punkt zurückgibt, der den Anforderungen entspricht.

Erläuterung

   $€       | 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
Nick Kennedy
quelle
1

Python 2 , 100 Bytes

Die Eingabe sollte in Form von erfolgen ((map_width, W_top_left_x, W_width),(map_height, W_top_left_y, W_height))

Die Ausgabe erfolgt in der Form: [[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

Probieren Sie es online!

Zufällige Ausgaben aus der Beispieleingabe:

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

Java (OpenJDK 8) , 100 Byte

W->H->r->{int x=0,y=0;for(;r.contains(x+=W*Math.random(),y+=H*Math.random());x=y=0);return x+","+y;}

Probieren Sie es online!

Verwendet java.awt.Rectangleals Inhaber einiger der Parameter. Natürlich verwenden diese intFelder und nicht floatoder double.

Olivier Grégoire
quelle
1
Oh, schöne Art, die Herausforderung buchstäblich mit dem Rectangle#containseingebauten zu nehmen! : D
Kevin Cruijssen
1

Wolfram Language (Mathematica) , 84 68 60 Bytes

RandomChoice[g=Join@@List~Array~##&;#~g~0~Complement~g@##2]&

Probieren Sie es online!

Eingaben übernehmen als {map_width, map_height}, {W_width, W_height}, {W_top_left_x, W_top_left_y}.

attinat
quelle
0

Holzkohle , 55 43 Bytes

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

Probieren Sie es online! Link ist eine ausführliche Version des Codes. Erläuterung:

NθNη

Geben Sie die Kartengröße ein. (Wenn sie das letzte Mal wären, könnte ich die Höhe inline eingeben, um 1 Byte zu sparen.)

FE²N⊞υ⟦ιN⟧

Geben Sie das innere Rechteck ein. (Wenn ich in der Reihenfolge left, width, top, heighteingeben könnte, könnte ich F²⊞υE²Nfür eine 3-Byte-Einsparung verwenden.)

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

Generieren Sie eine Liste aller Koordinaten im Feld.

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

Einträge herausfiltern, bei denen beide Koordinaten innerhalb des Rechtecks ​​liegen.

I‽...

Drucken Sie ein zufälliges Element der verbleibenden Elemente.

Neil
quelle
0

Perl 5 -ap , 84 Bytes

sub c{($c=0|rand((pop)+($l=pop)-"@_"))<$l?$c:$c+"@_"-$l}say c@F[4,2,0];$_=c@F[5,3,1]

Probieren Sie es online!

Xcali
quelle
0

Scala , 172 Bytes

Zufälligkeit? Erwischt.

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

Eine spaßige Implementierung, die mir einfiel.
So funktioniert es : Erzeugen Sie ein zufälliges Paar in der Karte. Wenn es sich im inneren Rechteck befindet, versuchen Sie es erneut.
Probieren Sie es online!

V. Courtois
quelle
0

J , 54 47 45 39 Bytes

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

Probieren Sie es online!

Nimm die Eingabe als 3 x 2 Gitter wie folgt:

grid_height  grid_width
inner_top    inner_left
inner_height inner_width
  • Wählen Sie einen zufälligen Punkt im gesamten Raster: 0?@{[
  • Verschieben Sie es um den oberen linken Punkt des inneren Rechtecks ​​nach links und unten: (-1&{)~
  • Kehren Sie zu Schritt 1 zurück, wenn sich der ausgewählte Punkt innerhalb befindet (<*/@,0<:[) des ähnlich verschobenen inneren Rechtecks ​​befindet2{[ . Anderenfalls geben Sie den ursprünglichen, nicht verschobenen Zufallspunkt zurück.
  • Setzen Sie den gesamten Prozess auf einen Punkt, von dem wir wissen, dass er ungültig ist, nämlich den oberen linken Punkt des inneren Rechtecks, der durch die Elemente 2 und 3 der Eingabeliste definiert wird: {~&1

Ein weiterer Ansatz, 45 Bytes

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

Probieren Sie es online!

Dieser ist konzeptionell einfacher und kümmert sich nicht um Looping. Stattdessen konstruieren wir eine Matrix aller Zahlen von 0 bis (wxh), verschieben sie um den inneren Startpunkt, greifen nur die Punkte im Untergitter (0, 0) bis (inneres w, inneres h) und entfernen sie aus dem Gesamten Nachdem Sie beide abgeflacht haben, wählen Sie eine zufällige Zahl aus dem Rest aus und konvertieren Sie die Ganzzahl mit divmod zurück in einen Punkt<.@% , |~

Jona
quelle