逃离迷宫!


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
房间标签/输入的灵活性如何?我们可以用0索引代替1索引吗?我们能否将房间号作为一个字符(以基数36为例思考)?
Chas Brown

2
@Therandomguy不,您需要处理这个特定的迷宫。
Arnaud

6
既然有可能,我认为所有可能的情况都应包括在测试用例中。
乔纳森·弗雷奇

1
@UnrelatedString这个问题需要1个输入,并根据其输入输出不同的路径。我认为此要求不适合kolmogorov-complexity标签。
tsh

2
有人需要在迷宫中提供答案。
Draco18s

Answers:


20

Python 2,64个字节

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

在线尝试!

该功能每行打印一个方向,并以错误终止。

该常数0x1211252b5375在基数4中编码d从每个房间号到数字0到3的行进方向。提取数字>>2*n-4&3还设计为在n=1终止代码时产生负移位误差。我们更新了房间号n通过的偏移,从方向计算的d作为d*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
此输出1用于input1,而不是一个空字符串(简单的解决方法是添加一个Lead õ?)。除此之外,很好的答案!
凯文·克鲁伊森

1
@KevinCruijssen感谢您指出该错误!我发现了一个单字节修复程序。
Grimmy

5

红宝石72 62字节

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

在线尝试!

怎么样?

这里的技巧是使用2个常量为每个单元格构建下一步,然后以递归方式解决问题。

2个常数18139004和4267088是二进制字符串,给出了下一步的方向,通过为每个单元格从两个常量中提取一位,我们可以得到:

"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

比四处移动和掩盖单个大二进制数恕我直言要容易。

得到方向后,我们将从字符串“ en sw”中提取相应的字母:

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

然后在单元格[n + x]上递归进行






2

木炭43 40字节

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

在线尝试!链接是详细版本的代码。基于@ChasBrown和@xnor的答案。说明:

Nθ

输入房间。

W⊖θ«

将循环变量设置为i小于房间号的一,并在非零时重复。

«≔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第二个字符的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,因此每个单元只需要1个字节,而不是2个”

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

在线尝试!


的PHP,71字节

这口阿尔诺的答案是端口XNOR的答案,但作为一个循环,而不是递归函数,因为它原来在PHP更短。

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

在线尝试!


2
4 * 25 <256,因此每个单元只需要1个字节,而不是2个:在线尝试!
Grimmy

1
@Grimy,太神奇了,我想您必须将其作为单独的答案发布,它足够不同。
夜间2

1
我不会那样做,因此您可以选择是将其合并到答案中还是将其保留为评论。
Grimmy

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

看到这个05AB1E尖矿(所有四个部分)的理解为什么.•DUo¢ê`Ω÷‰₂¡)R€ûK•"a wwswsnwwseenwwenwnwnenwn"; Ž₁922449; Ž₁9₂в[1,7,5,11]; 并且'€Ã"news"


1
那个方便的字典字符串一定是个好消息!
尼尔

@尼尔绝对。:)尽管显然字典字符串western更好。; p
Kevin Cruijssen

1

重击,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为每个房间保留一个字符(n,w,s,e),显示将一个房间移向出口的方向,跳过房间0和1。

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

以$ i开头,该数字等于命令行中给出的房间号($ 1)。将字符串$ S中索引$ i处的字符分配给$ d。从$ N中检索到达下一房间的方向的增量值,并将其分配给$ j。

打印下一个方向以输入$ d。

将$ j中的增量添加到$ i中/从$ i中减去。

循环直到我们离开2号房间(而$ i> 1)。



By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.