проблема
Представьте себе 7 ведер в ряд. Каждое ведро может содержать не более 2 яблок. Есть 13 яблок с маркировкой от 1 до 13. Они распределены между 7 ведрами. Например,
{5,4}, {8,10}, {2,9}, {13,3}, {11,7}, {6,0}, {12,1}
Где 0 представляет пустое пространство. Порядок, в котором яблоки появляются в каждом ведре, не имеет значения (например, {5,4} эквивалентно {4,5}).
Вы можете переместить любое яблоко из одного ведра в соседнее, при условии, что в контейнере назначения есть место для другого яблока. Каждый ход описывается номером яблока, которое вы хотите переместить (это однозначно, потому что есть только один пустой пробел). Например, применяя ход
7
к договоренности выше приведет к
{5,4}, {8,10}, {2,9}, {13,3}, {11,0}, {6,7}, {12,1}
Задача
Напишите программу, которая читает расположение из STDIN и сортирует его по следующему расположению
{1,2}, {3,4}, {5,6}, {7,8}, {9,10}, {11,12}, {13,0}
используя как можно меньше ходов. Опять же, порядок, в котором яблоки появляются в каждом ведре, не имеет значения. Порядок ведер имеет значение. Он должен выводить ходы, используемые для сортировки каждого расположения, разделенного запятыми. Например,
13, 7, 6, ...
Ваша оценка равна сумме количества ходов, необходимых для выполнения следующих мероприятий:
{8, 2}, {11, 13}, {3, 12}, {6, 10}, {4, 0}, {1, 7}, {9, 5}
{3, 1}, {6, 9}, {7, 8}, {2, 11}, {10, 5}, {13, 4}, {12, 0}
{0, 2}, {4, 13}, {1, 10}, {11, 6}, {7, 12}, {8, 5}, {9, 3}
{6, 9}, {2, 10}, {7, 4}, {1, 8}, {12, 0}, {5, 11}, {3, 13}
{4, 5}, {10, 3}, {6, 9}, {8, 13}, {0, 2}, {1, 7}, {12, 11}
{4, 2}, {10, 5}, {0, 7}, {9, 8}, {3, 13}, {1, 11}, {6, 12}
{9, 3}, {5, 4}, {0, 6}, {1, 7}, {12, 11}, {10, 2}, {8, 13}
{3, 4}, {10, 9}, {8, 12}, {2, 6}, {5, 1}, {11, 13}, {7, 0}
{10, 0}, {12, 2}, {3, 5}, {9, 11}, {1, 13}, {4, 8}, {7, 6}
{6, 1}, {3, 5}, {11, 12}, {2, 10}, {7, 4}, {13, 8}, {0, 9}
Да, у каждого из этих механизмов есть решение.
правила
- Ваше решение должно выполняться за полиномиальное время по количеству сегментов за ход. Дело в том, чтобы использовать умную эвристику.
- Все алгоритмы должны быть детерминированными.
- В случае ничьей побеждает самый короткий счетчик байтов.
источник
Ответы:
Счет: 448
Моя идея состоит в том, чтобы отсортировать их последовательно, начиная с 1. Это дает нам замечательное свойство: когда мы хотим переместить пространство в предыдущую / следующую корзину, мы точно знаем, какое из двух яблок нам нужно переместить - max / мин один соответственно. Вот тестовая разбивка:
Код может быть намного лучше, но лучшее качество кода будет мотивировать дополнительные ответы.
C ++ (501 байт)
Дальнейшие улучшения могут заключаться в переключении на C и попытке снизить оценку, начиная с больших значений вниз (и в конечном итоге они объединяют оба решения).
источник
С
426448Это сортирует яблоки по одному от 1 до 13, аналогично методу Ясена , за исключением тех случаев, когда у него есть возможность переместить большее число или меньшее число вниз, оно возьмет его.
К сожалению, это только улучшает производительность при первой проблеме теста, но это небольшое улучшение.Я допустил ошибку при запуске теста проблем. Кажется, я просто переопределил метод Ясена.Он принимает ввод без скобок или запятых, например
Вот код для игры в гольф, поступающий на 423 байта с подсчетом нескольких ненужных символов новой строки (возможно, может быть больше в гольфе, но я ожидаю, что этот счет будет побит):
И код ungolfed, который также печатает счет:
источник
Питон 3 - 121
Это реализует поиск в глубину с увеличением глубины, пока не найдет решение. Он использует словарь для хранения посещенных состояний, так что он не посещает их снова, если только у него нет окна большей глубины. Решая, какие состояния проверять, он использует количество неуместных элементов в качестве эвристики и посещает только лучшие возможные состояния. Обратите внимание, что поскольку порядок элементов в их сегменте не имеет значения, он всегда поддерживает порядок внутри блоков. Это облегчает проверку, если элемент находится не на своем месте.
Входные данные представляют собой массив целых чисел, причем первым int является количество сегментов.
Так, например, для № 8 (этот занимает очень много времени на моей машине, остальные заканчивают в секундах):
Вот результаты тестового набора: № 1: 12, № 2: 12, № 3: 12, № 4: 12, № 5: 11, № 6: 11, № 7: 10, № 8: 14, № 9: 13, # 10: 14
Вот код:
источник