Проблема потерянной пешки

14

Проблема потерянной пешки

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

Первоначальная задача описывает nXn «шахматную» доску и функцию f: {1,..,n-1}X{1,..,n}X{-1,0,1} => R+весов. цель состоит в том, чтобы найти лучший путь от некоторого квадрата в нижней строке до другого квадрата в верхней строке, где возможны следующие движения: вверх-вверх, вверх-вправо, и вы не можете выйти с игрового поля.

Эту проблему относительно легко решить в O (n ^ 2) с помощью динамического программирования, но это Codegolf, и нас не волнуют бесполезные вещи, такие как сложность во время выполнения ...

Проблема

input: 3-мерный массив (или другой набор по вашему выбору, полученный через stdin или в качестве аргумента функции), соответствующий обычной шахматной доске, точно по размеру: 7X8X3 (#linePasses X #rowSize X #movesPerPass), содержащий неотрицательные целые числа. стоимость перемещения из некоторой позиции, (i,j)где iнаходится индекс строки и индекс jстолбца:

  • a[i][j][0]за стоимость путешествовать вверх-влево на площадь (i+1,j-1), или графически: \.
  • a[i][j][1]за затраты на проезд до площади (i+1,j), или графически: |.
  • a[i][j][2]за стоимость путешествовать вверх прямо на площади (i+1,j+1), или графически: /.

Вы можете предположить, что он не будет содержать путь, сумма которого больше, чем MAX_INT.

вывод: вывод 8x8 ascii, показывающий лучший (самый короткий, т.е. минимальная сумма весов) путь (если имеется более 1 оптимального результата, вы можете показать произвольный путь по вашему выбору). путь рисуется снизу вверх, где в каждой строке символ, соответствующий положению пешки на пути, является тем, который он собирается сделать. Например, если пешка собирается переместиться вверх-влево от столбца 3 (к столбцу 2), вы должны нарисовать:

#?######
##\#####

где ?следует заменить следующим ходом. Окончательная позиция должна быть нарисована как X.

Примеры

вход:

[
  [[1,1,1],[1,1,1],[0,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,0,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,1,0],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,1,1],[1,1,0],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,1,1],[1,1,1],[1,0,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,1,1],[1,1,1],[1,0,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,1,1],[1,1,1],[0,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]]
]

выход:

##X#####
###\####
###|####
###|####
##/#####
#/######
#|######
##\#####

вход:

[
  [[41,27,38],[12,83,32],[50,53,35],[46,32,26],[55,89,82],[75,30,87],[2,11,64],[8,55,22]],
  [[56,21,0],[83,25,38],[43,75,63],[56,60,77],[68,55,89],[99,48,67],[94,30,9],[62,62,58]],
  [[23,18,40],[24,47,61],[96,45,72],[71,6,48],[75,63,98],[93,56,51],[23,31,30],[49,34,99]],
  [[20,47,42],[62,79,72],[32,28,44],[68,61,55],[62,39,57],[4,17,49],[97,85,6],[91,18,12]],
  [[51,50,11],[32,39,56],[12,82,23],[33,88,87],[60,55,22],[29,78,14],[70,11,42],[63,94,67]],
  [[75,64,60],[27,79,86],[70,72,56],[55,45,32],[95,67,12],[87,93,98],[81,36,53],[38,22,93]],
  [[31,80,50],[77,71,22],[59,46,86],[64,71,53],[41,19,95],[62,71,22],[92,80,41],[26,74,29]]
]

выход:

######X#
#####/##
####/###
#####\##
#####|##
######\#
######|#
#######\

это , поэтому выигрывает самый короткий код.

играй честно. никаких лазеек ...

РЕДАКТИРОВАТЬ:

Iv'e написал решение для scala, которое вы можете посмотреть. Есть также сайт, на котором вы можете играть с помощью scala-кода в режиме онлайн: scalakata (просто скопируйте и вставьте его в scalakata и нажмите кнопку воспроизведения)

Гилад Хох
источник

Ответы:

5

Q: 199 байт

f:{m::x;n::{@/[+/-1 0 1_\:/:(x;m[y;;|!3]);0 2;(0W,),{x,0W}]};i:*<*|r:{&/n[x;y]}\[8#0;!7];  s:{-1+{*<x}'+n[y;z]}\[();(,8#0),-1_r;!7];j:i,{x+y x}\[i;|s];-1(@[8#"#";;:;]'[j;"X","/|\\"1+s'[|!7;-1_j]]);}

ПРИМЕЧАНИЯ

  • Q-интерпретатор (kx.com) бесплатно для некоммерческого использования (версии для Windows, Linux, Mac)
  • В этом решении используется внутреннее ядро ​​Q (внутреннее имя k4), поэтому нам нужен файл сценариев с расширением k или интерактивный интерпретатор в режиме k (\ command in first prompt). Напротив, для «подробной» (разборчивой) версии языка требуется скрипт с расширением q, и он является режимом по умолчанию для интерактивного переводчика.

ТЕСТОВОЕ ЗАДАНИЕ

f ((1 1 1; 1 1 1; 0 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 0 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 1 0; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 1 1; 1 1 0; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 1 1; 1 1 1; 1 0 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 1 1; 1 1 1; 1 0 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 1 1; 1 1 1; 0 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1))

##X#####
###\####
###|####
###|####
##/#####
#/######
#|######
##\#####

f ((41 27 38; 12 83 32; 50 53 35; 46 32 26; 55 89 82; 75 30 87;  2 11 64;  8 55 22)
   (56 21  0; 83 25 38; 43 75 63; 56 60 77; 68 55 89; 99 48 67; 94 30  9; 62 62 58)
   (23 18 40; 24 47 61; 96 45 72; 71  6 48; 75 63 98; 93 56 51; 23 31 30; 49 34 99)
   (20 47 42; 62 79 72; 32 28 44; 68 61 55; 62 39 57;  4 17 49; 97 85  6; 91 18 12)
   (51 50 11; 32 39 56; 12 82 23; 33 88 87; 60 55 22; 29 78 14; 70 11 42; 63 94 67)
   (75 64 60; 27 79 86; 70 72 56; 55 45 32; 95 67 12; 87 93 98; 81 36 53; 38 22 93)
   (31 80 50; 77 71 22; 59 46 86; 64 71 53; 41 19 95; 62 71 22; 92 80 41; 26 74 29))

######X#
#####/##
####/###
#####\##
######\#
######|#
######|#
#######\

ОБЪЯСНЕНИЕ

Для иллюстрации мы предполагаем второй тест (матрица ((41 27 38; 12 83 32; ....)

Мы преобразуем исходную матрицу (m на уровне кода): вместо оргинальной матрицы с триплетом для каждой координаты мы определяем матрицу для смещений влево, вверх и вправо. Левая матрица содержит значения 7x7 (мы опускаем первый столбец), матрицу Up 7x8 и правую матрицу 7x7 (мы обрезаем последний столбец).

left                           up                         right
12 50 46 55 75 2  8       27 83 53 32 89 30 11 55     38 32 35 26 82 87 64
83 43 56 68 99 94 62      21 25 75 60 55 48 30 62     0  38 63 77 89 67 9 
24 96 71 75 93 23 49      18 47 45 6  63 56 31 34     40 61 72 48 98 51 30
62 32 68 62 4  97 91      47 79 28 61 39 17 85 18     42 72 44 55 57 49 6 
32 12 33 60 29 70 63      50 39 82 88 55 78 11 94     11 56 23 87 22 14 42
27 70 55 95 87 81 38      64 79 72 45 67 93 36 22     60 86 56 32 12 98 53
77 59 64 41 62 92 26      80 71 46 71 19 71 80 74     50 22 86 53 95 22 41

Чтобы рассчитать окончательную позицию, нам нужно оценить путь с минимальными затратами. Мы предполагаем начальную стоимость 0 0 0 0 0 0 0 0 (стоимость доставки в каждый столбец первой строки) и выполняем итерации с каждой следующей строкой. В каждом столбце i мы вычисляем три значения:

  • стоимость предыдущего значения i + 1 плюс оставленное [i + 1]. Мы отбрасываем первый компонент стоимости (смещаем и выравниваем столбцы для добавления) и суммируем компонент в компонент

  • стоимость предыдущего значения i плюс up [i]. Суммируем компонент в компонент

  • стоимость предыдущего значения i-1 плюс право [i-1]. Мы отбрасываем последний компонент стоимости (смещаем и выравниваем столбцы для добавления) и суммируем компонент в компонент

Чтобы вычислить минимум, мы завершаем левую стоимость, добавляя бесконечную, а правую стоимость добавляя бесконечную: с 3 векторами из восьми компонентов вычисляем минимальный компонент для компонента. Итоговое значение - это базовая стоимость для новой итерации.

Для первой итерации получаем значения (0W бесконечно в Q)

0W 12 50 46 55 75 2  8
27 83 53 32 89 30 11 55
38 32 35 26 82 87 64 0W

и рассчитывает минимум каждого столбца

27 12 35 26 55 30 2 8

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

0   0   0   0   0   0   0   0
27  12  35  26  55  30  2   8
27  37  78  82  110 78  11  70
45  61  123 88  173 129 34  104
87  123 151 143 212 133 40  122
98  155 163 176 234 147 51  185
158 182 219 208 246 234 87  207
208 204 265 261 265 256 128 233

Теперь мы нашли минимальное значение в последней строке (128, в столбце 6). Это конец пути (символ X в выходе).

Мы повторяем расчет стоимости снова, но теперь мы аннотируем направление, из которого получаем каждый минимум (который из 3 значений, используемых для расчета минимума, является выбранным значением).

\|/|\///
\\\\\/|/
\\\|//|/
\\|\//|/
\\|//|\/
\\//|\|/
\|/|/|\/

Мы переворачиваем строки, помещаем 'X' в позицию 6 и сохраняем только путь, который заканчивается в столбце 6 (остальные заменяются на #)

######X#
#####/##
####/###
#####\##
######\#
######|#
######|#
#######\
Дж. Сендра
источник
Iv'e никогда не слышал о Q, но спасибо за такой подробный ответ :)
Gilad Hoch