Создайте программу или функцию, чтобы размешать квадрат цифр, переворачивая (обращая вокруг центральной точки) только строки и столбцы.
вход
Ввод будет сетка цифр 9x9 в виде строки из 9 строк, как показано ниже:
986553229
264564891
759176443
643982153
567891234
526917874
685328912
891732537
117644378
Этот формат ввода не подлежит обсуждению - любые решения, которые являются «творческими» с форматом ввода, будут считаться недействительными.
Выход
Выходными данными должен быть список переворачиваемых движений, которые при применении к входным данным в заданном порядке должны воссоздавать целевую сетку.
Пример вывода (не решение предыдущего примера ввода):
28IF5D3EAB9G3
Этот формат вывода также не подлежит обсуждению. В выводе не должно быть символов новой строки или пробелов, только символы 1
- 9
и A
- I
(символы нижнего регистра допускаются вместо символов верхнего регистра, если вы предпочитаете).
Целевая сетка (состояние, которое вам нужно воссоздать) выглядит следующим образом:
123456789
234567891
345678912
456789123
567891234
678912345
789123456
891234567
912345678
Цифры 1
- 9
должны использоваться как инструкции для переворачивания строк, а буквы A
- I
должны использоваться для столбцов. Это показано ниже с сеткой в ее восстановленном состоянии.
ABCDEFGHI
|||||||||
vvvvvvvvv
1 -> 123456789
2 -> 234567891
3 -> 345678912
4 -> 456789123
5 -> 567891234
6 -> 678912345
7 -> 789123456
8 -> 891234567
9 -> 912345678
Таким образом, 8
средство переворачивает второй ряд снизу, а F
средство переворачивает шестой столбец.
В случае, если решение невозможно, программа должна завершиться, ничего не выводя вообще.
Примеры
Входные данные:
987654321
234567891
345678912
456789123
567891234
678912345
789123456
891234567
912345678
Выход:
1
В этом случае только верхний ряд необходимо перевернуть, чтобы вернуться к целевому состоянию.
Входные данные:
123456788
234567897
345678916
456789125
567891234
678912343
789123452
891234561
912345679
Выход:
I
В этом случае только последний столбец (столбец I
) нужно перевернуть, чтобы воссоздать состояние цели.
Входные данные:
123456788
798765432
345678916
456789125
567891234
678912343
789123452
891234561
912345679
Выход:
2I
В этом случае нам нужно перевернуть строку, 2
а затем перевернуть столбец, I
чтобы вернуться к целевому состоянию.
Заметки:
- Пожалуйста, включите пример использования в вашем ответе.
- Данный вывод не должен быть самой короткой последовательностью, которая будет возвращать состояние цели - любая последовательность, которая возвращает целевое состояние, будет работать до тех пор, пока она работает (т.е. до тех пор, пока я могу ее проверить)
- Я постараюсь проверить каждый ответ и оценить всех тех, кто работает и, очевидно, пытался играть в гольф.
- Это открытый конкурс - я приму кратчайший ответ где-то на следующей неделе, но если появится более новый действительный ответ, который будет короче в любой момент в будущем, я изменю принятый ответ, чтобы отразить это .
Награда была установлена на уровне 200 репутации за самый короткий ответ, полученный к 23:59:59 (GMT) 26/01/2014.Награда была присуждена Говарду за его решение GolfScript на 268 символов .
тестирование
Пожалуйста, укажите выходные данные вашей программы для следующих трех тестовых таблиц:
986553229
264564891
759176443
643982153
567891234
526917874
685328912
891732537
117644378
927354389
194762537
319673942
351982676
567891234
523719844
755128486
268534198
812546671
813654789
738762162
344871987
341989324
567891234
576217856
619623552
194435598
926543271
Я создал небольшую программу на Python, чтобы генерировать действительные сетки для тестирования:
import random
def output(array):
print '\n'.join([''.join(row) for row in array])
def fliprow(rownum, array):
return [row[::1-2*(rownum==idx)] for idx,row in enumerate(array)]
def flipcol(colnum, array):
return zip(*fliprow(colnum, zip(*array)))
def randomflip(array):
op=random.randint(0,1)
row=random.randint(0,9)
if(op==1):
return fliprow(row, array)
else:
return flipcol(row, array)
def jumble(array):
arraycopy=array
for i in range(10, 1000):
arraycopy=randomflip(arraycopy)
return arraycopy
startarray=[
['1','2','3','4','5','6','7','8','9'],
['2','3','4','5','6','7','8','9','1'],
['3','4','5','6','7','8','9','1','2'],
['4','5','6','7','8','9','1','2','3'],
['5','6','7','8','9','1','2','3','4'],
['6','7','8','9','1','2','3','4','5'],
['7','8','9','1','2','3','4','5','6'],
['8','9','1','2','3','4','5','6','7'],
['9','1','2','3','4','5','6','7','8']]
print output(jumble(startarray))
(-2, 4)
,(2, 4)
,(2, -4)
или(-2, -4)
.A1
) и переместить его вB1
. Вы можете получить1
позициюB1
, но это будет плиткаB9
, а не плиткаA1
. Поскольку нам разрешается только переворот строки / столбца, самый верхний левый 1 будет только в одном из четырех крайних углов. Если я ошибся правилами, пожалуйста, дайте мне знать.Ответы:
GolfScript,
300279268 символовОбратите внимание, что этот код очень медленный (также из-за тяжелых манипуляций с блоками кода) и может выполняться несколько минут. Код очень простой, с множеством переменных и явных циклов.
Я написал более аналитическое решение, которое длилось меньше секунды. Я полностью сломал тот во время игры в гольф. К сожалению, я не смог отследить или восстановить код за последние два дня. Поэтому я создал эту пробную версию, которая в любом случае короче.
Ответы на загадки приведены выше:
источник
Mathematica
582575503464282Для борьбы с гольфистами я должен использовать тяжелую артиллерию!
Выход:
Здесь
PermutationGroup[...]
настраивает возможные сальто иGroupElementToWord[...]
решает проблему (около0.2
сек). Основная проблема заключается в том, что трудно определить соответствие между положением9
в начальной и конечной сетке. Для игры в гольф я делаю это случайно (это занимает несколько секунд). Есть некоторые предупреждения, но их можно игнорировать.Другое для тестирования сетки:
Он полностью воспроизводит примеры:
Предыдущее решение (464)
без каких-либо умных встроенных функций и со временем выполнения 4 мс:
Все новые строки здесь не нужны.
Выход:
Другие две тестовые сетки:
Визуализация:
Входная строка
i
может быть сгенерирована случайным образомКраткое обсуждение
Сальто может взаимозаменять только эти элементы («четверка»):
Эти элементы можно взаимозаменять отдельно от других элементов, только если начальный и конечный порядок имеют одинаковую подпись.
Отражения этих четырех элементов образуют чередующуюся группу степени 4 (= группа вращений тетраэдра). Каждый элемент этой группы представляет собой композицию из 2 генерирующих элементов. Поэтому, если мы знаем начальную и конечную позицию, мы можем разложить соответствующее преобразование как комбинацию простых переворотов.
Детали
Для спортивного мастерства я опубликую детали до конца награды!
Преобразуйте строку
i
в матрицуM
.Мы будем добавлять символы к
S
. Теперь это пустая строка.H[i,j]
добавит символi
(1,2,3,...,9
) и символj
(a,b,c,...,i
в базе 36).Я конвертирую элементы как
получить целевую матрицу в следующем виде
Тогда есть два основных шага в моем алгоритме
Найдите сальто для получения подписей, как в целевой матрице (например, подпись
{-7,-1,1,7}
is1
и подпись{-6,2,-2,6}
is-1
):Вращайте каждую «четверку», чтобы получить правильный порядок:
Это самая нетривиальная часть алгоритма. Например, преобразование
1b1b
преобразуется{-7,-1,1,7}
в{-1,1,-7,7}
. Преобразование9h9h
будет преобразовано{-7,-1,1,7}
в{-7,7,-1,1}
. Итак, у нас есть две картыи мы хотим преобразовать произвольный порядок
{x,y,z,w}
в{1,2,3,4}
. Простой метод (кроме случайного поиска)Я не могу доказать это, но это работает!
Последний шаг
Он выполняет тривиальные перевороты центрального ряда и центрального столбца и возвращает результат.
источник
J
487438d
это глагол, который принимает строку сетки в указанном формате и возвращает строку решения в указанном формате.Пример использования:
Теперь принимает любой тип новой строки.
Решения для тестовых сеток:
Я довольно новичок в J; это может быть, возможно, еще дальше.
Проверка на наличие недействительных / неразрешимых сеток влечет за собой штраф в 123 символа. Я не думаю, что другие ответы на сегодняшний день имеют такую проверку ошибок.
Для этого измените первую строку
d
на это:и последняя строка к этому:
Я решил вернуться
0
к таким ошибкам, поскольку возвращение пустой строки было бы неотличимо от правильного решения полностью решенной сетки. Обратите внимание, что это предполагает новые строки UNIX (снова).источник
LF
s представляют разделы из последовательного файла.C #
540399Что ж, пожертвовали производительностью (теперь это занимает до 30 секунд), ввели динамические переменные, слегка изменили логику решения. И да, теперь он ожидает ввода в виде одной строки с переносами строк (как требуется в правилах).
Конечно, в C # нет предопределенных математических функций, поэтому было бы трудно бороться с ребятами из Mathematica. Тем не менее, это был большой вызов, спасибо автору!
Тестовые сетки:
Старое решение (540)
Работает менее чем за секунду на любом входе (проверено на тысячах случайно сгенерированных сеток). Максимальная длина выходной строки составляет 165 (изначально любая сетка решалась не более чем за 82 сальто, но во время игры в гольф я пожертвовал этим).
Ответ для примера 1:
Ответ для примера 2:
Ответ для примера 3:
Ответы на тестовые квадраты:
источник
1
,A
и2I
которые являются наиболее простыми решениями - но это на самом деле не важно , так как я не сужу по длине сеточного решения :-) Если бы вы могли изменить и дать ответы для 3 тестовых таблиц (я собираюсь проверить, смогу ли я запустить это на моем Mac сейчас), я могу дать вам +1.