Найти колыбельную поджигателя

26

Представьте себе поджигателя, гуляющего по городу и собирающего его жертв в соответствии с очень специфическим рисунком (или, альтернативно, представьте себе пчелу, летящую по саду и собирающую цветы для опыления в соответствии с очень специфическим рисунком ). Скажем, город представляет собой матрицу N × N , где N - это целое число, большее или равное 2 . Поджигатель начинает с верхнего левого угла и последовательно устанавливает точки дома М перед собой (где М - номер дома, в котором они находятся), изменяя направление движения после каждого пожара в следующем порядке: Восток, Юг, Запад, Север, Восток, Юг ... и так далее. колыбельнаяПоджигатель - это значение М, которое заставляет их покинуть город (то есть последний дом, который они посещают перед тем, как остановить мерзость). Это гораздо проще понять на примере. Возьмите следующую матрицу, например:

3 2 3 2 7
3 1 4 1 6
2 5 3 1 1
4 4 3 2 4
1 1 1 1 1
  • Мы начинаем в верхнем левом углу, поэтому M = 3 ( Xотмечает текущую и предыдущую позиции поджигателя):
    X 2 3 2 7
    3 1 4 1 6
    2 5 3 1 1
    4 4 3 2 4
    1 1 1 1 1
    
  • Согласно известному порядку, он сначала идет на восток (3) пятна и приземляется на 2, поэтому M изменяется соответственно:
    X 2 3 X 7
    3 1 4 1 6
    2 5 3 1 1
    4 4 3 2 4
    1 1 1 1 1
    
  • Тогда это идет на юг 2 пятна, и M теперь 1 :
    X 2 3 X 7
    3 1 4 1 6
    2 5 3 X 1
    4 4 3 2 4
    1 1 1 1 1
    
  • Теперь он перемещается на 1 позицию на запад, а М становится 3 :
    X 2 3 X 7
    3 1 4 1 6
    2 5 XX 1
    4 4 3 2 4
    1 1 1 1 1
    
  • После того, как он движется на 3 точки на север, он выходит из города! Следовательно, 3 - это колыбельная этого поджигателя:
        Икс
    X 2 3 X 7
    3 1 4 1 6
    2 5 XX 1
    4 4 3 2 4
    1 1 1 1 1
    

Учитывая N × N матрицу (вы также можете принять N в качестве входных данных), найдите колыбельную поджигателя. Я написал программу, с помощью которой вы можете сгенерировать больше тестов и визуализировать путь поджигателя: попробуйте онлайн!

  • Можно предположить , что поджигатель делает есть колыбельную (то есть, на самом деле может выйти из матрицы).
  • Для простоты матрица будет содержать только положительные целые числа, меньшие или равные 9 (цифрам). Решения, которые обрабатывают любое положительное целое число, полностью приветствуются.
  • Обратите внимание, что поджигатель может приземлиться в месте, где он уже сожжен, в случае, если смысл, в котором он движется, отличается от первого раза. В таком случае просто возьмите значение этого элемента и двигайтесь снова, как обычно.
  • Вы можете соревноваться на любом языке программирования и можете принимать и выводить данные любым стандартным методом , при этом отмечая, что эти лазейки по умолчанию запрещены. Это , поэтому выигрывает самое короткое представление (в байтах) для каждого языка .

Контрольные примеры

-------------
9 2 3
1 7 2
8 7 6

Колыбельная: 9
-------------
2 1 2 1
3 1 1 2
1 2 2 1
1 1 1 3

Колыбельная: 2
-------------
3 2 3 2 7
3 1 4 1 6
2 5 3 1 1
4 4 3 2 4
1 1 1 1 1

Колыбельная: 3
-------------
1 2 1 2 1 2
1 2 1 2 1 2
1 2 1 2 1 2
1 2 1 2 1 2
1 2 1 2 1 2
1 2 1 2 1 2

Колыбельная: 2
-------------
3 2 1 2 1 1 1
2 3 2 3 2 1 1
2 1 1 1 3 1 2
3 1 1 1 1 1 1
4 5 2 3 1 1 1
1 2 1 2 1 2 2
1 2 2 3 2 1 2

Колыбельная: 3
-------------

Матрицы в другом формате:

[[9, 2, 3], [1, 7, 2], [8, 7, 6]]
[[2, 1, 2, 1], [3, 1, 1, 2], [1, 2, 2, 1], [1, 1, 1, 3]]
[[3, 2, 3, 2, 7], [3, 1, 4, 1, 6], [2, 5, 3, 1, 1], [4, 4, 3, 2, 4], [ 1, 1, 1, 1, 1]]
[[1, 2, 1, 2, 1, 2], [1, 2, 1, 2, 1, 2], [1, 2, 1, 2, 1, 2], [1, 2, 1, 2, 1, 2], [1, 2, 1, 2, 1, 2], [1, 2, 1, 2, 1, 2]]
[[3, 2, 1, 2, 1, 1, 1], [2, 3, 2, 3, 2, 1, 1], [2, 1, 1, 1, 3, 1, 2], [ 3, 1, 1, 1, 1, 1, 1], [4, 5, 2, 3, 1, 1, 1], [1, 2, 1, 2, 1, 2, 2], [1, 2, 2, 3, 2, 1, 2]]

Пятый контрольный пример очень интересен для визуализации .

Мистер Xcoder
источник
1
Это как обобщение Skip как Кролика в двух измерениях с немного другой целью. Тематика этого конкурса и его название были вдохновлены песней Hozier
Mr. Xcoder
что происходит, когда поджигатель приземляется на площади, которая уже сожжена?
Уровень Река St
2
Можем ли мы предположить, что поджигатель на самом деле не поджигатель и вместо этого делает что-то хорошее в каждом месте, а не сжигает его? +1 за очень хорошую идею :)
ElPedro
2
@ElPedro Конечно, альтернативная версия для вас: представьте, как пчела летает по саду и собирает цветы для опыления в соответствии с очень специфическим рисунком. : D Счастливого дружеского гольфа!
Мистер Xcoder
1
Это гораздо более приятная мысль. Если бы я мог снова проголосовать, я бы за это.
ElPedro

Ответы:

11

MATL , 32 байта

JQ6*`G5thYay&Zj3$)wyJ2@-^*+8M]b&

Попробуйте онлайн! Или проверьте все тестовые случаи .

Как это работает

Входная матрица дополняется рамкой из пяти нулей, например,

3 2 3 2 7
3 1 4 1 6
2 5 3 1 1
4 4 3 2 4
1 1 1 1 1

становится

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 3 2 3 2 7 0 0 0 0 0
0 0 0 0 0 3 1 4 1 6 0 0 0 0 0
0 0 0 0 0 2 5 3 1 1 0 0 0 0 0
0 0 0 0 0 4 4 3 2 4 0 0 0 0 0
0 0 0 0 0 1 1 1 1 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Рамка нулей используется для определения того, когда пчела- поджигатель покинула матрицу. Расширение с пятью нулями гарантирует, что модульное смещение длины вплоть до 9любого направления от любой ненулевой записи будет корректно попадать в ноль, не переходя к некоторой ненулевой записи.

В матричных координатах пчела начинается с входа (6,6)в расширенную матрицу. Он читает эту запись и обновляет координаты по мере необходимости, применяя (модульное) смещение длины считывания в соответствующем направлении. Это повторяется в цикле, пока не будет прочитано значение 0. Запись, которая была прочитана до этого (то есть последняя ненулевая запись), является выходной.

Координаты на самом деле хранятся в виде комплексного числа, например, (6,6)становится 6+6j. Таким образом, четыре циклических направления могут быть реализованы как степени мнимой единицы. Соответствующая мощность ( j, 1, -jили -1) умножаются на записи для чтения , чтобы получить сложное перемещение , которое используется для обновления координат.

Последовательные считанные значения хранятся в стеке. Когда цикл завершается, в стеке содержатся все ненулевые значения чтения по порядку, затем последнее значение чтения 0, а затем последние комплексные координаты. Таким образом, третий верхний элемент - это требуемый результат.

Луис Мендо
источник
1
+1 за очень инновационный подход.
LastStar007
7

JavaScript (ES6), 70 68 байт

m=>(g=d=>(n=(m[y]||0)[x])?g(--d&3,x-=d%2*(y+=--d%2*n,L=n)):L)(x=y=0)

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

комментарии

m => (                        // given m = input matrix
  g = d =>                    // g = recursive function taking the direction d
    (n = (m[y] || 0)[x]) ?    // let n be the content of the current cell; if it's defined:
      g(                      //   do a recursive call:
        --d & 3,              //     with the next direction (0 = E, 3 = S, 2 = W, 1 = N)
        x -=                  //     update x by subtracting ...
          d % 2 * (           //       ... ((d - 1) % 2) * n
            y += --d % 2 * n, //       and update y by adding ((d - 2) % 2) * n
            L = n             //       save n into L
          )                   //     end of x update
      )                       //   end of recursive call
    :                         // else:
      L                       //   stop recursion and return L
)(x = y = 0)                  // initial call to g() with x = y = d = 0

Учитывая, что по модулю в JS используется знак дивиденда, направление обновляется следующим образом:

 d | d' = --d&3 | dx = -(d%2)  | dy = --d%2 | direction
---+------------+--------------+------------+------------------
 0 |     3      | -(-1%2) = +1 | -2%2 =  0  | (+1,  0) = East
 3 |     2      | -( 2%2) =  0 |  1%2 = +1  | ( 0, +1) = South
 2 |     1      | -( 1%2) = -1 |  0%2 =  0  | (-1,  0) = West
 1 |     0      | -( 0%2) =  0 | -1%2 = -1  | ( 0, -1) = North
Arnauld
источник
4

Древесный уголь , 25 18 байт

PS↶WKK«≔ιθ×Iι¶↷»⎚θ

Попробуйте онлайн! Ссылка на подробную версию кода. Объяснение:

PS

Напечатайте входную строку, но не перемещайте позицию печати.

Поверните шарнир влево, чтобы направление печати стало вверх.

WKK«

Повторите, пока под позицией печати находится символ.

≔ιθ

Сохраните символ в переменной.

×Iι¶

Приведите персонажа к числу и выведите столько строк перевода. Поскольку направление печати увеличено, печать заканчивается горизонтально. В результате мы переместили позицию печати в желаемом направлении на величину, указанную числом под позицией печати.

↷»

Поверните ось поворота, чтобы следующие новые строки переместили позицию печати в следующем направлении по часовой стрелке для следующего прохода цикла.

F⟦ωθ⟧¿ιι⎚

К сожалению, у нас все еще есть входные данные, загромождающие наш холст, и еще более к сожалению, если мы очищаем холст, мы также очищаем нашу переменную. Итак, это небольшая хитрость: список пустой строки и переменной зацикливается. На первом проходе цикла переменная цикла пуста, поэтому холст, переменная цикла и переменная результата очищаются. Но цикл еще не закончен! На втором проходе цикла мы все равно получаем доступ к нашей переменной, тщательно сохраненной в нашем списке циклов. Осталось просто напечатать его.

⎚θ

Очистите холст и распечатайте сохраненную переменную. (Спасибо @ ASCII-только за исправление углем.)

Нил
источник
2

Древесный уголь , 50 49 46 34 33 26 байтов

NθEθSMθ↑WKK«MIι✳⊗Lυ⊞υι»⎚⊟υ

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

Ссылка на подробную версию кода

Ввод должен быть N на отдельной строке, затем строки массива на отдельных строках после этого.

Любые способы сбить байты приветствуются и желательны, так как я не очень хороший игрок в древесный уголь!

-12 байт благодаря @Neil! -1 байт благодаря @ ASCII-only! -7 байт благодаря @ ASCII-only (исправлена ​​ошибка, приводившая к Clearсбросу переменных)

Zachary
источник
1

Красный , 145 байт

func[b][h:[0 1 0 -1 0]x: y: 1 i: 0
until[y: h/(i: i % 4 + 1) *(t: b/(y)/(x)) + y x: h/(i + 1) * t + x none = b/(y) or(x < 1 or(x > length? b))]t]

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

Более читабельно:

f: func[b][
    h: [0 1 0 -1 0]                                ; step lengths (combined for x and y) 
    x: y: 1                                        ; starting coords (1,1)
    i: 0                                           ; step counter 
    until[
        y: h/(i: i % 4 + 1) * (t: b/(y)/(x)) + y   ; next y; t stores the lullaby
        x: h/(i + 1) * t + x                       ; next x
        none = b/(y) or (x < 1 or (x > length? b)) ; until x or y are not valid indices
    ]
    t                                              ; return the lullaby
]
Гален Иванов
источник
1

Чисто , 141 байт

import StdEnv
d=[0,1,1,0,0,-1,-1,0:d]
$m[x,y]n[a,b:l]#r=size m
#u=x+a*n
#v=y+b*n
|0>u||0>v||u>=r||v>=r=n= $m[u,v]m.[u,v]l
?m= $m[0,0]m.[0,0]d

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

Определяет функцию ? :: {#{#Int}} -> Int, беря распакованный массив неупакованных массивов целых чисел и возвращая результат.

Οurous
источник
1

Java 8, 121 байт

m->{int l=m.length,x=0,y=0,f=0,r=0;for(;x*y>=0&x<l&y<l;x+=f<1?r:f==2?-r:0,y+=f==1?r:f>2?-r:0,f=++f%4)r=m[y][x];return r;}

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

Альтернатива с таким же байтовым числом 121 байта:

m->{int l=m.length,x=0,y=0,f=0,r=0;try{for(;;x+=f<1?r:f==2?-r:0,y+=f==1?r:f>2?-r:0,f=++f%4)r=m[y][x];}finally{return r;}}

Использует try-finally вместо проверки, находится ли x,y-coordinate в границах.

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

Объяснение:

m->{                   // Method with integer-matrix parameter and integer return-type
  int l=m.length,      //  Dimensions of the matrix
      x=0,y=0,         //  x,y coordinate, starting at [0,0]
      f=0,             //  Direction-flag, starting at 0 (east)
      r=0;             //  Result-integer
  for(;x*y>=0&x<l&y<l  //  Loop as long as the x,y coordinates are still within bounds
      ;                //    After every iteration:
       x+=f<1?         //     If the direction is east:
           r           //      Increase the `x` coordinate by `r`
          :f==2?       //     Else-if the direction is west:
           -r          //      Decrease the `x` coordinate by `r`
          :            //     Else (it's north/south):
           0,          //      Leave the `x` coordinate the same
       y+=f==1?        //     If the direction is south:
           r           //      Increase the `y` coordinate by `r`
          :f>2?        //     Else-if the direction is north:
           -r          //      Decrease the `y` coordinate by `r`
          :            //     Else:
           0,          //      Leave the `y` coordinate the same
       f=++f%4)        //     Go to the next direction (0→1→2→3→0)
    r=m[y][x];         //   Set `r` to the value of the current cell
  return r;}           //  Return the last `r` before we went out of bounds
Кевин Круйссен
источник
0

Perl 5 , 92 байта

sub b{1while eval join'&&',map{/./;map"(\$$_$&=".'$n=$_[$y][$x])'.$',x,'y'}'+<@_','->=0';$n}

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

Как?

Набор вложенных карт и объединение производят это:

($x+=$n=$_[$y][$x])<@_&&($y+=$n=$_[$y][$x])<@_&&($x-=$n=$_[$y][$x])>=0&&($y-=$n=$_[$y][$x])>=0

который затем оценивается, чтобы определить, заканчивается ли цикл. Поскольку логическое значение оценивается слева направо, значение $nфактически изменяется (до) четыре раза в течение оценки. Поскольку булево логическое короткое замыкание в Perl, значением $nявляется колыбельная при выходе из цикла.

Xcali
источник
0

Python 3 , 85 84 байта

xcoder: -1 (я никогда не помню трюк + ~)

def f(x):
 r=c=0
 while-1<r:d=x[r][c];r,c=len(x)-c+~d,r;x=[*zip(*x)][::-1]
 return d

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

Вместо того, чтобы двигаться в разных направлениях (E, S, W, N), это решение всегда перемещается на восток и поворачивает сетку против часовой стрелки после каждого движения. После поворота последний столбец стал первой строкой, поэтому, если индекс строки меньше нуля, это означает, что мы сбежали с доски.

RootTwo
источник
84 байта : -d-1=>+~d
г-н Xcoder