乌龟找到门户


30

乌龟想要沿着网格移动以获取食物。他想知道要到达那里需要多少步。

同样,由于他的速度很慢,因此他在自己的域周围设置了传送器,如果它缩短了路径,他将利用它。如果延长了他的行程,或者避免使用它们。

遇见乌龟

🐢

在网格上的乌龟生活

XXXXXXXXXXXX🐢XXXXXXXXXXXX
乌龟可以移动到任何相邻方...
XXXXXXXX🐢XXXXXXXX

然而,乌龟不能移动到一个正方形与山

X🌄XXXXXX🌄🐢XX🌄XX🌄XXX

海龟要吃掉他的草莓,想知道需要多久才能到达他的草莓

X🌄🍓🐢🌄XX🌄XXXX
这个例子将采取龟5
X🌄🍓🌄🌄XX
幸运的是,乌龟发现了一个传送点!网格上有两个相互映射的传送端口。踩到传送器后,乌龟会立即移动到相应的传送器。传送器非常不稳定,一旦使用它们,它们就会消失并且不再可用。
🔵🌄🍓🐢🌄🔴X🌄XXXX
现在快是龟两次拉升。现在海龟最短路径是2
🔵🌄🐢🌄🔴X🌄XXXX

挑战

给定初始网格配置输出后,乌龟会到达其草莓的移动次数。

规则

  • 您可以假设输入网格具有解决方案

  • 每个网格只有一个strawberry,两个portals和一个turtle

  • 输入网格可以以任何方便的格式输入

  • 您应该将其视为teleporters一次性用品

  • 乌龟移动到一个teleporter正方形的转弯,他已经在相应的位置了teleporter。他从不teleporter动弹,一直呆在那里

  • 最短路径不需要利用门户

  • 乌龟不能进入山瓦

  • 您可以使用任何ASCII字符或整数来表示mountainsturtleempty grid squarestrawberry

  • 您可以使用相同的字符或两个不同的ASCII字符或整数来表示teleporter

  • 一个网格可以有多个路径且具有相同的最短路径长度

  • 这是

规则澄清

  • 您应该将其视为teleporters一次性用品。

推理:有人指出的情况:

🐢X🔵X🍓🌄🌄🌄🌄🌄🔴XXXX

只能通过两次进入和退出门户网站来解决。在作出澄清时,两种解决方案都以假定它们是一次性使用或没有理由尝试使用先前使用的正方形的方式起作用。为了避免破坏他们辛苦的解决方案,这似乎是解决此问题的最佳方法。因此,这将被视为无效的网格。

测试用例格式化为列表

[ ['T', 'X', 'X', 'S', 'X'], ['X', 'X', 'X', 'X', 'X'], ['X', 'X', 'X', 'X', 'X'] ] --> 3
[ ['T', 'M', 'X', 'S', 'X'], ['X', 'M', 'X', 'X', 'X'], ['O', 'X', 'X', 'X', 'O'] ] --> 4
[ ['T', 'M', 'X', 'S', 'O'], ['O', 'M', 'X', 'X', 'X'], ['X', 'X', 'X', 'X', 'X'] ] --> 2
[ ['T', 'M', 'X', 'S', 'X'], ['O', 'M', 'X', 'X', 'X'], ['O', 'X', 'X', 'X', 'X'] ] --> 4
[ ['T', 'M', 'S', 'X', 'O'], ['X', 'M', 'M', 'M', 'M'], ['X', 'X', 'X', 'X', 'O'] ] --> 7
[ ['T', 'X', 'X', 'S', 'X'], ['O', 'M', 'M', 'M', 'X'], ['X', 'X', 'O', 'X', 'X'] ] --> 3

为人类格式化的测试用例

T X X S X
X X X X X
X X X X X --> 3

T M X S X
X M X X X
O X X X O --> 4

T M X S O
O M X X X
X X X X X --> 2

T M X S X
O M X X X
O X X X X --> 4

T M S X O
X M M M M
X X X X O --> 7

T X X S X
O M M M X
X X O X X --> 3

学分

通过以下方式进行设计和结构: Arnauld的“饿老鼠”

拟议挑战编辑建议:卡米尔·德拉卡里(Kamil-drakari)beefster

常规编辑建议:okx nedla2004 mbomb007


2
我认为添加一个测试用例将是一个好主意,在这种情况下,使用传送器会花费更长的时间。
Okx

@Okx立即创建和添加。
akozi

编辑,谢谢。
akozi

1
@xnor我觉得这可能是从我原来的规则中抽象出来的。因此,也许门户网站一次性使用一项更好?
akozi

1
相关(我认为)。
查理

Answers:


13

的JavaScript(ES7), 140 139  138字节

使用以下映射将输入作为整数矩阵:

  • -1个 =🔵(任何门户)
  • 0 = X (空)
  • 1个 =🌄(山)
  • 2 =🐢(乌龟)
  • 3 =🍓(草莓)
m=>(R=g=(t,X,Y,i)=>m.map((r,y)=>r.map((v,x)=>r[(u=0,t?v-t:(x-X)**2+(y-Y)**2<3?v-3?~v?v:u--:R=R<i?R:i:1)||g(u,x,y,u-~i,r[x]=1),x]=v)))(2)|R

在线尝试!

怎么样?

主要的递归搜索功能 G 能够寻找特定的瓷砖 Ť 在黑板上(如果用 Ť0)或 Xÿ 可以从当前位置到达 Xÿ

它跟踪当前路径的长度 一世 并更新最佳结果 [R[R一世 每当乌龟找到草莓时。

首先用 Ť=2 找到海龟的起始位置。

它用 Ť=-1个如果到达一个门户,则乌龟会被传送到另一个门户。我们不增加一世 在这样的迭代过程中。

每个访问的图块都临时设置在一座山上,以防止龟在同一路径上的同一图块上移动两次。如果我们陷入了死胡同,则递归将停止而无需更新[R

已评论

m => (                        // m[] = input matrix
  R =                         // initialize R to a non-numeric value
  g = (t, X, Y, i) =>         // g = recursive search function taking t = expected tile,
                              //     (X, Y) = current coordinates, i = path length
    m.map((r, y) =>           // for each row r[] at position y in m[]:
      r.map((v, x) =>         //   for each tile v at position x in r[]:
        r[                    //     this statement will eventually restore r[x] to v
          ( u = 0,            //     u = next tile to look for, or 0 if none
            t ?               //     if we're looking for a specific tile:
              v - t           //       test whether we've found it
            :                 //     else:
              (x - X) ** 2 +  //       compute the squared Euclidean distance between
              (y - Y) ** 2    //       (x, y) and (X, Y)
              < 3 ?           //       if it's less than 3 (i.e. reachable from (X, Y)):
                v - 3 ?       //         if v is not equal to 3:
                  ~v ?        //           if v is not equal to -1:
                    v         //             test if v = 0
                  :           //           else (v = -1):
                    u--       //             set u = -1 to find the other portal
                :             //         else (v = 3):
                  R = R < i ? //           we've found the strawberry: set R = min(R, i)
                      R : i   //
              :               //       else (this tile can't be reached):
                1             //         yield 1
          ) ||                //     if the above result is falsy:
          g(                  //       do a recursive call:
            u,                //         t = u
            x, y,             //         move to (x, y)
            u - ~i,           //         unless u is set to -1, increment i
            r[x] = 1          //         set this tile to a mountain
          ),                  //       end of recursive call
          x                   //     restore r[x] ...
        ] = v                 //     ... to v
    ))                        // end of both map() loops
)(2) | R                      // initial call to g with t = 2; return R

1
“每个访问的磁贴都临时设置在山上,以防止海龟在同一磁贴上移动两次”,这真是个绝妙的招。很好的答案,我一如既往地感谢您的解释:)
akozi

5

Python 2 441个 431 341字节

from itertools import*
G=input()
W=len(G[0])
H=len(G)
A=[0]*5
E=enumerate
for y,r in E(G):
 for x,C in E(r):A[C]=[x,y]
for L in count():
 for M in product(*[zip('UDLR'*2,'LRDU    ')]*L):
  x,y=A[0]
  for m in M:
    x+='R'in m;x-='L'in m;y+='D'in m;y-='U'in m
    if(x,y)==A[3]:x,y=A[2]
    if 1-(W>x>-1<y<H)or G[y][x]>3:break
  if[x,y]==A[1]:exit(L)

在线尝试!

输入为列表,但使用数字代替字符(感谢Quintec),并使用一个单独的值作为传送器的目的地。如果Stack Exchange将其删除,则大的缩进应为制表符。我特别欢迎任何提示或想法,因为我认为这可能会缩短很多

下表是挑战程序所用字符的表格,但您也可以使用 此程序

Challenge | My program
T         | 0
S         | 1
E         | 2
O         | 3
M         | 4
X         | -1

借助Quintec,将输入从使用字符更改为数字,从而获得了-10个字节。

-多亏了Jonathan Frech,ElPedro和Jonathan Allan的帮助。


2
您可以通过列出每个对象用数字而不是字符串表示的列表来减少一些字符。
Quintec

@Quintec添加,谢谢。我想对方向做同样的事情,但是对角线必须分开做。仍然有可能将它们移动到数字上。
nedla2004

1
@ElPedro Ahha我可以像这样
Jonathan Allan

1
...以及356的
乔纳森·艾伦

2
@JonathanAllan和ElPedro和Jonathan French。所有人的好建议,我已经将它们加在一起,并结合了我提出的一些建议。(经过
长时间的

2

Python 2,391 397 403 422字节

M=input()
from networkx import*
a=b=c=d=0
N,h,w,S=[-1,0,1],len(M),len(M[0]),[]
for i in range(h):
 for j in range(w):
  I,m=(i,j),M[i][j]
  if m>7:c,d=a,b;a,b=I
  if m<0:Z=I
  if m==5:F=I
  S+=[I+I]
S+=[(a,b,c,d),(c,d,a,b)]
print len(shortest_path(from_edgelist([((A+p,B+q),(C,D))for A,B,C,D in S for p,q in[(p,q)for p in N for q in N]if-1<A+p<h and-1<B+q<w and M[C][D]*M[A+p][B+q]]),Z,F))-1

在线尝试!

问题被转化为图形,解决方案是找到从乌龟到草莓的最短路径。

Challenge | This code
T         | -1
S         |  5
O         |  8
M         |  0
X         |  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.