Hintergrund
Mit den meisten (halbwegs anständigen) Texteditoren können Sie mit den Pfeiltasten durch den Text navigieren. Nach oben und unten können Sie durch Linien navigieren, während sich links und rechts über eine Linie bewegen, aber auch umlaufen. Wenn die Linie kürzer als die X-Position Ihres Cursors ist, wird der Cursor am Ende der Linie angezeigt, kehrt jedoch zur gleichen X-Position zurück, wenn Sie sich weiter nach oben oder unten bewegen. Vielleicht hilft die folgende visuelle Erklärung:
Beispiele für Bewegung
Ein einfaches Textbeispiel könnte so aussehen. Der Cursor wird zwischen zwei Zeichen in diesem Text oder an einem Ende eingefügt.
-----
---
------
let's put the cursor here:
X-----
---
------
move down (v):
-----
X---
------
move left (<):
-----X
---
------
v
-----
---X
------
v (notice how the X position of the cursor has been maintained)
-----
---
-----X-
^
-----
---X
------
> (more line wrapping)
-----
---
X------
<
-----
---X
------
^ (the X-position from earlier is no longer maintained due to the left-right motion)
---X--
---
------
Die Herausforderung
Suchen Sie bei mehreren ASCII-Testzeilen den kürzesten Weg vom Startort zum Endort. Der Startort wird durch ^
und der Endort durch dargestellt $
, und es wird jeweils nur einen geben. Diese werden nicht als Teil des Textes betrachtet und tragen nicht zur "Länge" dieser Zeile bei.
Die Eingabe besteht aus mehreren nicht leeren Textzeilen. Die Ausgabe besteht aus einer Reihe von ^v<>
Zeichen, die einen der kürzesten Pfade anzeigen. Optional können Sie am Ende jeweils einen zusätzlichen Zeilenumbruch annehmen, der jedoch nicht im navigierbaren Text enthalten ist.
Sie können ein Programm oder eine benannte Funktion schreiben. Der Gewinner ist die kürzeste Einsendung, gemessen in Bytes.
Beispiel E / A.
^Squares
are
fun$ny
vv<v (which is better than the naive vv>>>)
Squares
^are
funny$
<vv
Alp$habet^
Song
v<^
Mary had a little lamb,
His fleece was white as snow,
And$ everywhere that ^Mary went,
The lamb was sure to go.
^^>>>>v>>>
$^degenerate case
(no output)
v<vv
, oder? Oder würde das nach dem letzten Zeichen in dieser Zeile enden?Antworten:
CJam, 139 Bytes
Nun, es hat viele Stunden gedauert, bis etwas erreicht war, das sich erledigt anfühlt. Es scheint, dass die Zeit, die benötigt wird, um CJam-Code aggressiv zu optimieren, in Bezug auf die Größe des Codes etwas größer als O (n) ist ...
Sie können es online ausprobieren , aber für jede Eingabe, für die der beste Pfad mindestens 6 Operationen sind, sollten Sie es wahrscheinlich offline mit einem schnelleren Interpreter versuchen .
Gequetscht:
Erweitert und kommentiert:
Insgesamt ist dies eine ziemlich einfache Lösung. Es "führt" die Ziffern der Basis-5-Darstellung einer Pfadnummer aus, die bei jeder Iteration beginnend mit 0 inkrementiert wird, bis ein Pfad funktioniert. Die Ziffern
1
-4
Karte auf die Operationen nach oben, unten, links und rechts, und0
tut nichts. Die erste Iteration unter Verwendung eines Pfades von0
fängt nur den entarteten Fall ab. Alle anderen Pfade, die a enthalten,0
werden nie ausgewählt, da es sich nur um Versionen bereits getesteter Pfade mit hinzugefügten No-Ops handelt.Der Status wird so minimalistisch wie möglich modelliert: der Text mit entfernten Start- und Endmarkierungen, die Cursorposition im Text und der "Spaltenspeicher". Zeilenumbrüche werden meistens wie jedes andere Zeichen behandelt, daher gibt es kein Konzept für eine Zeile, und die Cursorposition ist nur ein Index. Dies macht das Verschieben nach links und rechts ganz einfach, die nur als Dekrement und Inkrement implementiert werden (mit Klemmung auf die Größe des Textes). Das Auf und Ab zu bewegen ist etwas schwieriger, aber immer noch überschaubar.
Die Wiederverwendung von Code war eine ziemlich wichtige Optimierungstaktik. Beispiele hierfür sind:
5
Operation am Anfang der Pfadzeichenfolge, die0
aufgrund der zirkulären Array-Indizierung und nur 5 definierten Operationen zufällig die No-Op-Logik verwendet.Insgesamt bin ich sehr zufrieden mit dem Ergebnis. Dies ist definitiv die meiste Arbeit, die ich bisher in eine Code-Golf-Antwort gesteckt habe (für etwas, das in einen Tweet passt!?). Die Laufzeit ist allerdings ziemlich miserabel. CJam ist nicht gerade die schnellste Sprache, und dieser Algorithmus hat eine Komplexität von etwa O (m * 5 n ) , wobei m die Größe der Eingabe und n die Größe der Ausgabe ist. Gut, dass Geschwindigkeit nicht zählt!
quelle
Python 2: 446
Einfache Lösung. Ich führe eine Breitensuche durch.
t
iteriert über alle verschiedenen Pfade. Ich konvertieret
in Basis5
, verwende aber nur die Einträge, die ungleich Null sind.1
ist oben,2
ist unten,3
ist links und4
ist rechts.Ich halte die aktuelle Position des Cursors in 3 Variablen
x
,y
undz
.x
ist die Zeile,y
die Spaltenposition undz
die 'versteckte' Spaltenposition, wenn Sie nach oben oder unten gehen und die Zeile zu kurz ist. Viele Wenns entscheiden, wie sich die Variable während eines Zuges ändert.Die Vorverarbeitung ist sehr langwierig, die ersten 4 Zeilen führen nur diese Aufgabe aus.
Der lange Testfall dauert sehr lange. Der Algorithmus hat eine Komplexität von O (N * 5 ^ N), wobei N die Länge der kürzesten Lösung ist.
Verwendung: Geben Sie die Zeilen als einzelne Zeichenfolge (Zeilen getrennt durch
\n
) wie ein"Alp$habet^\nSong"
quelle
CJam - 274
Noch keine Antwort? Ok, hier ist einer :)
Probieren Sie es unter http://cjam.aditsu.net/ aus . Mit Ausnahme des Mary-Beispiels oder etwas in dieser Größe möchten Sie wahrscheinlich den Java-Interpreter .
quelle