迷宮を脱出せよ!


20

この5x5の迷宮に閉じ込められています-各部屋には1〜25のラベルが付けられ、出口は部屋1にあります。

ここに画像の説明を入力してください

現在の部屋の入力として与えられます。あなたの仕事は、部屋1に到達するために必要な移動の最短シーケンス(北、東、南、西)を出力することです。

文字を使用する限り、移動は任意の形式(リスト、文字列、配列...)で出力できますn,w,e,s

すべてのテストケースは次のとおりです。

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

バイト単位の最短回答が勝ちます!


3
部屋のラベリング/入力はどの程度柔軟ですか?1インデックスの代わりに0インデックスを使用できますか?部屋番号をキャラクターとして取ることができますか(ベース36のように考えて)?
チャスブラウン

2
@Therandomguyいいえ、この特定の迷路を処理する必要があります。
アルノー

6
可能性があるため、考えられるすべてのケースをテストケースに含める必要があると思います。
ジョナサンフレッチ

1
@UnrelatedStringこの質問は1つの入力を受け取り、その入力に基づいて異なるパスを出力します。この要件はkolmogorov-complexityタグに適合しないと思います。
tsh

2
誰かが迷宮で答えを提供する必要があります。
Draco18s

回答:


20

Python 2、64バイト

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

オンラインでお試しください!

1行に1方向を印刷し、エラーで終了する関数。

定数0x1211252b5375は、d各部屋番号から0から3の番号としてベース4にエンコードします。抽出桁>>2*n-4&3n=1、コードを終了するときに負のシフトエラーを与えるようにも設計されています。次のようにマップされるn方向から計算されるオフセットを介して、部屋番号を更新します。dd*3+d%2-5

d   d*3+d%2-5
0  -> -5
1  -> -1
2  ->  1
3  ->  5 

1
これがそのまま有効かどうかはわかりません。関数は再利用可能でなければならず、この関数を呼び出した後に実行を継続するにはエラートラップ(try/ except)が必要です。
エリック・ザ・アウトゴルファー


6

05AB1E30 29バイト

素数との奇跡的な一致のおかげで-1バイト

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

オンラインでお試しください!

[                      }    # 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)

1
これ11は、空の文字列の代わりにinput出力ます(簡単な修正は、先頭にを追加することですõ?)。それとは別に、いい答えです!
ケビンクルーッセン

1
@KevinCruijssenその間違いを指摘してくれてありがとう!シングルバイトの修正を見つけました。
グリムミー

5

ルビー72 62バイト

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

オンラインでお試しください!

どうやって?

ここでの秘Theは、2つの定数を使用して各セルの次のステップを作成し、問題を再帰的に解決することです。

2つの定数18139004および4267088は、次の移動の方向を示すバイナリ文字列です。各セルの両方から1ビットを抽出することにより、次のように取得できます。

"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

1つの大きな2進数を移動してマスクするよりも簡単です。

方向を取得したら、文字列 "en sw"から対応する文字を抽出します。

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

そして、セル[n + x]を再帰的に進めます



3

Perl 5(-n)、94バイト

Grimyのおかげで-5バイト

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

TIO





1
別の回答として投稿する必要があるということですか?
グリムミー

1
はい、あなたはほとんどの仕事をしたようですので、私たちが常にスペースを節約する方法を見るのは興味深いものでした
Nahuel Fouilleul



2

43 40バイト

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

オンラインでお試しください!リンクは、コードの詳細バージョンです。@ChasBrownと@xnorの両方の回答に基づいています。説明:

Nθ

部屋を入力します。

W⊖θ«

ループ変数iを部屋番号より1つ小さい値に設定し、ゼロ以外の間繰り返します。

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

圧縮された文字列から方向を抽出します0113130113220112010102010。(先頭0は単なる数字です。)

§nwesι

方向を印刷します。

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

@xnorの式を使用して、新しい部屋番号を計算します。


2

ゼリー30 29バイト

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

オンラインでお試しください!

開始セルを取得し、指示とともに文字列を返すモナドリンク。

Jellyの辞書には「Kennesaw」(ジョージア州アトランタの北西の都市)のような単語があり、ここで使用されているの[5, 1, -5, -1] + 1は、nesw

説明

“þ...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"

2

PHP、110バイト

Chas Brownのすばらしい答えxnorのすばらしい答えではない解決策。私はこれが長いことを知っていますが、私は別の解決策を望んでいました!

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];

オンラインでお試しください!

ボードのすべてのセルに2文字のマッピング文字列を作成しました。各セルの最初の文字は移動(n / e / s / w)で0あり、2番目の文字のASCIIコードmod 30は別のセル番号を返します。このセル番号は、セル(cell < 2)を出るまで再帰モードで移動する必要があります。

たとえば、8の入力の場合:

  • セルの2文字8は次のとおりです。w%
  • それは印刷してw、セルの動きを続けることを意味します%
  • のASCIIコード%は37で、mod 30は7になるため、次に続くセルは7です。
  • セルの2文字7は次のとおりですn (最後の文字はスペース、ASCIIコード= 32)
  • これはn、32 mod 30のセルの印刷と移動の続行を意味します2
  • セルに2文字 2は次のとおりです:(w<最後の文字ASCIIコード= 60)
  • それは印刷を意味します w、60 mod 30のセルの移動を続行0
  • セル番号が以下の場合 2、ループは停止します!
  • 最終的な印刷結果: wnw

PHP、75バイト

このバージョンはGrimyによって書かれ、彼/彼女が賢いので、私の元の答えよりも35バイト短くなっています!Grimyのコメント:「4 * 25 <256。したがって、セルごとに必要なのは2バイトではなく1バイトだけです」

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

オンラインでお試しください!


PHP、71バイト

このArnauldの回答の移植版はxnorのanswerの移植版ですが、PHPの方が短いため、再帰関数ではなくループとして使用されます。

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

オンラインでお試しください!


2
4 * 25 <256。したがって、必要なのはセルごとに1バイトのみで、2は必要ありません。オンラインで試してください!
グリムミー

1
@Grimy、驚くべきことに、別の回答として投稿する必要があると思う、それは十分に異なっている。
ナイト2

1
私はそれをするつもりはないので、あなたはそれをあなたの答えに組み込むか、それを単なるコメントとして残すかを選択します。
グリムミー

1
@Grimy、あなたの名前であなたのバージョンを追加しました。とにかく、ありがとう。
ナイト2

2

C(clang)、81バイト

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

オンラインでお試しください!

@ Tommylee2k提案-8に感謝します!+再帰呼び出し

C(clang)、90バイト

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

オンラインでお試しください!

すべての非圧縮ソリューションに似ています。


1
短縮できます:v;f(p){for(;p-1;p+=v%5?6-v%8:v%2?5:-5)putchar(v="00wwswsnwwseenwwenwnwnenwn"[p]);}
Tommylee2k

1

05AB1E45 43 バイト

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

@ChasBrownのPython 2回答のポート。

オンラインそれを試してみたり、すべてのテストケースを確認してください

説明:

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

理由を理解するに.•DUo¢ê`Ω÷‰₂¡)R€ûK•"a wwswsnwwseenwwenwnwnenwn"この05AB1Eのヒント(4つのセクションすべて)参照してくださいŽ₁9です22449Ž₁9₂вです[1,7,5,11]。と'€Ãです"news"


1
その便利な辞書文字列は朗報だったに違いありません!
ニール

@Neil間違いなく。:)どうやら辞書の文字列westernが優れています。; p
ケビンクルーッセン

1

Bash、120バイト

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; }

オンラインでお試しください!

しばらくの間、文字列をニブルとしてビットパックしようとしていましたが、デコードには保存された数よりも多くの文字が必要になります。

使い方:

S=__wwswsnwwseenwwenwnwnenwn

文字列$ Sは、部屋0と1をスキップして、出口に向かって1つの部屋を移動する方向を示す各部屋の単一の文字(n、w、s、e)を保持します。

N=n-5w-1s05e01

文字列$ Nには、方向の変更ごとに現在の部屋番号に加算/減算するデルタがあります(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; }

コマンドラインで指定された部屋番号($ 1)に等しい$ iから始めます。文字列$ Sのインデックス$ iの文字を$ dに割り当てます。次の部屋に進む方向の$ Nからデルタ値を取得し、$ jに割り当てます。

次の方向を印刷して、$ dを取り込みます。

$ jのデルタを$ iに加算/減算します。

ルーム#2を出るまでループします($ i> 1の間)。



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