ASCII-Reflexionen in einer Box

8

ASCII-Reflexionen in einer Box

Sie kennen wahrscheinlich alle das Gesetz der Reflexion . In dieser Herausforderung visualisieren Sie die Flugbahn eines Balls in einer Box.

Verwandte: ASCII Ball in Box Animation und ASCII Doodling: Laser in einer Box

Aufgabe

Sie sind drei ganzzahligen Paare gegeben W,H, x,yund dx,dy- das erste stellt die Größe des Feldes, der zweite die Ausgangsposition und das dritte Paar ist die Richtung , in der die Kugel beginnt sich zu bewegen.

Die Aufgabe besteht darin, die Bewegung des Balls zu visualisieren, bis er aufhört zu rollen. Dies geschieht, sobald sich der Ball an einer Position befindet, an der er zuvor war oder eine Ecke berührt.

Der Charakter *muss die Flugbahn des Balls visualisieren und +seine endgültige Position markieren, der Rest der Box muss aus (Leerzeichen) bestehen.

Beispiele

Um es etwas klarer _darzustellen , wird in diesen Beispielen ein Leerzeichen dargestellt. Auch die Zwischenstufen dienen nur zur Verdeutlichung, Sie müssen nur die letzte Stufe ausgeben, diese Beispiele sind 1indiziert.


Gegeben W = 3, H = 5, x = 3, y = 2und dx = -1, dy = 1:

___    ___    ___    ___
__*    __*    __*    __*
___ -> _*_ -> _*_ -> _+_
___    *__    *__    *_*
___    ___    _*_    _*_
  • Ball beginnt am Punkt (3,2)und
  • bewegt sich in Richtung (-1,1), trifft die Wand bei (1,4)und
  • wird reflektiert, neue Richtung ist (1,1). Es trifft die Wand wieder an(2,5)
  • wo es reflektiert wird. Die neue Richtung ist (1,-1)und es trifft die Wand sofort an (3,4),
  • wieder wird es in die Richtung reflektiert (-1,-1). Es würde jetzt durch Punkte wandern (2,3),(1,2), reflektiert usw., aber da es die Position bereits besucht (2,3)hat, stoppt es dort.

Dieses Beispiel zeigt, was passiert, wenn ein Ball eine Ecke trifft. Hierzu lassen W = 7, H = 3, x = 1, y = 3und dx = 1, dy = -1:

_______    __*____    __*____    __*___+
_______ -> _*_____ -> _*_*___ -> _*_*_*_
*______    *______    *___*__    *___*__
  • Startposition ist (1,3),
  • Der Ball bewegt sich nun in Richtung, (1,-1)bis er die Wand bei trifft(3,1)
  • wo es in die neue Richtung reflektiert wird (1,1).
  • Dabei wird (5,3)es reflektiert und reist in die neue Richtung (1,-1). Es kommt zu einem abrupten Stopp bei, (7,1)weil das eine Ecke ist.

Gegeben W = 10, H = 6, x = 6, y = 6und dx = 1, dy = 1:

__________    __________    ________*_    ________*_    ________*_    __*_____*_    __*_____*_
__________    _________*    _________*    _______*_*    _______*_*    _*_____*_*    _*_*___*_*
__________ -> ________*_ -> ________*_ -> ______*_*_ -> *_____*_*_ -> *_____*_*_ -> *___*_*_*_
__________    _______*__    _______*__    _____*_*__    _*___*_*__    _*___*_*__    _*___+_*__
__________    ______*___    ______*___    ____*_*___    __*_*_*___    __*_*_*___    __*_*_*___
_____*____    _____*____    _____*____    ___*_*____    ___*_*____    ___*_*____    ___*_*____

Eingabespezifikation

Die Eingabe besteht aus den drei Integer - Paare W,H, x,yund dx,dykann nehmen Sie Eingabe in einem beliebigen Format , die am meisten Sinn für Ihre Programmiersprache und die Reihenfolge spielt keine Rolle spielt. Die akzeptierte Eingabe darf jedoch nicht mehr Informationen codieren, als diese Paare enthalten ( ein Beispiel finden Sie in dieser Antwort).

  • W,H >= 1
  • x,y1Sind entweder -indexed ( 1 <= x <= Wund 1 <= y <= H) oder 0-indexed ( 0 <= x < Wund 0 <= y < H), geben Sie bitte an, welche Indizierung Sie gewählt haben
  • dx,dysind immer entweder -1oder1

Ungültige Eingaben können ignoriert werden.

Ausgabespezifikation

  1. Führende Leerzeichen sind nicht zulässig
  2. Nachgestellte Leerzeichen können weggelassen werden
  3. Nachgestellte Leerzeichen sind nicht zulässig, wenn sie nicht in die Box passen
  4. Nachgestellte Zeilenumbrüche ( nach allen ausgabebezogenen Zeilen) sind zulässig

Nehmen wir das erste Beispiel:

       (good by 2)
__*
_+     (good by 2)
*_*_   (bad by 3)
       (bad by 4)
_*_
       (good by 4)

Testfälle

Unter der Annahme, dass die Eingabe das Format hat (W,H,x,y,dx,dy)und 1-indexing ausgewählt wurde, sind hier einige Testfälle (wieder _hier, um Leerzeichen darzustellen!):

Eingabe: 1,1,1,1,1,1

Ausgabe:

+

Eingabe: 3,3,3,3,1,1

Ausgabe:

___
___
__+

Eingabe: 3,3,3,3, -1, -1

Ausgabe:

+__
_*_
__*

Eingabe: 7,3,1,3,1, -1

Ausgabe:

__*___+
_*_*_*_
*___*__

Eingabe: 10,6,6,6,1,1

Ausgabe:

__*_____*_
_*_*___*_*
*___*_*_*_
_*___+_*__
__*_*_*___
___*_*____

Eingabe: 21,7,6,4, -1, -1

Ausgabe:

__*_______*_______*__
_*_*_____*_*_____*_*_
*___*___*___*___*___*
_*___*_*_____*_*___*_
__*___*_______+___*__
___*_*_________*_*___
____*___________*____

Dies ist , also gewinnt das kürzeste Programm / die kürzeste Funktion, aber jede Anstrengung wird geschätzt.

ბიმო
quelle
Ich vermute, dass eine der 2D-Sprachen (Turtle?) Mit dieser Herausforderung wirklich gut zurechtkommt.
Draco18s vertraut SE
1
Wäre es erlaubt, die vier möglichen dx / dy-Werte als vier aufeinanderfolgende ungerade ganze Zahlen zu codieren? Wie wichtig ist es, dass x und y 1-indiziert sind?
Neil
Ich werde die 1-indexierte Einschränkung fallen lassen, wenn Sie (?) Über diese erste Frage nicht sicher sind, was Sie meinen, aber es klingt in Ordnung. Ich denke, alles, was eine Bijektion ( {-1,1}x{-1,1} ≡ "Your space") ist, wäre gut.
14.
Können Sie Ihre andere Frage genauer beantworten, die in der Indizierung bearbeitet wurde?
14.
1
Ich möchte eine Antwort auf diese Frage sehen.
Magic Octopus Urn

Antworten:

8

Holzkohle , 50 Bytes

UONN JNN↷NW⁼ KK«*¿¬KK«↷²¶*¿¬KK«↷²¶↷²*¿¬KK«↷²¶»»»»+

Probieren Sie es online aus! Der Link führt zur ausführlichen Version des Codes. Nimmt fünf Eingänge: w, h, x, y, a. xund ysind nullindiziert. astellt dxund dygemäß der folgenden Codierung dar:

a mod 8 == 1 => dx = 1, dy = 1
a mod 8 == 3 => dx = -1, dy = 1
a mod 8 == 5 => dx = -1, dy = -1
a mod 8 == 7 => dx = 1, dy = -1

Erläuterung:

UONN 

(hinteres Leerzeichen beachten) Füllt den Hintergrund mit Leerzeichen für die Eingabebreite und -höhe. (Normalerweise ist jedes Quadrat des Hintergrunds eine leere Zeichenfolge, die dann bei der Ausgabe in ein Leerzeichen umgewandelt wird.)

JNN

Bewegt den Cursor auf die Anfangskoordinaten.

↷N

Dreht sich zum Anfangswinkel.

W⁼ KK«

Wiederholt sich, solange das aktuelle Quadrat ein Leerzeichen ist.

    *

Druckt ein Sternchen und bewegt sich in die aktuelle Richtung vorwärts.

    ¿¬KK«

Wenn sich der Cursor außerhalb des ursprünglichen Längs bewegt,

        ↷²¶*

Drehen Sie die Richtung und drucken Sie dann eine neue Linie (die uns bequem zum vorherigen Quadrat zurückführt) und ein Sternchen, das sich in die neue Richtung bewegt.

        ¿¬KK«

Wenn sich der Cursor außerhalb des ursprünglichen Rechtecks ​​zurückbewegt,

            ↷²¶↷²*

Bewegen Sie den Cursor zurück zum vorherigen Quadrat, drehen Sie ihn dann erneut und drucken Sie das Sternchen in die andere Richtung.

            ¿¬KK«

Wenn sich der Cursor immer noch außerhalb des Rechtecks ​​befindet, müssen wir uns an einer Ecke befinden.

                ↷²¶

Gehen Sie also zurück zum vorherigen Feld und geben Sie auf.

»»»»+

Wenn wir uns nicht mehr bewegen können, drucken Sie ein "+" - Zeichen und halten Sie an.

Neil
quelle
1
Nett! Hier ist ein TIO für diejenigen, die es ausprobieren möchten.
14.
@BruceForte Danke, aber ich wollte keine Verbindung zu TIO herstellen, bis ich eine Lösung mit Peek()(die ich jetzt mache) hatte.
Neil
Hoppla, Peekfunktioniert jetzt wieder
ASCII-nur
2

Desmos Calculator - Nicht konkurrierend, um weiteres Wissen zu helfen

Probieren Sie es online aus!

Eingaben:

X as X position to Start
Y as Y position to Start
s as slope -> -1 for dX/dY = -1, +1 for dX/dY = +1
h as height of box, with 0-indexing
w as width of box, with 0-indexing

Zwischenprodukte:

Let b = gcd(h,w),  
Let c = |b-(X-sY)%2b| Or |b-mod(X-sY,2b)|

Formel, abgekürzt:

(|b-(x+y)%2b|-c)(|b-(x-y)%2b|-c)=0

Ausgänge:

x as x position, 0-indexed, where the ball will land when released
y as y position, 0-indexed, where the ball will land when released

Wie es funktioniert:

(|b-(x+y)%2b|-c)*(|b-(x-y)%2b|-c)=0
                ^ OR operation - |b-(x+y)%2b|-c=0 or |b-(x-y)%2b|-c=0
|b-(x+/-y)%2b|-c = 0
|b-(x+/-y)%2b| = c
|b-(x+/-y)%2b| = c means (b-(x+/-y))%2b = + or -c 
b-(x+/-y)%2b = +/- c -> b +/- c = (x+/-y)%2b -> (x+/-y) = n*2*b + b +/- c 
Where n is integer.  This will force patterns to repeat every 2b steps in x and y.  
Initial pattern n=0: (x +/- y) = b +/- c -> y = +/- x + b +/- c
In the x positive and y positive plane only, these correspond to lines of positive and 
negative slope, set at intercept b, offset by c on either side.

Das Programm erfüllt nicht das endgültige Kriterium - Anhalten am Schnittpunkt und Markieren mit einem + - und wird daher als nicht wettbewerbsfähig für Informationen eingereicht, um anderen bei der Bewältigung der Herausforderung zu helfen. Beachten Sie, dass ein kleiner Versatzfaktor von 0,01 eingeführt wurde, damit Desmos funktioniert, wenn c = 0 oder c = b ist, da Desmos Grenzen von Mod (A, B) von (0, B) anstelle von [0, B zu haben scheint )

Kennzeichen
quelle
Ich nehme an, Sie gesehen haben diese ?
20.
Eigentlich habe ich selbst Nerd geschnippt und ungefähr 4 Tage meiner Zeit zu Hause verloren. Dieses Problem hat mir sehr gut gefallen.
Mark
Gern geschehen; P Auch relevant .
20.
1

Python 3 , 293 279 Bytes

w,h,x,y,i,j=map(int,input().split());x-=1;y-=1;l=[x[::]for x in[[' ']*w]*h]
while 1:
 a,b=((x,i)in[(0,-1),(w-1,1)]),((y,j)in[(0,-1),(h-1,1)])
 if a and b or l[y][x]!=' ':l[y][x]='+';break
 i,j=i*(-a*2+1),j*(-b*2+1);l[y][x]='*';x+=i;y+=j
print('\n'.join([''.join(x) for x in l]))

Probieren Sie es online aus!

Andrew Dunai
quelle
1
Nett! Sie können ein paar Bytes sparen, indem Sie sie fx,fyTrue1
kürzen
@ BruceForte danke! Ich habe vergessen, diese zu ersetzen.
Andrew Dunai
1
-13 Bytes durch Umwandlung in eine Funktion.
Artemis vertraut SE
1
Warten Sie, ich habe gerade gesehen, wie alt diese Frage ist ... Doch ich bin vom HNQ hierher gekommen ...
Artemis vertraut SE