インタラクティブ迷路ソルバー


13

ボブは誘kidされ、迷路で立ち往生しています。あなたの仕事は彼が道を見つけるのを助けることです。しかし、それは非常に暗いと怖い迷路なので、彼は何も見ることができません。彼は壁に出会ったときだけ壁を感じることができ、出口を見つけたときは知っていますが、それ以上何も知りません。

彼はプログラムをメモリで実行する必要があるため、可能な限り短くする必要があります。

注:この問題はhttp://acmgnyr.org/year2016/problems.shtmlから取得しましたが、わずかに修正し、ジャッジプログラム/テストケースを自分で作成しました。

仕様

  • これは対話型の問題であるため、プログラムは動きをstdoutに出力し、stdinからの応答を取り込みます。
  • 動きのあなたのプログラムを出力することができる1 rightleftdownup
  • 次に、次のいずれかを入力として取得します。
    • wall-これは、ボブが壁にぶつかったことを意味します。ボブは同じ場所に留まります。
    • solved-ボブは出口を見つけました!これで、プログラムは何も出力せずに終了するはずです。
    • ok -ボブは指定された方向に移動できました。
  • 迷路に出口がない場合、プログラムはno exitボブにshouldめるべきだと知らせるために出力する必要があります。その後、プログラムは何も印刷せずに終了します。
  • ボブは外に出るのが急いでいるので、あなたのプログラムは余分な動きをしてはいけません。つまり、プログラムは同じ正方形から同じ方向に2回移動することはできません
  • これはなので、最短のプログラムが勝ちます!

次の例では、 Sは、は開始正方形、X出口#は壁、壁は有効な正方形です。正解は1つではないため、これらはソリューションの単なる実行例です。また、迷路の絵はあなたが見るためだけにあり、あなたのプログラムはそれらを入力として取得しないことに注意してください。

########
#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

チェッカープログラム

  • Pythonでソリューションチェッカーを作成しました。あなたはそれを見つけることができますhttps://gist.github.com/Maltysen/f0186019b3aa3812d812f8bb984fee19でます
  • のように実行しますpython mazechecker.py ./mazesolver
  • というフォルダ内のすべての迷路でプログラムをテストします mazes
  • 迷路は上記と同じ形式の別々のファイルにあります。
  • 上記のすべての条件をチェックし、ソリューションに違反する場合は通知します。
  • 追加の診断情報を印刷することができます python mazechecker.py -d ./mazesolver
  • zip形式のmazesフォルダーはこちらで見つけることができます。必要に応じて、独自のものを追加することもできます。

1
問題はCC-BY-NA-SAライセンスの下でリリースされたと明示的に述べる価値があるでしょう。したがって、リミックスは必然的に同じライセンスの下にあります。
ニックケネディ

3
solved出力時にを取得しno exitますか?その場合は、テストケースだけでなく、ルールにも明記してください。
wastl

1
あなたのプログラムが二度同じ広場から同じ方向に移動することはできません。」このに関する二つの質問:私は位置によ1.ましょうと言うx,yと行くup応答して、wallその後、right再び応答ではwall、私はその後、試すことがup再び、またはleftdownまだこの広場から移動していないので、まだ利用可能ですか?
ケビンクルーッセン

1
2. この迷路があるとしましょう。このフローでは:右(OK); 右(ok); 右(壁); アップ(OK) ; アップ(OK); 上(壁); 左(壁); ダウン(OK); ダウン(OK); ダウン(OK); ダウン(OK); ダウン(壁); 右(壁); アップ(OK); アップ(OK); 以前(太字で)その特定の広場から既に行っていたとしても、私は再び上に行くことを許可されますか?
ケビンCruijssen

1
@KevinCruijssen私は答えのどこから来たのかを明確に追跡していません。代わりに、各正方形で処理されたすべての方向を追跡し、最初に未訪問の正方形を試します。すべての未訪問の正方形が試されたとき、残っている合法的な動きは私がどこから来たのかだけです(すでに訪れていますが、この方向ではありません)。
アーナルド

回答:


7

JavaScript(ES6)、 180  174バイト

prompt()方向を出力し、結果を取得するために使用します。

_=>(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])

オンラインでお試しください!(自動I / Oを使用)

インタラクティブなスニペット

警告:このコードは、 'solved'が入力されるか、関数が出口がないと判断するまで、prompt()ダイアログを表示します。

(
_=>(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])
)()

コメント済み

_ => (                      // 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)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.