Черепаха знаходить портал


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. Він ніколи не рухається на a teleporterі залишається там для руху

  • Найкоротший шлях не потребує використання порталу

  • Черепаха не може перейти в гірські черепиці

  • Ви можете використовувати будь-який ASCII символ або ціле число , щоб представити mountains, turtle, empty grid square,strawberry

  • Ви можете використовувати або один і той же символ, або два різних символи 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

Пропоновані виклики Поради щодо редагування: Каміль-Дракарі , яловичина

Загальні поради щодо редагування: okx nedla2004 mbomb007


2
Я думаю, що було б хорошою ідеєю додати тестовий випадок, коли використання телепортатора зайняло б більше часу.
Okx

@Okx Створення та додавання зараз.
акозі

Відредаговано, спасибі
akozi

1
@xnor Я вважаю, що це може бути абстрагуватися від моїх початкових правил. Тож, мабуть, краще порталам користуватися одним предметом?
akozi

1
Пов'язані (я думаю).
Чарлі

Відповіді:


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

Спробуйте в Інтернеті!

Як?

Основна рекурсивна функція пошуку здатна або шукати конкретну плитку на дошці (якщо вона називається за допомогою ), або будь-яку плитку в якої можна дійти з поточного положення .gtt0(x,y)(X,Y)

Він відслідковує довжину поточного шляху в та оновлює найкращий результат до щоразу, коли черепаха знайде полуницю.iRmin(R,i)

Спочатку викликається з щоб знайти вихідне положення черепахи.t=2

Він називає себе з якщо досягнутий портал, так що черепаха телепортується на інший портал. Ми не збільшуємо під час такої ітерації.t=1i

Кожна відвідана плитка тимчасово встановлюється на гору, щоб запобігти пересуванню черепахи двічі по одній плитці однією і тією ж стежкою. Якщо ми спіймані в пастку в глухий кут, рекурсія просто зупиняється без поновлення .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

Пітон 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

-10 байт завдяки Quintec за зміну введення з використання символів на числа.

-Багато байтів завдяки Джонатану Фреху, ЕльПедро та Джонатану Аллану.


2
Можливо, ви можете поголити кілька символів, взявши список, де кожен об'єкт представлений цифрою замість символу рядка.
Квінтек

@Quintec Додано, спасибі Я хотів би зробити те ж саме для напрямків, але тоді діагоналі доведеться робити окремо. Однак все-таки можливо перенести їх на номери.
nedla2004

1
@ElPedro Ahha я можу голитися 4 від , як це
Джонатан Аллана

1
... і ще 10 за 356
Джонатан Аллан

2
@JonathanAllan та ElPedro та Jonathan French. Чудові поради від усіх вас, і я додав їх разом із кількома речами, які я придумав. (Після великої затримки)
nedla2004

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.