Entkomme dem Labyrinth!

20

Sie sind in diesem 5x5 Labyrinth gefangen - jeder Raum ist mit 1 bis 25 gekennzeichnet und der Ausgang befindet sich in Raum 1.

Bildbeschreibung hier eingeben

Als Eingabe erhalten Sie den Raum, in dem Sie sich gerade befinden. Sie müssen die kürzeste Abfolge von Zügen (Nord, Ost, Süd, West) ausgeben, die erforderlich ist, um Raum 1 zu erreichen.

Bewegungen können in jedem gewünschten Format (Liste, Zeichenfolge, Array ...) ausgegeben werden, solange Sie die Zeichen verwenden n,w,e,s.

Hier sind alle Testfälle:

1 => empty string/list
2 => w
3 => ww
4 => swwnw
5 => wswwnw
6 => seenwnw
7 => nw
8 => wnw
9 => wwnw
10 => swwnwnw
11 => eenwnw
12 => enwnw
13 => nwnw
14 => wnwnw
15 => wwnwnw
16 => enenwnw
17 => nenwnw
18 => wnenwnw
19 => nwnwnw
20 => wnwnwnw
21 => nenenwnw
22 => enwnenwnw
23 => nwnenwnw
24 => wnwnenwnw
25 => nwnwnwnw

Kürzeste Antwort in Bytes gewinnt!

Arnaud
quelle
3
Wie flexibel ist die Raumkennzeichnung / -eingabe? Können wir 0-Index anstelle von 1-Index? Können wir die Raumnummer als Zeichen nehmen (Denken wie in Basis 36)?
Chas Brown
2
@Therandomguy nein, du musst mit diesem speziellen Labyrinth umgehen.
Arnaud
6
Da es möglich ist, denke ich, sollten alle möglichen Fälle in die Testfälle einbezogen werden.
Jonathan Frech
1
@UnrelatedString Diese Frage benötigt 1 Eingabe und gibt je nach Eingabe einen anderen Pfad aus. Ich glaube, diese Anforderung passt nicht zum Kolmogorov-Komplexitäts- Tag.
Dienstag,
2
Jemand muss im Labyrinth eine Antwort geben .
Draco18s

Antworten:

20

Python 2 , 64 Bytes

def f(n):d=0x1211252b5375>>2*n-4&3;print"nwes"[d];f(n+d*3+d%2-5)

Probieren Sie es online!

Eine Funktion, die eine Richtung pro Zeile ausgibt und mit einem Fehler endet.

Die Konstante 0x1211252b5375codiert in der Basis 4 die Richtung, die dwir von jeder Raumnummer als Zahl 0 bis 3 zurücklegen. Die Extraktionsziffer >>2*n-4&3ist auch so ausgelegt, dass sie beim n=1Beenden des Codes einen negativen Verschiebungsfehler ergibt . Wir aktualisieren die Raumnummer nüber einen Versatz, der aus der Richtung dwie folgt berechnet d*3+d%2-5wird:

d   d*3+d%2-5
0  -> -5
1  -> -1
2  ->  1
3  ->  5 
xnor
quelle
1
Ich bin mir nicht sicher, ob dies so ist wie es ist, Funktionen müssen wiederverwendbar sein und Sie benötigen eine Fehlerbehebung ( try/ except), um die Ausführung nach dem Aufrufen dieser Funktion fortzusetzen.
Erik der Outgolfer
10

Python 2 , 95 93 Bytes

f=lambda n:n>1and Q[n]+f(n+[-5,5,1,-1]['nsew'.find(Q[n])])or''
Q='  wwswsnwwseenwwenwnwnenwn'

Probieren Sie es online!

Kann 3 bis 2 Bytes einsparen, wenn eine 0-indizierte Raumbeschriftung zulässig ist.

Chas Brown
quelle
89 Bytes
Arnauld
6

05AB1E , 30 29 Bytes

-1 Byte dank eines wunderbaren Zufalls mit Primzahlen

[Ð#•θzƶ‰`Ó•4вsè<DˆØ·5-+}'‹™¯è

Probieren Sie es online!

[                      }    # infinite loop:
 Ð                          #  triplicate the room number (initially, the input)
  #                         #  break if room number == 1
   •θzƶ‰`Ó•4в               #  compressed list 202232302231102210202010
             sè             #  use the room number to index into that list
               <            #  decrement
                Dˆ          #  add a copy to the global array
                  Ø         #  nth prime (-1 => 0, 0 => 2, 1 => 3, 2 => 5)
                   ·        #  double
                    5-      #  subtract 5
                      +     #  add that to the room number
'‹™                         # dictionary string "western"
   ¯                        # push the global array
    è                       # index (wraps around, so -1 => n, 0 => w, 1 => e, 2 => s)
Grimmig
quelle
1
Diese Ausgaben 1für die Eingabe1 anstelle einer leeren Zeichenfolge (einfache Lösung wäre das Hinzufügen eines führenden Zeichens õ?). Ansonsten schöne Antwort!
Kevin Cruijssen
1
@ KevinCruijssen danke für den Hinweis auf diesen Fehler! Ich habe ein Einzelbyte-Update gefunden.
Grimmy
5

Ruby , 72 62 Bytes

f=->n{n<2?'':' en  sw'[x=4*18139004[n]+6*4267088[n]-5]+f[n+x]}

Probieren Sie es online!

Wie?

Der Trick dabei ist, mit 2 Konstanten den nächsten Schritt für jede Zelle zu erstellen und das Problem dann rekursiv zu lösen.

Die beiden Konstanten 18139004 und 4267088 sind binäre Zeichenfolgen, die die Richtung des nächsten Zuges angeben. Durch Extrahieren eines einzelnen Bits aus beiden für jede Zelle können wir Folgendes erhalten:

"n" = 4*0+6*0-5 = -5
"w" = 4*1+6*0-5 = -1
"e" = 4*0+6*1-5 = +1
"s" = 4*1+6*1-5 = +5

Einfacher als umzuschalten und eine einzige große Binärzahl zu maskieren, IMHO.

Wenn wir die Richtung erhalten, extrahieren wir den entsprechenden Buchstaben aus der Zeichenfolge "en sw":

  1   5
  |   |
" en  sw"
   |   |
  -5  -1

Und gehe rekursiv auf der Zelle vor [n + x]

GB
quelle
3

Perl 5 (-n ), 94 Bytes

-5 Bytes dank Grimy

@A=map/./g,__wwswsnwwseenwwenwnwnenwn;%H=(n,-5,s=>5,e,1,w,-1);$_+=$H{$,=$A[$_]},say$,until$_<2

TIO

Nahuel Fouilleul
quelle
-8
Grimmy
-2
Grimmy
-5
Grimmy
1
Meinst du, ich sollte es als separate Antwort posten?
Grimmy
1
Ja, weil Sie anscheinend den größten Teil der Arbeit erledigt haben, war es interessant zu sehen, wie wir immer Platz sparen können
Nahuel Fouilleul,
2

JavaScript, 80 73 71 Bytes

Angepasst von Chas 'Python-Lösung , gefällt +1ihm das auch.

f=n=>--n?(d=" wwswsnwwseenwwenwnwnenwn"[n])+f(n+~~{n:-4,s:6,e:2}[d]):``

Probieren Sie es online!

1 Byte gespart dank Arnauld .

Zottelig
quelle
Danke, @Arnauld :) Hatte das auch gerade selbst gesehen.
Shaggy
2

Kohle , 43 40 Bytes

NθW⊖θ«≔I§”)“⊞x⟧∧⎚⁵2”ιι§nwesι≧⁺⁻⁺﹪ι²×³ι⁵θ

Probieren Sie es online! Link ist eine ausführliche Version des Codes. Basierend auf den Antworten von @ ChasBrown und @ xnor. Erläuterung:

Nθ

Betritt den Raum.

W⊖θ«

Setzen Sie die Schleifenvariable iauf eins weniger als die Raumnummer und wiederholen Sie den Vorgang, solange sie nicht Null ist.

«≔I§”)“⊞x⟧∧⎚⁵2”ιι

Extrahieren Sie die Richtung aus der komprimierten Zeichenfolge 0113130113220112010102010. (Der führende 0ist nur eine Füllziffer.)

§nwesι

Drucken Sie die Richtung.

≧⁺⁻⁺﹪ι²×³ι⁵θ

Verwenden Sie die Formel von @ xnor, um die neue Zimmernummer zu berechnen.

Neil
quelle
2

Gelee , 30 29 Bytes

“þ&ƊĿñ÷°e’b6Ḥ_5Ż⁸+ị¥ƬI‘ị“®ȯẹ»

Probieren Sie es online!

Eine monadische Verknüpfung, die die Startzelle übernimmt und eine Zeichenfolge mit den Anweisungen zurückgibt.

Ich liebe die Tatsache, dass Jellys Wörterbuch ein Wort wie "Kennesaw" (eine Stadt nordwestlich von Atlanta, Georgia) hat, das hier verwendet wird, weil das Indizieren darin mit " [5, 1, -5, -1] + 1gives"nesw !

Erläuterung

“þ...e’                    | Base-250 integer 1962789844189344852  
       b6                  | Convert to base 6 (2, 2, 5, 2, 5, 0, 2, 2, 5, 3, 3, 0, 2, 2, 3, 0, 2, 0, 2, 0, 3, 0, 2, 0)
         Ḥ                 | Double
          _5               | Subtract 5
            Ż              | Prepend 0
             ⁸  ¥Ƭ         | Using this as the right argument and the original link argument as the left argument, loop the following as a dyad until there is no change, collecting up results
              +            | - Add the left argument to:
               ị           |   - The left argument indexed into the right argument
                  I        | Differences between consecutive numbers
                   ‘       | Increment by 1
                    ị“®ȯẹ» | Index into "Kennesaw"
Nick Kennedy
quelle
2

PHP , 110 Bytes

Eine Lösung, die nicht die beste Antwort von Chas Brown oder die beste Antwort von xnor ist . Ich weiß, das ist länger, aber ich wollte eine andere Lösung haben!

for($n=$argn;$n>1;$n=ord($s[$n*2+1])%30)echo($s='0000w<w sEw"s)n w%w&s-e*e+n&w+w,e/n*w/n,w1n.e5n0w5n2')[$n*2];

Probieren Sie es online!

Ich habe eine Zuordnungszeichenfolge erstellt, die 2 Zeichen für jede Zelle in der Platine enthält. Das erste Zeichen für jede Zelle ist eine Bewegung (n / e / s / w) oder 0und der ASCII-Code des zweiten Zeichens, Mod 30, gibt eine andere Zellennummer zurück, die wir im rekursiven Modus verfolgen sollten, bis wir cell ( cell < 2) verlassen.

Zum Beispiel für die Eingabe von 8:

  • 2 Zeichen für die Zelle 8sind:w%
  • Es bedeutet drucken wund mit den Bewegungen für die Zelle von fortfahren%
  • Der ASCII-Code %ist 37, der Mod 30 ist 7, die nächste Zelle also7 .
  • 2 Zeichen für die Zelle 7sind: n (letztes Zeichen ist Leerzeichen, ASCII-Code = 32)
  • Es bedeutet drucken nund mit den Zügen für die Zelle von 32 mod 30 fortfahren 2.
  • 2 Zeichen für die Zelle 2sind: w<(letztes Zeichen ASCII-Code = 60)
  • Es bedeutet drucken wund mit den Zügen für die Zelle von 60 mod 30 fortfahren 0.
  • Wenn die Zellenzahl kleiner als ist 2, stoppt die Schleife!
  • Endgültiges Druckergebnis: wnw

PHP , 75 Bytes

Diese Version wurde von Grimy geschrieben und ist 35 Bytes kürzer als meine ursprüngliche Antwort, weil er / sie schlauer ist! Grimys Kommentar: "4 * 25 <256, Sie brauchen also nur 1 Byte pro Zelle, nicht 2"

for($n=$argn;$n=ord("0\0~f;6o4R:s%ql&rup*@^tIDbx"[$n%25]);)echo news[$n%4];

Probieren Sie es online!


PHP , 71 Bytes

Dieser Port von Arnauld's Antwort, der der Port von xnors Antwort ist , aber als Schleife statt als rekursive Funktion, da er sich in PHP als kürzer herausstellt.

for($n=$argn;--$n;$n+=$d*3+$d%2-4)echo nwes[$d=79459389361621/4**$n&3];

Probieren Sie es online!

Night2
quelle
2
4 * 25 <256, Sie benötigen also nur 1 Byte pro Zelle, nicht 2: Probieren Sie es online aus!
Grimmy
1
@Grimy, erstaunlich, ich denke du musst es als separate Antwort posten, es ist anders genug.
Nacht,
1
Ich werde das nicht tun, also entscheiden Sie, ob Sie es in Ihre Antwort aufnehmen oder nur als Kommentar hinterlassen möchten.
Grimmy
1
@Grimy, hat deine Version mit deinem Namen hinzugefügt. Trotzdem danke.
Nacht,
2

C (clang) , 81 Bytes

v;f(p){p-1&&putchar(v="00wwswsnwwseenwwenwnwnenwn"[p])+f(p+=v%5?6-v%8:v%2?5:-5);}

Probieren Sie es online!

Danke an @ Tommylee2k Vorschlag -8! + rekursiver Aufruf

C (clang) , 90 Bytes

v;f(p){for(char*l="00wwswsnwwseenwwenwnwnenwn";p-1;p+=v%5?6-v%8:v%2?5:-5)putchar(v=l[p]);}

Probieren Sie es online!

Ähnlich wie bei allen nicht komprimierten Lösungen.

AZTECCO
quelle
1
kann gekürzt werden:v;f(p){for(;p-1;p+=v%5?6-v%8:v%2?5:-5)putchar(v="00wwswsnwwseenwwenwnwnenwn"[p]);}
Tommylee2k
1

05AB1E , 45 43 Bytes

õ?[Ð#.•DUo¢ê`Ω÷‰₂¡)R€ûK•¦sè©?Ž₁9₂в6-'€Ã®kè+

Port von @ChasBrowns Python 2 Antwort .

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Erläuterung:

õ?               # Output an empty string
                 # (to overwrite the implicit output if the input is 1)
[                # Start an infinite loop:
 Ð               #  Triplicate the top of the stack
                 #  (which is the (implicit) input in the first iteration)
  #              #  If it's exactly 1: stop the infinite loop
  .•DUo¢ê`Ω÷‰₂¡)R€ûK
                 #  Push compressed string "a  wwswsnwwseenwwenwnwnenwn"
   ¦             #  Remove the first character
    sè           #  Swap to get the number, and use it to index into the string
      ©          #  Store it in variable `®` (without popping)
       ?         #  Print it without trailing newline
  Ž₁9            #  Push compressed integer 22449
     ₂в          #  Convert to base-26 as list: [1,7,5,11]
       6-        #  Subtract 6 from each: [-5,1,-1,5]
         '€Ã    '#  Push dictionary string "news"
            ®k   #  Get the index in this string of character `®`
              è  #  And use that to index into the integer-list
               + #  And add it to the originally triplicated integer

Sehen Sie sich meinen Tipp 05AB1E (alle vier Abschnitte) an, um zu verstehen, warum dies so .•DUo¢ê`Ω÷‰₂¡)R€ûK•ist "a wwswsnwwseenwwenwnwnenwn". Ž₁9ist 22449; Ž₁9₂вist [1,7,5,11]; und '€Ãist "news".

Kevin Cruijssen
quelle
1
Diese praktische Wörterbuch-Zeichenfolge muss eine gute Nachricht gewesen sein!
Neil,
@ Neil Auf jeden Fall. :) Obwohl anscheinend der Wörterbuchstringwestern besser ist. ; p
Kevin Cruijssen
1

Bash , 120 Bytes

S=__wwswsnwwseenwwenwnwnenwn
N=n-5w-1s05e01
for((i=$1;$i>1;i+=$j)){ d=${S:$i:1};j=${N:`expr index $N $d`:2};printf $d; }

Probieren Sie es online!

Ich spielte eine Weile mit dem Versuch, die Zeichenfolge als Knabbereien zu packen, aber die Dekodierung würde mehr Zeichen als die gespeicherte Zahl erfordern.

Wie es funktioniert:

S=__wwswsnwwseenwwenwnwnenwn

Die Zeichenfolge $ S enthält ein einzelnes Zeichen (n, w, s, e) für jeden Raum, das angibt, in welche Richtung ein Raum zum Ausgang bewegt werden soll, wobei die Räume 0 und 1 übersprungen werden.

N=n-5w-1s05e01

String $ N hat das Delta, das bei jedem Richtungswechsel zur aktuellen Raumnummer addiert / von dieser subtrahiert wird (n: -5, w: -1, s: +5, e: +1)

for((i=$1;$i>1;i+=$j)){ d=${S:$i:1};j=${N:`expr index $N $d`:2};printf $d; }

Beginnen Sie mit $ i, das der in der Befehlszeile angegebenen Raumnummer entspricht ($ 1). Weisen Sie das Zeichen am Index $ i in der Zeichenfolge $ S bis $ d zu. Rufen Sie den Delta-Wert von $ N ab, damit die Richtung zum nächsten Raum geht, und weisen Sie ihn $ j zu.

Drucken Sie die nächste Richtung, um $ d aufzunehmen.

Addiere / subtrahiere das Delta in $ j zu / von $ i.

Schleife bis wir Raum # 2 verlassen (solange $ i> 1 ist).

spuckte
quelle
1

Kotlin , 112 Bytes

val d="  113130113220112010102010"
fun p(r:Int):String=if(r>1)"nwes"[d[r]-'0']+p("046:"[d[r]-'0']-'5'+r)
else ""

Probieren Sie es online!

JohnWells
quelle