Дано 2 целочисленных ввода, представляющих размер поля, x
и y
выведите путь через поле.
Пример вывода для 5, 4
:
#
#
# ###
### #
Все поле 5 на 4, и есть путь, состоящий из хеш-меток, пересекающих поле.
Путь должен всегда начинаться в верхнем левом углу и идти внизу справа. Весь путь должен быть рандомизирован каждый раз при запуске программы. Каждый допустимый путь должен быть возможным выходом.
Правила для путей:
Сделано из hashmarks
Каждый хеш связан только с 2 другими хешами (т. Е. Путь не пересекается и не проходит рядом с самим собой)
Нехэш-пробелы могут быть заполнены любым другим символом, но он должен быть согласованным (т. Е. Все пробелы, все точки и т. Д.)
Примеры:
2, 2
##
#
3, 4
##
##
#
#
5, 5
#####
#
#
#
#
6, 5
## ###
# # #
## # #
# ## #
### #
7, 9
#######
#
#### #
# # #
# # #
# # #
# ####
#
#######
Этот тип пути похож на случайную прогулку, избегающую себя, однако он не может быть смежным с самим собой, в отличие от настоящего ПИЛА.
Непрерывность пути и касание пути определены без диагоналей.
Ответы:
MATLAB,
316 305 300293 байтаСпасибо @LuisMendo за различные предложения и кучу байтов =)
Попробуйте онлайн! (Без гарантии: обратите внимание, что для его запуска в Octave потребовалось несколько настроек: во-первых, мне нужно было удалить
function
ключевое слово и жестко закодировать значения, во-вторых: пробелы не выводятся правильно, как в Matlab. Также я этого не делал проверьте команды свертки Octave, которые могут действовать по-другому.)Пример вывода для ввода
(7,10)
(это может занять довольно много времени):объяснение
Это генерирует пути последовательно от верхнего левого до нижнего правого с желаемой 4-связностью, а затем использует выборку отклонения, чтобы отклонить пути, которые действительно нарушают критерий, что у вас не может быть прилегающих частей.
Ну и как всегда
источник
Befunge, 344 байта
Попробуйте онлайн!
Как упомянул @flawr в своем ответе на MATLAB, это может занять некоторое время, если размер поля любого нетривиального размера. На самом деле, довольно легко попасть в ситуацию, когда действительно не стоит пытаться дождаться его окончания, потому что вы, скорее всего, будете ждать до конца времени.
Чтобы понять, почему это происходит, полезно посмотреть, как выполняется программа, в одном из многочисленных «визуальных отладчиков» Befunge. Поскольку в Befunge данные и код - это одно и то же, вы увидите путь, который меняется с течением времени. Например, вот короткая анимация, показывающая, как может выглядеть часть бега по медленному пути.
Как только алгоритм решает совершить этот роковой поворот налево в нижней части границы поля, он по существу обрекает себя на целую жизнь бесцельного блуждания. С этого момента он должен пройти каждый возможный путь в этой огороженной области, прежде чем он сможет отступить и попытаться повернуть направо. И количество потенциальных путей в этих случаях может легко стать астрономическим.
Итог: если кажется, что это занимает много времени, возможно, хорошей идеей будет просто прервать выполнение и начать заново.
объяснение
Это в основном рекурсивный алгоритм, который пробует все возможные пути через поле, а затем раскручивает шаги, которые уже выполнялись, когда он застревал. Поскольку у Befunge нет понятия функций, о рекурсивной функции не может быть и речи, но мы можем эмулировать процесс, отслеживая состояние в стеке.
Это работает, заполняя стек потенциальными координатами, которым мы можем следовать. Затем мы извлекаем один набор из стека и проверяем, подходит ли он (то есть в диапазоне и не перекрывается ли существующий путь). Как только у нас будет подходящее место, мы записываем
#
в игровое поле в этом месте и добавляем эти детали в стек на случай, если нам понадобится вернуться позже.Затем мы помещаем дополнительные четыре набора координат в стек (в случайном порядке), указывая потенциальные пути, которые мы можем взять из этого нового местоположения, и возвращаемся к началу цикла. Если ни один из возможных путей не выполним, мы дойдем до той точки в стеке, где мы сохранили местоположение записанного
#
нами, поэтому мы отменим этот шаг и продолжим пробовать потенциальные координаты с одного предыдущего шага.Вот как выглядит код с выделенными различными компонентами:
Прочитайте ширину и высоту поля и нажмите начальные координаты вместе с
0
маркером типа, чтобы указать потенциальный путь, а не место возврата.Проверьте места обратного отслеживания (обозначенные
1
маркером типа), которые возвращаются с помощью простойp
команды, поскольку они хранятся в точном формате, необходимом для записи пробела обратно в игровое поле.Проверьте, находятся ли координаты внутри игрового поля. Если они находятся за пределами диапазона, отбросьте их из стека и вернитесь назад, чтобы попробовать следующие потенциальные координаты.
Если они находятся в диапазоне, получите следующие два значения из стека, который является местоположением предыдущего шага (требуется в следующем тесте).
Проверьте, вступят ли координаты в контакт с существующим сегментом пути. Местоположение предыдущего шага, очевидно, игнорируется этой проверкой.
Если все тесты пройдены успешно, напишите
#
в игровое поле и проверьте, достигли ли мы места назначения.Если у нас есть, запишите окончательный путь и выйдите.
В противном случае сохраните координаты в стек с
1
маркером типа для последующего возврата.Это прерывается вычислением случайного числа, которое нам скоро понадобится.
Нажмите четыре потенциальных места назначения, которые могут быть достигнуты из текущего местоположения. Случайное число определяет порядок, в котором они выдвигаются, и, следовательно, порядок их следования.
Вернитесь к началу основного цикла и обработайте следующие значения в стеке.
источник
QBasic, 259 байт
Я уверен, что люблю
GOTO
с.Основная стратегия: на каждом шаге выведите a
#
в текущее местоположение и двигайтесь в произвольном направлении. Массивa
0 и 1 отслеживает, где мы были. Если движение допустимо и приводит нас к конечной точке,GOTO 9
чтобы выйти из цикла и вывести финал#
. Иначе, если ход законен, сделайте еще один шаг. Иначе, очистите экран и начните все сначала (гораздо сложнее, чем кодировать алгоритм возврата!).Протестировано на моем ноутбуке в QB64, это обычно дает результат в течение
9, 9
пяти секунд или меньше. Пробеги10, 10
заняли где-то от трех до 45 секунд. Теоретически, все допустимые пути имеют ненулевую вероятность, но вероятность пути с большими кривыми исчезающе мала. Я иногда видел пути с одной или двумя маленькими кривыми, хотя:Необработанная версия и / или подробное объяснение доступны по запросу.
источник
R 225 байт
Объяснение:
Мы генерируем регулярный (решетчатый) [x * y] неориентированный граф со случайными весами на ребрах, затем находим кратчайший путь от начала до конца. Однако в сгенерированном пути могут быть ячейки, которые имеют более двух соседей, например:
Таким образом, мы должны применить алгоритм кратчайшего пути два раза. Во второй раз мы устанавливаем все веса в 1, кроме тех, которые находятся в текущем найденном пути, которые установлены в 0;
результат
Ungolfed:
источник
JavaScript (ES7),
333331330329324318312 байтРасширение:
#
s случайно помещаются в массив, пока путь не будет найден через поле с использованием поиска в ширину; первый и, следовательно, самый короткий, такой путь затем выводится; это гарантирует, что путь не пересекает себя. Обратите внимание, что, в частности, для больших полей возможно превышение стека механизма JS, прежде чем будет найден путь. Ungolfed:источник