Bewegen Sie die Pfeile entlang einer Kontur

28

Sandkasten

nBewegen Sie die Pfeile bei einem Satz geschlossener, nicht überlappender 2D-Konturen (durch mindestens ein Leerzeichen auch in Diagonalen getrennt) mit Pfeilen, die durchgehend im oder gegen den Uhrzeigersinn ausgerichtet sind (jede Kontur hat ihre eigene Richtung) und einer positiven Zahl nSchritte entlang der Konturen in die jeweilige Richtung. Die Pfeile sind > v < ^jeweils für die Rechts-, Abwärts-, Links- und Aufwärtsrichtung dargestellt. Dort sind die anderen Zeichen -(horizontal), |(vertikal) und +(Ecke). Wenn sich ein Pfeil an einer Ecke befindet, behält er seine aktuelle Richtung bei und ändert sie erst nach dem Abbiegen.

Es wird immer ein gerades Segment (oder ein Leerzeichen) zwischen zwei Ecken geben (wie +-+bei der Horizontalen und ähnlich bei der Vertikalen) - mit anderen Worten, die scharfen UKurven sind verboten. Die Segmente zwischen den Ecken sind entweder vertikal oder horizontal und die Biegung an einer Ecke beträgt immer 90 Grad.

Eingang:

  • eine positive ganze Zahl - n- Anzahl von Schritten
  • eine ASCII-Darstellung der Konturen - es kann sich um eine mehrzeilige Zeichenfolge, eine Liste von Zeichenfolgen, eine Liste von Zeichen usw. handeln.

Ausgabe:

Dieselben Konturen mit allen Pfeilen haben die nSchritte in der gesamten Richtung der jeweiligen Kontur verschoben .

Testfälle:

1.

Eingang:

n = 1

 +----->->            
 |       |            
 |       v---+        
 |           |        
 +---<-------+      

Ausgabe:

 +------>+
 |       v
 |       +>--+
 |           |
 +--<--------+

2.

Eingang:

n = 2

 +-----+ +---+        
 |     | |   |        
 +-->--+ |   v  
         |   | 
 +--->---+   |        
 |           |         
 +------<<---+       

Ausgabe:

 +-----+ +---+
 |     | |   |
 +---->+ |   |
         |   | 
 +----->-+   v
 |           |     
 +----<<-----+        

3.

Eingang:

n = 3

 +---+   +---+   +-------+      
 |   |   |   v   |       |      
 ^   |   |   |   +-<-+   |      
 |   |   ^   |       |   v      
 |   +---+   +-->----+   |      
 |                       |      
 |   +-------+   +---+   |      
 |   |       |   v   |   |      
 +---+       +---+   +---+      

Ausgabe:

 +>--+   ^---+   +-------+
 |   |   |   |   ^       |
 |   |   |   |   +---+   |
 |   |   |   |       |   |
 |   +---+   v----->-+   |
 |                       |
 |   +-------+   +---+   v 
 |   |       |   |   |   |
 +---+       +-<-+   +---+  

4.

Eingang:

n = 1

+--+ 
|  |
|  +---+
|      |     
+----+ |
     | |
     +-+ 

Ausgabe:

+--+ 
|  |
|  +---+
|      |     
+----+ |
     | |
     +-+ 

5.

Eingang

n = 4

^>>>>
^   v
^   v>>>>
^       v           
<<<<<<<<v

Ausgabe:

^>>>>
^   v
^   v>>>>
^       v           
<<<<<<<<v

6.

Eingang:

n = 1

^->
^ v
<<v

Ausgabe:

^>+
^ v
<<v

Schreiben Sie eine Funktion oder ein Programm zur Lösung der oben genannten Aufgabe. Der kürzeste Code in Bytes in jeder Sprache gewinnt. Lassen Sie sich von den Golfsprachen nicht entmutigen. Die Erklärung des Algorithmus und des Codes wird sehr geschätzt.

Galen Ivanov
quelle
Können zwei Konturen ihre Ecken auf einer Diagonale berühren oder berührt sich eine Kontur so?
31.
4
"Bei einem Satz geschlossener, nicht überlappender 2D-Konturen ... mit Pfeilen, die durchgehend im oder gegen den Uhrzeigersinn ausgerichtet sind", hört sich für mich so an, als ob jede Kontur in die gleiche Richtung ausgerichtet ist, während es aus den Testfällen den Anschein hat, als ob Pfeile müssen nur innerhalb einer Kontur konsistent sein.
spätestens
3
@xnor Danke für deine Kommentare! - Nein, Konturen dürfen sich nicht diagonal berühren. - Jede Kontur hat eine eigene Richtung. Ich werde die Beschreibung aktualisieren.
Galen Ivanov
2
Ist eine Eingabe ohne Zwischenraum zwischen den Wänden möglich? ZB: Online ausprobieren! . Ich weiß, dass Sie "durch mindestens ein Leerzeichen getrennt" gesagt haben, aber mir war nicht klar, ob dies nur für unabhängige Schleifen oder auch für eine einzelne Schleife gilt.
Jonah
1
@Jonah Nein, es ist nicht möglich:There will always be a straight segment (or a space) between any two corners (like +-+ for the horizontal and similar for the vertical) - in other words the sharp U turns are forbidden.
Galen Ivanov

Antworten:

14

JavaScript (ES6),  210 ... 182  180 Bytes

(m)(n)m

m=>g=n=>n?g(n-1,m=m.map((r,y)=>r.map((c,x)=>(i=0,h=$=>~$?(m[Y=y+($-2)%2]||0)[X=x+~-$%2]>h?"-|+"[n+=`;m[${Y}][${X}]=S[${$}]`,i?2:$&1]:h($^++i):c)((S="<^>v").indexOf(c)))),eval(n)):m

Probieren Sie es online!

Wie?

Sie können diesem Link folgen , um eine formatierte Version der Quelle anzuzeigen.

Verpackung

gn1n=0

Aktualisierungsmethode

Es ist nicht möglich, jeden Pfeil einzeln sicher zu verschieben, da nicht aktualisierte Pfeile durch aktualisierte Pfeile überschrieben werden können. Stattdessen entfernen wir zuerst alle Pfeile und berechnen ihre neuen Positionen. Wir übernehmen die neuen Positionen ein zweites Mal.

n

n

"1;m[0][7]=S[2];m[1][8]=S[3];m[2][9]=S[2];m[4][3]=S[0]"

n

Die neuen Positionen werden durch einfaches Ausführen übernommen eval(n).

Richtungen

d$

10+23

dxdy

 d | dx = (d - 1) % 2 | dy = (d - 2) % 2
---+------------------+------------------
 0 |        -1        |         0
 1 |         0        |        -1
 2 |        +1        |         0
 3 |         0        |        +1

Ecken

hddxor1dxor3

+-|d

h$h"$""$""$"

Animierte Version

Arnauld
quelle
Vielen Dank für die Erklärung!
Galen Ivanov
8

K (ngn / k) , 183 161 157 Bytes

{A:"^>v<";D,:-D:(-1 0;!2);s:(#x;#*x);c:~^x;r:" -+|"c*+/'3'0,c,0;$[#p:+s\&~^t:A?,/x;;:r];q:q@'*'&'~^x ./:/:q:+p+/:D@4!(t^0N)+/:0 1 3;s#@[,/r;s/+q;:;A@D?q-p]}/

Probieren Sie es online!

{ }/Beim Aufruf mit einem int left arg n wird die Funktion in { }n-fachen Schritten auf das right arg angewendet

A:"^>v<" Pfeile

D,:-D:(-1 0;!2) ∆y, ∆x für die 4 Hauptrichtungen

s:(#x;#*x) Form der Eingabe: Höhe, Breite

c:~^x countours - Boolesche Matrix, die anzeigt, wo sich die Nicht-Leerzeichen befinden

r:" -+|"c*+/'3'0,c,0 Erstellen Sie die Zeichenmatrix mit einer Zählung ohne Pfeile neu, indem Sie für jede Zelle in Selbst + Oben + Unten zählen c und 1-> -, 2-> +, 3-> ersetzen|

t:A?,/xArten von Pfeilen: 0 1 2 3 für ^>v<alle anderen Zellen werden als 0N(null) dargestellt

p:+s\&~^t Koordinaten der Pfeile

$[#p ;;:r] Wenn es keine Pfeile gibt, kehre zurück r

q:+p+/:D@4!(t^0N)+/:0 1 3 alle 3 möglichen neuen Positionen für jeden Pfeil - wenn er sich vorwärts bewegt, wenn er sich nach links dreht und wenn er sich nach rechts dreht

q:q@'*'&'~^x ./:/:q Wählen Sie für jeden Pfeil die erste Option, die auf dem Countour landet

@[,/r;s/+q;:;A@D?q-p]Drücken rSie die Pfeile flach und setzen Sie sie an ihre neuen Positionen und in ihre neuen Richtungen

s# wieder in die ursprüngliche Form bringen

ngn
quelle
2
Du bist schnell! Ich hoffe, Sie erklären den Code, nachdem Sie mit dem Golfen fertig sind.
Galen Ivanov
Vielen Dank für die Erklärung!
Galen Ivanov
4

Kohle , 105 Bytes

W¬ΦυΣκ⊞υS≔⊟υη≔⪫υ⸿θ≔⟦⟧υ≔>^<vζPθFθ¿№ζι«⊞υ⟦⌕ζιⅉⅈ⟧§+|-↨EKV›κ ²»ιFυ«J⊟ι⊟ι≔⊟ιιFIη«≔⊟Φ⁴∧﹪⁻⊖ι⊕λ⁴›§KV⁻⁵λ ιM✳⊗黧ζι

Probieren Sie es online! Link ist eine ausführliche Version des Codes. Beinhaltet 22 Bytes, um ein umständliches Eingabeformat zu vermeiden. Erläuterung:

W¬ΦυΣκ⊞υS≔⊟υη≔⪫υ⸿θ≔⟦⟧υ

Geben Sie bequem die Konturen und die Anzahl der Schritte ein.

≔>^<vζ

Die Richtungszeichen werden mehrmals verwendet, sodass die Zeichenfolge hier zwischengespeichert wird. Der Index eines Richtungszeichens in dieser Zeichenfolge wird als Richtung bezeichnet.

Pθ

Drucken Sie die Originalkonturen, ohne den Cursor zu bewegen.

Fθ

Bewegen Sie sich über die Zeichen in der Kontur.

¿№ζι«

Wenn das aktuelle Zeichen ein Richtungszeichen ist ...

⊞υ⟦⌕ζιⅉⅈ⟧

... dann speichere die Richtung und Position in einer Liste ...

§+|-↨EKV›κ ²

... und ersetzen Sie das Zeichen durch das entsprechende Zeilenzeichen.

»ι

Geben Sie andernfalls das Zeichen aus und fahren Sie mit dem nächsten Zeichen fort.

Fυ«

Durchlaufen Sie die gespeicherten Positionen.

J⊟ι⊟ι

Zur gespeicherten Position springen.

≔⊟ιι

Extrahieren Sie die gespeicherte Richtung.

FIη«

Führen Sie eine Schleife über die entsprechende Anzahl von Schritten aus.

≔⊟Φ⁴∧﹪⁻⊖ι⊕λ⁴›§KV⁻⁵λ ι

Ermitteln Sie die Richtung des nächsten Schritts. Dabei handelt es sich um eine beliebige Richtung, die weder umgekehrt noch leer ist.

M✳⊗ι

Machen Sie einen Schritt in diese Richtung. (Die Richtungsindizes für den MoveBefehl entsprechen dem doppelten Wert meiner Richtung.)

»§ζι

Drucken Sie das entsprechende Richtungszeichen.

Neil
quelle
Vielen Dank für die Erklärung!
Galen Ivanov