Сценарий
После долгого рабочего дня, работающего в офисе и просматривающего stackexchange.com , я наконец вышел в дверь в 16:58, уже уставший от дня. Поскольку я все еще только стажер, мой текущий способ передвижения на велосипеде. Я направляюсь к своему верному Peugeot Reynolds 501 , но прежде чем я смогу отплыть, мне нужно его разблокировать. Замок представляет собой стандартный четырехзначный кодовый замок (0-9) через раму и переднее колесо. Стараясь бодрствовать, я поднимаю руку, чтобы войти в комбинацию.
Соревнование
Поскольку мои пальцы очень устали, я хочу повернуть замок в правильную комбинацию с наименьшим количеством движений. Одно движение определяется как вращение на одну позицию (36 градусов), например, есть одно движение от 5737
до 5738
. Тем не менее, я могу одновременно захватывать любые три последовательных кольца и вращать их как одно , что считается только одним движением. Например , существует также только одно движение от 5737
до 6837
или 5626
. Перемещение от 5737
к 6838
не является одним движением, поскольку цифры номер 1,2 и 4 двигались в том же направлении, но независимо от цифры номер 3.
Поэтому для данной комбинации я могу видеть на замке велосипеда (любое 4-значное целое число), какое наименьшее количество движений я могу сделать, чтобы разблокировать его, и да, я могу вращаться в любом направлении в любое время. Под этим я подразумеваю, что могу поворачивать некоторые цифры в одном направлении и другие цифры в другом направлении: не все мои движения будут против часовой стрелки или по часовой стрелке для каждой разблокировки.
Поскольку я ленивый, мой код разблокировки 0000.
Это кодовый гольф, я не могу не писать много кода, поэтому выигрывает самая короткая программа с количеством байтов.
Входные данные взяты из стандартного ввода, и ваш код должен выводить комбинации, которые я вижу на каждом шаге после каждого движения, включая 0000 в конце. Каждая из комбинаций должна быть отделена пробелом / новой строкой / запятой / точкой / амперсандом.
Примеры
Input: 1210
0100
0000
Input: 9871
9870
0980
0090
0000
Input: 5555
4445&3335&2225&1115&0005&0006&0007&0008&0009&0000
Input: 1234
0124 0013 0002 0001 0000
Я пытался опубликовать это на http://bicycles.stackexchange.com , но им это не понравилось ...
Отказ от ответственности: Первый гольф, так что все, что сломано / любая недостающая информация, дайте мне знать! Также я сделал все примеры вручную, поэтому могут быть решения, которые включают меньше движений!
РЕДАКТИРОВАТЬ: Для ответов, которые имеют несколько путей решения с равным количеством движений (практически все), не существует предпочтительного решения.
Ответы:
Matlab,
412327 байтИгра в гольф (спасибо @AndrasDeak за игру в гольф
s
!):Этот код использует некоторое динамическое программирование для нахождения кратчайшего «пути» из заданного числа и
0000
использования только возможных шагов. Задача - это, по сути, проблема кратчайшего пути (в качестве альтернативы вы, возможно, могли бы рассматривать этапы как коммутирующую группу), но проблема заключалась в эффективной реализации. Базовые структуры - это два массива по 10000 элементов, один для хранения количества шагов, чтобы добраться до этого индекса, другой для хранения указателя на предыдущий «узел» в нашем графе. Он одновременно вычисляет «пути» ко всем другим возможным числам.Примеры:
Полный код (включая некоторые комментарии):
источник
6444
ваш код дает 6444 7554 8664 9774 0884 0994 0004 0003 0002 0001 0000, тогда как я нахожу ответ 6444 6333 6222 6111 6000 7000 8000 9000 0000. Мой ответ - 8 шагов, ваш - 10. Я не вижу проблема, и это, кажется, там и в версии для гольфа и в не гольфе. Это исправлено в вашем последнем редактировании.s
последнем ряду должно быть[0,1,1,1]
. Тогда вы получите 8-шаговое решение тоже! Я извиняюсь за неудобства =)Пакет - 288 байт
Даже если вы сказали, что они должны быть последовательными (кольца), я предполагаю по логике (следуя примеру), что могу пропустить среднюю, начиная1234
с0224
.Это мое пакетное решение: 236 байт.Редактировать: исправленное решение
Новое решение (исправлено в соответствии с нижеследующими комментариями) имеет размер 288 байт.
источник
1234
к0224
является не одним движением. Идея состоит в том, что с помощью только двух пальцев я могу схватить до трех последовательных колец одной ручкой.Haskell - 310 байт
Это работает путем многократного построения нового списка комбинаций, применяя каждый возможный ход к каждой комбинации, которая уже достигнута, пока одна из них не станет правильной комбинацией. Дубликаты удаляются из списка на каждой итерации, чтобы не увеличивать объем использования памяти в геометрической прогрессии.
Как грубое решение проблемы, это очень неэффективно и может занять несколько минут.
У меня нет большого опыта работы с Haskell, так что, возможно, кое-что можно сделать лучше.
источник