Пути и время истощения

22

посылка

Так что недавно я был на полчаса раньше, чем на прием, и решил подождать снаружи. Я также решил, что было бы странно, если бы я просто стоял неподвижно перед домом. Поэтому я решил быстро прогуляться в пределах ограниченного пространства. Я также пришел к выводу, что если бы я начал ходить по кругу, это сделало бы очевидным, что я слонялся без дела. Поэтому я был вдохновлен на создание своего первого соревнования Code Golf.

Спецификация

Вам будет предоставлен список, карта области, которая будет содержать либо, " "либо "#", которые представляют свободные пространства и препятствия в некотором роде. Свободные места могут пересекаться только один раз, и пересечение занимает 1 минуту. Ваша начальная позиция будет обозначена в "@"соответствии с традицией roguelike, и цель будет представлена ​​с, "$"потому что это то, что вы собираетесь потерять там. Вам также дадут целое число, которое будет представлять, сколько минут вы должны потратить, прежде чем не будет казаться, что вы вторгаетесь. Когда вы приземлитесь на"$", это должно было быть точное количество минут (поэтому, если вы выполняли обратный отсчет, это должно быть 1 на соседней плитке и 0 на плитке). Всегда будет возможность добраться до места назначения. Ваша программа или функция должна будет вернуть список, показывающий кратчайший путь с помощью <,>, ^ и v, чтобы представить четыре возможных направления.

Примеры

Входные данные:

[[" ", " ", " ", " "],
 ["@", " ", " ", "$"],
 [" ", " ", " ", " "],
 [" ", " ", " ", " "]]

а также

5

Ouput:

[[">", ">", ">", "v"],
 ["^", " ", " ", "$"],
 [" ", " ", " ", " "],
 [" ", " ", " ", " "]]

Входные данные:

[[" ", "#", " ", " ", " "],
 [" ", "#", " ", " ", " "],
 ["@", "#", " ", "$", " "],
 [" ", " ", " ", " ", " "],
 [" ", "#", " ", " ", " "],
 [" ", "#", " ", " ", " "]]

а также

7

Выход:

[[" ", "#", " ", " ", " "],
 [" ", "#", ">", "v", " "],
 ["v", "#", "^", "$", " "],
 [">", ">", "^", " ", " "],
 [" ", "#", " ", " ", " "],
 [" ", "#", " ", " ", " "]]

Входные данные:

[[" ", "#", " ", " ", " "],
 [" ", "#", " ", " ", " "],
 ["@", "#", " ", "$", " "],
 [" ", " ", " ", " ", " "],
 [" ", "#", " ", " ", " "],
 [" ", "#", " ", " ", " "]]

а также

17

Выход:

[[" ", "#", " ", "v", "<"],
 [" ", "#", " ", "v", "^"],
 ["v", "#", " ", "$", "^"],
 [">", ">", "v", ">", "^"],
 [" ", "#", "v", "^", "<"],
 [" ", "#", ">", ">", "^"]]

правила

  • Применяются стандартные лазейки
  • Каждая плитка должна быть перемещена только один раз
  • Точное количество времени должно быть проведено на доске
  • В случае нескольких путей должен отображаться только один путь
  • Это вопрос игры в гольф, поэтому выигрывает самый короткий ответ
  • В соответствии с вопросом user202729 в ​​комментариях, вы можете принять правильные данные.

Добавить комментарий, если требуется дальнейшее уточнение

LForchini
источник
1
Гарантируется ли, что «всегда будет возможность достичь пункта назначения в указанное время »?
user202729
Да, так и будет, всегда найдется способ, даже если
запутаться
5
Добро пожаловать в PPCG! :) Хороший первый вызов.
Джузеппе
Что случилось с полминуты на каждом конце ?! (не нужно ничего менять, если это не очевидно)
Джонатан Аллан

Ответы:

6

JavaScript (ES6), 171 байт

Принимает ввод в синтаксис карри (a)(n). Выходы путем изменения входной матрицы.

a=>g=(n,y=a[F='findIndex'](r=>~(i=r[F](v=>v>'?'))),x=i,R=a[y])=>!n--|[-1,0,1,2].every(d=>(R[x]='<^>v'[d+1],(c=(a[Y=y+~-d%2]||0)[X=x+d%2])<1?g(n,Y,X):n|c!='$')&&(R[x]=' '))

Попробуйте онлайн!

комментарии

a =>                           // a[] = input matrix
g = (                          // g = recursive function taking:
  n,                           //   n = number of remaining moves
                               //   (x, y) = current coordinates, initialized as follows:
  y = a[F = 'findIndex'](r =>  //     y = index of the row containing the starting point,
    ~(i = r[F](v => v > '?'))  //         found by iterating over all rows r until we
  ),                           //         find some i such that r[i] > '?'
  x = i,                       //     x = index of the column of the starting point
  R = a[y]                     //   R[] = current row
) =>                           //
  !n-- |                       // decrement n; force failure if we're out of moves
  [-1, 0, 1, 2].every(d =>     // for each direction d, where -1 = left, 0 = up,
    (                          // 1 = right and 2 = down:
      R[x] = '<^>v'[d + 1], (  //   update the current cell with the direction symbol
        c = (                  //   c = content of the new cell at (X, Y) with:
          a[Y = y + ~-d % 2]   //     Y = y + dy
          || 0                 //     (use a dummy value if this row does not exist)
        )[X = x + d % 2]       //     X = x + dx
      ) < 1 ?                  //   if c is a space:
        g(n, Y, X)             //     we can go on with a recursive call
      :                        //   else:
        n | c != '$'           //     return false if n = 0 and we've reached the target
    ) &&                       //   unless the above result is falsy,
    (R[x] = ' ')               //   restore the current cell to a space
  )                            // end of every()
Arnauld
источник
5

Python 2 , 310 256 байт

Спасибо @cairdcoinheringaahing за except:0-3 байта
Спасибо @Mnemonic за -8 байтов
Спасибо @JonathanAllan за -3 байта
Спасибо @ovs за -5 байтов

G,L=input()
R=[]
def S(x,y,G,c,R):
 try:
	if x>-1<y<G[y][x]in' @':i=0;exec"T=[r[:]for r in G];T[y][x]='<v^>'[i];S(x+~-i/2,y+~-(i^2)/2,T,c-1,R);i+=1;"*4
	R+=[G]*(0==c<'$'==G[y][x])
 except:0
for i,y in enumerate(G):"@"in y>S(y.index("@"),i,G,L,R)
print R[0]

Попробуйте онлайн!

Некоторое объяснение:

try-exceptиспользуется для обеспечения того, чтобы xи yкоординаты, и координаты находились в границах. Исключение будет поднят при доступе кG[y][x] . Python слишком хорош и отрицательные индексы приемлемы, поэтому проверка x>-1<yдобавлена.

T=[r[:]for r in G] используется для создания копии G по значениям

~-i/2и ~-(i^2)/2используются для генерации пар (-1, 0), (0, 1), (0, -1), (1, 0), которые используются для перемещения в сетке (путь должен быть еще короче!)

R+=[G]*(0==c<'$'==G[y][x])проверьте, что '$'достигнуто требуемое количество шагов.Rиспользуется для получения этого результата от рекурсивных вызовов функций.

for i,y in enumerate(G):"@"in y>S(y.index("@"),i,G,L,R)Найдено xи yиз '@'во входной и вызове функции S.

print R[0] R может содержать более одного решения, поэтому выводите только сначала

Мертвый Опоссум
источник
-4 байта
caird coinheringaahing
1
Вы можете сохранить байт, заменив if G[y][x]=='$':на if'$'==G[y][x]:.
1
На самом деле, все это условие можно заменить R+=(G[y][x]=='$')*(c==0)*[G]на другой байт.
1
Да, не уверен, что я видел. Вы можете сохранить пару байтов в первом условии с помощьюif(x>-1<y)*(G[y][x]in' @'):
1
Более короткий путь для вас y+cmp(i%2,i/2)будет y+~-(i^2)/2; там может быть еще короче.
Джонатан Аллан
2

Python 2 , 264 261 251 249 байт

def f(a,n,r=-1,s=0):
 j=len(a[0]);x=1;z=y=0
 if r<0:s,r=divmod(sum(a,[]).index('@'),j)
 for c in'>v<^':
	u=r+x;v=s+y;x,y=-y,x
	if j>u>-1<v<len(a):b=[e[:]for e in a];b[s][r]=c;w=a[v][u];z=n*(w<'!')and f(b,n-1,u,v)or n==1and w=='$'and b
	if z:return z

Попробуйте онлайн!

Час Браун
источник
1
@Arnauld: Ой! Получил слишком причудливый. Исправлена.
Час Браун