Учитывая матрицу, состоящую из натуральных чисел, выведите путь с наименьшей суммой при обходе от верхнего левого элемента к нижнему правому. Вы можете двигаться вертикально, горизонтально и по диагонали. Обратите внимание, что можно перемещать вверх / вниз, вправо / влево и по диагонали во все стороны.
Пример:
1* 9 7 3 10 2 2
10 4* 1* 1* 1* 7 8
3 6 3 8 9 5* 7
8 10 2 5 2 1* 4
5 1 1 3 6 7 9*
Путь, дающий наименьшую сумму, отмечен звездочками и приводит к следующей сумме: 1 + 4 + 1 + 1 + 1 + 5 + 1 + 9 = 23 .
Тестовые случаи:
1 1 1
1 1 1
Output: 3
7 9 6 6 4
6 5 9 1 6
10 7 10 4 3
4 2 2 3 7
9 2 7 9 4
Output: 28
2 42 6 4 1
3 33 1 1 1
4 21 7 59 1
1 7 6 49 1
1 9 2 39 1
Output: 27 (2+3+4+7+7+1+1+1+1)
5 6 7 4 4
12 12 25 25 25
9 4 25 9 5
7 4 25 1 12
4 4 4 4 4
Output: 34 (5+12+4+4+4+1+4)
1 1 1 1
9 9 9 1
1 9 9 9
1 9 9 9
1 1 1 1
Output: 15
2 55 5 3 1 1 4 1
2 56 1 99 99 99 99 5
3 57 5 2 2 2 99 1
3 58 4 2 8 1 99 2
4 65 66 67 68 3 99 3
2 5 4 3 3 4 99 5
75 76 77 78 79 80 81 2
5 4 5 1 1 3 3 2
Output: 67 (2+2+3+3+4+5+4+3+3+3+1+2+2+1+3+1+1+4+5+1+2+3+5+2+2)
Это код-гольф, поэтому выигрывает самый короткий код на каждом языке.
code-golf
number
graph-theory
optimization
matrix
Стьюи Гриффин
источник
источник
Ответы:
JavaScript,
442 412 408358 байтЭто моя первая подача PPCG. Обратная связь будет оценена.
Это принимает многомерный массив в качестве входных данных.
объяснение
По сути, перебирайте все ячейки снова и снова, настраивая наименьшую из известных затрат, чтобы добраться до каждого из соседей. В конце концов, сетка достигнет состояния, когда общая стоимость для достижения в правом нижнем углу является самой низкой стоимостью, чтобы добраться туда.
демонстрация
Редактировать: Отдельное спасибо @ETHproductions за помощь мне побрить десятки вкусных байтов.
Еще раз спасибо @Stewie Griffin за ваши советы, которые сбили 50 байтов.
источник
}
что должно сэкономить несколько байтов. Вам также не нужно объявлять свои переменные; Я думаю, что удалениеvar
s должно сэкономить вам еще 24 байта.m[v][t]
в качестве переменной:t=x+X;v=y+Y;k=m[v][t]
будет еще короче ...?Python 3 + NumPy + SciPy ,
239222186 байтПопробуйте онлайн!
источник
Пакет обработки изображений Octave +,
175162157151142139 байтСохранено 14 байтов благодаря @Luis Mendo и 1 байт благодаря @notjagan
Использует пакет обработки изображений, потому что почему бы и нет? Разве не так все решают проблемы с графами?
Попробуйте онлайн!
взорванный
объяснение
Дан массив весов:
Инициализируйте массив затрат, чтобы стоимость каждого элемента равнялась Бесконечности, за исключением начальной точки (левый верхний элемент), стоимость которой равна его весу.
Это итерация 0. Для каждой последующей итерации стоимость достижения ячейки устанавливается на минимум:
После первой итерации стоимость пути к элементу (2,2) (с использованием индексации на основе 1) будет
Полный массив затрат после первой итерации будет:
После итерации
k
каждый элемент будет иметь наименьшую стоимость для достижения этого элемента с самого начала, принимая не болееk
шагов. Например, элемент в (3,3) может быть достигнут за 2 шага (итерации) по цене 22:Но на 4-й итерации путь из 4 шагов найден со стоимостью 20:
Поскольку ни один путь через матрицу mxn не может быть длиннее, чем количество элементов в матрице (как очень свободная верхняя граница), после
m*n
итераций каждый элемент будет содержать стоимость самого короткого пути для достижения этого элемента с самого начала.источник
while
и~
.while
наfor
и все еще мог использовать ваш совет. Благодарность!JavaScript, 197 байт
приукрасить:
источник
Mathematica 279 байт
Основная идея состоит в том, чтобы создать граф с вершинами, соответствующими элементам матрицы, и направленными ребрами между любыми двумя вершинами, разделенными
ChessboardDistance
большим, чем ноль, но меньшим или равным 1. Кстати, это, как известно, известно как граф Кинга , так как он соответствует действительные ходы короля на шахматной доске.FindShortestPath
затем используется, чтобы получить минимальный путь. Он работаетEdgeWeight
, а неVertexWeight
так, поэтому есть некоторый дополнительный код для определенияEdgeWeight
элемента матрицы, соответствующего назначению каждого направленного ребра.Код:
Обратите внимание, что
символ является символом транспонирования. Он будет вставлен в Mathematica как есть.Использование:
Выход:
Если вы установите,
g=Graph[...,GraphLayout->{"GridEmbedding","Dimension"->d},VertexLabels->Thread[s->m]
аp=FindShortestPath[...
затем следующий график будет визуально отображать решение (верхняя часть матрицы соответствует нижней части графика):источник
Haskell, 228 байт
Позиции - это списки из двух элементов, потому что их легко генерировать
sequence
и сопоставлять по образцу с двумя кортежами.Начните с
-1,-1
и посчитайте стоимость каждого шага в поле назначения.Альтернативно первые две строки: начинаются с
0,0
, подсчитываются поля отправления, оканчиваются в координатах, равных размерам матрицы (так внизу справа от цели, которую необходимо добавить в список допустимых пунктов назначения) - точно такой же длины, но медленнее:Использование инфикса for
map
не экономит здесь байты, но я заменяю его, как только он не стоит того, потому что он может стать лучше только при большем количестве применений, а иногда и при других реструктуризациях, которые сбрасывают другую пару скобок.Быть улучшенным: избыточный
filter
s. Слияние / в-выравнивая ихfilter(flip elem$(s$(\x->[0..x])#m)\\p)
сimport Data.List
на\\
расходы 3 байта.Кроме того, слишком плохо
(fromEnumTo 0)
на 2 байта больше, чем(\x->[0..x])
.sum$concat c
суммируется стоимость всех полей и, таким образом, кратко выражаемая верхняя граница стоимости пути, которая задается для того,minimum
чтобы избежать пустого списка (моя программа проверки типов уже определила все, что нужно для работы сInteger
s, так что нет жесткого кодирования максимума Хе-хе). Независимо от того, как я ограничиваю шаги, основанные на предыдущем шаге (который сильно ускорил бы алгоритм, но также и на байтах), я не могу избежать тупиков, которые делают этот откат необходимым.Одна идея фильтра была
((not.e n).zipWith(-)(head r))
с извлечениемn=s[[-1..1],[-1..1]]
, которое требует добавления,[-1,-1]
к начальному пути. Затем алгоритм избегает перехода туда, куда он уже мог пойти на предыдущем шаге, что делает переход на граничное поле ортогонально этому краю тупиком.Другой был
((>=0).sum.z(*)d)
с извлечениемz=zipWith
, которое вводит новый аргументd
в рекурсивную функцию, которая дается как(z(-)p q)
в рекурсии, так и[1,1]
в начальном случае. Алгоритм избегает последовательных шагов с отрицательным скалярным произведением (d
что является предыдущим шагом), что означает отсутствие резких поворотов на 45 °. Это по-прежнему значительно сужает выбор и позволяет избежать предыдущего тривиального тупика, но все же есть пути, которые в конечном итоге будут заключены в уже посещенных полях (и, возможно, «побег», который, однако, будет резким поворотом).источник
Python 2,
356320 байтПопробуй это здесь!
-36 байт благодаря нотьягану !
Получает список списков в качестве входных данных и выводит наименьшую стоимость при перемещении по матрице сверху слева внизу справа.
объяснение
Найдите все возможные маршруты от верхнего левого до нижнего правого угла матрицы, создав список координат x, y для каждого маршрута. Маршруты не могут быть возвращены, и они должны заканчиваться в
(len(s)-1,len(s[0])-1)
.Суммируйте целые числа на каждом пути координат и возвращайте минимальную стоимость.
print
Может быть легко изменен , чтобы вывести список координат для кратчайшего маршрута.источник
or
для условных. Спасибо!APL (Dyalog Classic) , 33 байта
Попробуйте онлайн!
{ }
функция с аргументом⍵
+\+⍀⍵
возьмите частичные суммы по строкам и столбцам, чтобы установить пессимистическую верхнюю границу расстояний пути( )⍣≡
повторить до схождения:(⍉3⌊/⊣/,⊢,⊢/)⍣2
Минимум расстояний до соседей, т.е. делайте дважды (( )⍣2
): добавьте крайний левый столбец (⊣/,
) к себе (⊢
) и добавьте крайний правый столбец (,⊢/
), найдите минимумы в горизонтальных тройках (3⌊/
) и транспонируйте (⍉
)⍵+
добавить значение каждого узла к его минимуму расстояний до соседей⊢⌊
попытаться превзойти текущие лучшие расстояния⊃⌽,
наконец, верните нижнюю правую ячейкуисточник