Проблема втраченої пішаки


14

Проблема втраченої пішаки

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

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

Проблему порівняно легко вирішити в O (n ^ 2) за допомогою динамічного програмування, але це кодегольф, і нам не байдуже такі непотрібні речі, як складність часу роботи ...

Проблема

вхід: 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 ассі вивід, що показує найкращий (найкоротший, тобто мінімальна сума ваги) шлях (якщо оптимального результату більше 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#
#####/##
####/###
#####\##
#####|##
######\#
######|#
#######\

це , тому найкоротший код виграє.

грати справедливо. немає лазівки ...

Редагувати:

Я написав рішення, що не входить в гольф, прямо в масштабі, який ви можете подивитися. Існує також веб-сайт, на якому можна грати в режимі он-лайн з кодом 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 (\ команда в перший запит). На відміну від цього, «багатослівна» (розбірлива) версія мови вимагає написання сценарію з розширенням 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]. Ми відкидаємо перший компонент вартості (зміщуємо і alineates стовпці для додавання) і підсумовуємо компонент до компонента

  • вартість попереднього значення i плюс до [i]. Підсумовуємо компонент до компонента

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

Для обчислення мінімальної величини ми заповнюємо ліву вартість, передбачивши нескінченну, а праву вартість додаючи нескінченну: за допомогою 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#
#####/##
####/###
#####\##
######\#
######|#
######|#
#######\

Я ніколи не чув про Q, але дякую за таку детальну відповідь :)
gilad hoch
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.