Interaktiver Labyrinthlöser

13

Bob wurde entführt und steckt in einem Labyrinth. Ihre Aufgabe ist es, ihm zu helfen, einen Ausweg zu finden. Aber da es ein sehr dunkles und beängstigendes Labyrinth ist, kann er nichts sehen. Er kann Wände nur fühlen, wenn er hineinläuft und weiß, wann er den Ausgang gefunden hat, weiß aber nichts mehr darüber.

Da er Ihr Programm im Speicher ausführen muss, muss es so kurz wie möglich sein.

Hinweis: Ich habe dieses Problem von http://acmgnyr.org/year2016/problems.shtml übernommen , es aber leicht angepasst und das Richterprogramm / die Testfälle selbst geschrieben.

Spezifikation

  • Dies ist ein interaktives Problem, sodass Sie Bewegungen nach stdout ausgeben und Antworten von stdin einlesen.
  • Ihr Programm ausgeben kann eines der bewegt right, left, down, up.
  • Es wird dann als Eingabe eine der folgenden Angaben geliefert:
    • wall- Dies bedeutet, dass Bob eine Wand getroffen hat. Bob wird am selben Ort bleiben.
    • solved- Bob hat den Ausgang gefunden! Ihr Programm sollte jetzt auch beendet werden, ohne etwas anderes zu drucken.
    • ok - Bob konnte sich in die angegebene Richtung bewegen.
  • Wenn das Labyrinth keinen Ausgang hat, sollte Ihr Programm ausgeben no exit , um Bob wissen zu lassen, dass er aufgeben sollte. Ihr Programm sollte dann beendet werden, ohne etwas anderes zu drucken.
  • Da Bob es eilig hat, auszusteigen, sollte Ihr Programm keine überflüssigen Bewegungen ausführen. Mit anderen Worten, Ihr Programm darf sich nicht zweimal vom selben Feld in dieselbe Richtung bewegen .
  • Das ist , also gewinnt das kürzeste Programm!

Beispiele

In den folgenden Beispielen Sist das Startquadrat Xder Ausgang, #eine Wand und Leerzeichen sind gültige Quadrate. Da es keine einzige richtige Antwort gibt, handelt es sich nur um Beispielläufe einer Lösung. Beachten Sie auch, dass die Zeichnungen des Labyrinths nur für Sie sichtbar sind und Ihr Programm sie nicht als Eingabe erhält.

########
#S     #
###### #
     # #
     #X#

right
              ok
right
              ok
right
              ok
right
              ok
right
              ok
right
              wall
down
              ok
right
              wall
down
              ok
right
              wall
down
              solved

#####
# S #
#####

right
              ok
right
              wall
down
              wall
up
              wall
left
              ok
down
              wall
up
              wall
left
              ok
down
              wall
up
              wall
left
              wall
right
              ok
no exit
              solved

###############################
#S                            #
##############       ###      #
             #       #X#      #
             #                #
             ##################

right
              ok
right
              ok
right
              ok
right
              ok
right
              ok
right
              ok
right
              ok
right
              ok
right
              ok
right
              ok
right
              ok
right
              ok
right
              ok
right
              ok
right
              ok
right
              ok
right
              ok
right
              ok
right
              ok
right
              ok
right
              ok
right
              ok
right
              ok
right
              ok
right
              ok
right
              ok
right
              ok
right
              ok
right
              wall
down
              ok
right
              wall
down
              ok
right
              wall
down
              ok
right
              wall
down
              wall
left
              ok
down
              wall
up
              ok
up
              ok
left
              ok
down
              ok
down
              ok
down
              wall
left
              ok
down
              wall
up
              ok
up
              ok
left
              ok
down
              ok
down
              ok
down
              wall
left
              ok
down
              wall
up
              ok
up
              ok
left
              wall
down
              ok
left
              wall
down
              ok
left
              ok
down
              wall
up
              wall
left
              ok
down
              wall
up
              solved

Checker-Programm

  • Ich habe einen Solution Checker in Python geschrieben. Sie finden es unter https://gist.github.com/Maltysen/f0186019b3aa3812d812f8bb984fee19 .
  • Führen Sie es wie python mazechecker.py ./mazesolver.
  • Es testet Ihr Programm auf allen Labyrinthen in einem Ordner namens mazes.
  • Die Labyrinthe befinden sich in separaten Dateien im selben Format wie oben.
  • Es überprüft alle oben aufgelisteten Bedingungen und benachrichtigt Sie, wenn Ihre Lösung gegen eine der Bedingungen verstößt.
  • Sie können zusätzliche Diagnoseinformationen mit ausdrucken lassen python mazechecker.py -d ./mazesolver .
  • Einen gezippten mazesOrdner finden Sie hier . Sie können auch Ihre eigenen hinzufügen, wenn Sie möchten.
Maltysen
quelle
1
Es ist wahrscheinlich erwähnenswert, ausdrücklich darauf hinzuweisen, dass das Problem unter einer CC-BY-NA-SA-Lizenz veröffentlicht wurde und Ihr Remix daher notwendigerweise unter derselben Lizenz vorliegt.
Nick Kennedy
3
Bekommen wir eine solvedbei der Ausgabe no exit? Wenn ja, geben Sie dies bitte in den Regeln an, nicht nur in den Testfällen!
Wastl
1
Ihr Programm ist in der gleichen Richtung von dem gleichen Platz zweimal nicht erlaubt zu bewegen. “ Zwei Fragen in Bezug auf : 1. Sagen wir , ich bin in der Position x,yund gehen up, mit respond wall, dann rightmit wieder reagieren wall, kann ich versuchen , dann upwieder, oder sind nur leftund downnoch verfügbar, da ich noch nicht von diesem Platz gezogen bin?
Kevin Cruijssen
1
2. Sagen wir, ich habe dieses Labyrinth . Mit diesem Flow: richtig (ok); richtig (ok); rechts (Wand); auf (ok) ; auf (ok); oben (Wand); links (Wand); unten (ok); unten (ok); unten (ok); unten (ok); unten (Mauer); rechts (Wand); auf (ok); auf (ok); Darf ich jetzt wieder hochgehen, obwohl ich es schon vorher von diesem bestimmten Feld aus getan habe (bei dem fetten)?
Kevin Cruijssen
1
@ KevinCruijssen Ich verfolge in meiner Antwort nicht explizit, woher ich komme. Stattdessen verfolge ich alle Richtungen, die auf jedem Feld verarbeitet wurden, und versuche es zuerst mit nicht besuchten Feldern. Wenn alle nicht besuchten Plätze ausprobiert wurden, ist der einzige verbleibende legale Zug, von wo ich gekommen bin (bereits besucht, aber nicht in diese Richtung).
Arnauld

Antworten:

7

JavaScript (ES6),  180 bis  174 Byte

Gibt prompt()die Richtung aus und ruft das Ergebnis ab.

_=>(g=p=>[...'012301234'].some((d,i)=>g[p]>>d&1|i<4&g[P=[p[0]+(d-2)%2,p[1]+~-d%2]]>0?0:(r=prompt('up/left/down/right/no exit'.split`/`[g[p]|=1<<d,d]))<'s'?g(P):r<'t'))([0,0])

Probieren Sie es online! (mit automatisierter E / A)

Interaktives Snippet

WARNUNG : Dieser Code zeigt ein Aufforderungsdialogfeld () an, bis "gelöst" eingegeben wird oder die Funktion feststellt, dass es überhaupt keinen Exit gibt.

(
_=>(g=p=>[...'012301234'].some((d,i)=>g[p]>>d&1|i<4&g[P=[p[0]+(d-2)%2,p[1]+~-d%2]]>0?0:(r=prompt('up/left/down/right/no exit'.split`/`[g[p]|=1<<d,d]))<'s'?g(P):r<'t'))([0,0])
)()

Kommentiert

_ => (                      // anonymous function taking no argument
  g = p =>                  // g = recursive function taking the current position p = [x, y]
    [ ...'0123',            // i<4  : try to move on squares that haven't been visited yet
      ...'0123',            // 3<i<8: try to go back to where we initially came from
      ...'4'                // i=8  : if everything failed, there must be no exit
    ].some((d, i) =>        // for each direction d at index i:
      g[p] >> d & 1         //   if this direction was already tried at this position
      | i < 4 &             //   or i is less than 4 and
      g[P = [               //   the square at the new position P = [X, Y] with:
        p[0] + (d - 2) % 2, //     X = x + dx[d]
        p[1] + ~-d % 2      //     Y = y + dy[d]
      ]] > 0 ?              //   was already visited:
        0                   //     abort
      : (                   //   else:
        r = prompt(         //     output the direction:
          [ 'up',           //       0 = up
            'left',         //       1 = left
            'down',         //       2 = down
            'right',        //       3 = right
            'no exit'       //       4 = no exit
          ][                //
            g[p] |= 1 << d, //       mark this direction as used
            d               //       d = actual index of the string to output
          ]                 //     r = result of prompt()
        )                   //
      ) < 's' ?             //     if r = 'ok':
        g(P)                //       do a recursive call at the new position
      :                     //     else:
        r < 't'             //       yield true if r = 'solved' or false if r = 'wall'
    )                       // end of some()
)([0, 0])                   // initial call to g at (0, 0)
Arnauld
quelle