Эта задача о преобразовании 2D лабиринтов в 1D лабиринты.
обзор
+-+-+-+-+-+-+ +-+-+-+-+-+-+ graph {
| | | | |A| | B| A B A -- D
+ + + + +-+-+ + + + + +-+-+ \ | C -- D
| | | | | | | | \ | D -- E
+-+-+ +-+-+ + +-+-+ +-+-+ + \ | E -- F
| | |C D E F| C---D-E---F E -- G
+-+-+-+ +-+ + +-+-+-+ +-+ + | | B -- F
| | | | G | | .---G | F -- J
+ +-+-+-+ + + + +-+-+-+ + + .' / | G -- H
| | | | |H|I |J| H I-' J G -- I
+-+-+-+-+-+-+ +-+-+-+-+-+-+ (ascii) } // (graphviz dot)
Figure 1 Figure 2 Figure 3
Для целей этой задачи традиционный 2D-лабиринт представляет собой прямоугольный лабиринт, образованный из точек решетки, где выполняется все следующее:
- Он закрыт (внешний обод соединен стенами).
- Все точки решетки связаны со стенами
- Это связано (для каждых двух пространств X и Y есть путь между ними)
- Это ациклично (нет пути из любого пространства X обратно в X без возврата)
На рисунке 1 показан традиционный 2D лабиринт. У этих лабиринтов есть три области интереса:
- Тупики - места, из которых есть только один доступный путь
- Коридоры - места, из которых есть два доступных пути
- Точки принятия решения - места, из которых есть три или четыре доступных пути
Для каждого такого лабиринта можно создать график, в котором тупики и точки принятия решений являются узлами, а между каждыми двумя узлами есть граница, соединенная путем вдоль коридора. На рисунке 2 показан тот же лабиринт с помеченными такими узлами, а на рисунке 3 - график лабиринта (в точечной записи ASCII и Graphviz).
1D лабиринты
1D лабиринты содержат точки перекоса, которые идут парами и идентифицируются с помощью буквы (в любом случае). На рисунке 4 показан пример 1D лабиринта. В остальном он идентичен двухмерному лабиринту с высотой 1, как показано на рисунке 5. Обратите внимание, в частности, на рисунке 5 позиции точки решетки, отмеченные +
, которые чередуются слева направо; в одномерном лабиринте любой другой символ, начинающийся с крайней левой стены, также является точкой решетки.
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| D| D E|G E F| F | G | | D| D E|G E F| F | G |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Figure 4 Figure 5
Правила навигации по этому лабиринту следующие. Каждое движение может быть представлено как вперед ( >
) или назад ( <
). Вперед и назад здесь по умолчанию имеют то же значение, что и наше интуитивное пространственное понимание; вперед переходит в положение сразу вправо, а назад сразу влево.
Точки деформации представляют местоположения, которые асимметрично меняют местность с соседями. Если вы идете от соседа к точке деформации, положение двух точек деформации меняется местами; если вы переходите от точки деформации к соседу, они не меняются местами. Например, на рисунке 6 перемещение назад от 1 приводит вас к 2 (поскольку 1 является соседом G, а мы переходим от соседа, точки 2 и @ меняются местами). Движение вперед от 2 (точка деформации G) приводит вас к 3 (здесь мы начинаем с точки деформации, поэтому нет свопа). Аналогично, переход назад от 3 приведет вас к @.
54 2367 89^ @1
| D| D E|G E F| F | G |
Y X
Figure 6
На рисунке 6 также показан пример навигации от X до Y с использованием последовательности ходов <<>><>>>>>
. Эти шаги приводят вас к точкам, помеченным 123456789^
соответственно, в указанном порядке. Не стесняйтесь исследовать его самостоятельно, используя фрагмент кода в следующем разделе.
Преобразование 2D в 1D
Используя одномерный лабиринт, можно создать график, где каждый узел является либо тупиком, либо парой точек деформации, и существуют ребра между любыми двумя узлами, соединенными вдоль коридора. Этот график позволяет сравнивать 1D и 2D лабиринты.
Например, 1D лабиринт на рисунке 4 - это тот же лабиринт на рисунке 1. Чтобы понять почему, рисунок 7 добавляет метки в тупики. Используя эти метки для построения графика, график на рисунке 7 снова просто рисунок 3. На рисунке 8 показан прорыв построения этого графика.
| D| D E|G E F| F | G |
A C B J H I
Figure 7
| D| D E|G E F| F | G |
+ + + + + + + + + + + + + + + <- lattice points
|A |C | |B J|H I| <- dead ends
|A D|C D E|G E F|B F J|H G I| <- all nodes (dead ends+warp points); i.e.:
"where each end is either a dead end
or a warp point pair"; note that each
pair of warp points is the same node.
|A-D|C-D-E|G-E-F|B-F-J|H-G-I| <- corridors; note each is a connection, since
1 2 3 4 5 6 7 8 9 "edges exist between any two nodes
connected along a corridor"
graph { graph {
A -- D // 1 <----> A -- D
C -- D // 2 <----> C -- D
D -- E // 3 <----> D -- E
G -- E // 4 <----> E -- G
E -- F // 5 <----> E -- F
B -- F // 6 <----> B -- F
F -- J // 7 <----> F -- J
H -- G // 8 <----> G -- H
G -- I // 9 <----> G -- I
} ^ }
Built from | From Figure 3
1D maze `-> isomorphic mappings
Figure 8
(Обратите внимание, что метки и расположение каждого графа были искусственно выбраны для выравнивания в целях иллюстрации; в общем, это проблема изоморфизма графа ).
Следующий фрагмент предоставлен, чтобы помочь визуализировать механику 1D-лабиринта и связь между 1D-лабиринтом, графиком эквивалентности и 2D-лабиринтом.
При перемещении по 1D-лабиринту в этом фрагменте последние два узла, к которым вы прикоснулись, подсвечиваются. Одинаковые узлы подсвечиваются одинаково на графике эквивалентности и в двумерном лабиринте.
В общем, для любого традиционного двухмерного лабиринта может быть создан эквивалентный одномерный лабиринт этого типа. Несколько более сложный пример - рисунок 9:
+-+-+-+-+-+-+ +-+-+-+-+-+-+ graph {
| | | | | |A| | |B| A B A -- D
+ + + + + + + + + + + + + + \ / C -- D
| | | | | | | | | | \ / D -- E
+-+-+ + +-+-+ +-+-+ + +-+-+ \ / B -- E
| | |C D E | C---D-E E -- F
+-+-+-+ +-+ + +-+-+-+ +-+ + |\ E -- I
| | | | F | | .---F \ F -- G
+ +-+-+-+ + + + +-+-+-+ + + .' / \ G -- H
| | | | |G|H |I| G H-' I H -- I
+-+-+-+-+-+-+ +-+-+-+-+-+-+ (ascii) } // (graphviz dot)
Figure 9 Figure 10 Figure 11
| D| D E |F E | F | | D| D E |F E | F |
A C I B G H
Figure 12 Figure 13
Этот лабиринт имеет узел с четырьмя путями (E на рисунке 10). Рисунок 11 показывает его график. Фиг.12 - эквивалентный 1D лабиринт; и на рисунке 13 показан тот же лабиринт с метками для тупиков, чтобы сравнить с рисунком 11.
Вызов
Используя 2D Лабиринт в качестве входных данных, напишите функцию или программу, которая преобразует 2D лабиринт в 1D лабиринт с точками деформации. Очки деформации могут использовать любую из 52 букв в каждом случае.
Гарантии ввода (если что-либо из этого не выполнено во вводе, вам не нужно иметь с этим дело):
- Входной лабиринт подключен (то есть вы всегда можете перейти из любой точки в любую другую).
- Входной лабиринт закрыт.
- Входной лабиринт прямоугольный.
- Все точки решетки используют
+
. - Все стены между точками решетки в одном ряду используют
|
- Все стены между точками решетки в одном и том же столбце используют
-
. - Все пространства являются частью пути (и все внутри лабиринта).
- Пути - это все пробелы (это всегда будет традиционным, не деформированным)
- Дорожки шириной ровно в одно пространство.
- Лабиринт построен путем соединения точек на решетке.
- В графе лабиринта не более 52 узлов (т. Е. Тупиков и точек принятия решений).
Выходной формат:
- Ваш вывод должен быть одной строкой, показывающей 1D лабиринт.
- Ваш вывод не должен иметь пробелов в начале / конце; за исключением того, что завершающий перевод новой строки в порядке.
- Первый символ и каждый последующий символ являются точками решетки.
- Все стены должны быть на точках решетки; и все точки перекоса между ними.
- График вашего 1D лабиринта должен быть эквивалентен графику 2D лабиринта.
- Ваши 1D лабиринты должны быть компактными; все точки без решетки должны быть тупиками (т.е. смежными со стенами) или точками деформации.
- В только буквы в вашем выводе должны быть точки основы. Каждая точка деформации происходит на линии ровно дважды.
Пример:
| D| D E|G E F| F | G | <- (1,2) The single line output
+ + + + + + + + + + + + + + + <- lattice point spacing... (3)
(4,6) lattice points are all walls or spaces
(5) See Figure 8
(7) D, E, F, G appear twice; no other labels
Это код-гольф. Победителем считается правильное представление без лазеек с наименьшим количеством байтов.
тестирование
Для этой задачи нет тестовых случаев, поскольку для любого нетривиального лабиринта имеется большое количество правильных выходных данных.
Однако я построил средство проверки в C ++ (оно проверяет оба решения посредством канонизации графа ).
Кроме того, вот несколько примеров, которые помогут проиллюстрировать правильное форматирование:
Пример 1
+-+-+-+-+-+-+
| | | |
+ + + + +-+-+
| | | |
+-+-+ +-+-+ +
| |
+-+-+-+ +-+ +
| | |
+ +-+-+-+ + +
| | | |
+-+-+-+-+-+-+
->
| D| D E|G E F| F | G |
Пример 2
+-+-+-+-+-+-+
| | | | |
+ + + + + + +
| | | | |
+-+-+ + +-+-+
| |
+-+-+-+ +-+ +
| | |
+ +-+-+-+ + +
| | | |
+-+-+-+-+-+-+
->
| D| D E |F E | F |