J, 28 символов
((C.!.2=_1^i.&0)&.".&.stdin''
Порядок ввода - основной ряд, строки читаются попеременно слева направо и справа налево по одному пути по всей таблице. Предполагается, что ноль принадлежит верхнему левому углу.
Использование в Windows:
<nul set /p="0 1 2 3 7 6 5 4 8 9 10 11 15 14 13 12" | jconsole c:\...\15.jhs
Объяснение:
<nul set /p=
используется для предотвращения перехода на новую строку во вводе, которая echo
выдает, что ".
не нравится. Конечно, Unix поддерживает echo /n
.
v&.".&.stdin''
читает «v под анализом под stdin», что означает «ввод, затем анализирует ввод, затем выполняет v, затем отменяет анализ (= формат), затем отменяет ввод (= вывод)». 1!:1]3
на один символ короче, но не имеет определенного обратного.
C.!.2
означает «четность перестановок». Он возвращает либо 1
(четный паритет), либо _1
(нечетный паритет). Это,_1^inversions
_1^i.&0
означает «-1 к степени индекса 0».
- таким образом,
C.!.2=_1^i.&0
означает «равенство перестановки равно четности положения дыры?»
Это работает для платы 4x4, но если желаемая конечная позиция является главной строкой слева направо, то перестановка для решаемой позиции имеет нечетное число инверсий и, следовательно, нечетную четность. Кроме того, четность меняется на противоположную (для любого входного порядка), когда желаемое положение отверстия перемещается сверху вниз слева направо. В обоих случаях исправление состоит из одного символа: добавьте -
после, =
чтобы изменить ожидаемый паритет.
Доказательство правильности:
После каждого хода ноль обменивает позицию с некоторым числом, переключая четность перестановки. Ноль также чередуется между белыми и черными позициями шахматной доски, обозначенными нечетными и четными позициями во входном порядке. Таким образом, это условие является необходимым. Это также достаточно для счетного аргумента: общеизвестно, что ровно половина позиций разрешима. Это условие отфильтровывает ровно половину возможных позиций.