Введение
У меня есть комната, полная волшебных зеркал . Это загадочные артефакты, которые могут дублировать любой предмет, кроме другого волшебного зеркала. Более точно, дублированная версия предмета появится на другой стороне зеркала, на том же расстоянии. Однако, если с обеих сторон на пути между дублирующим зеркалом и каким-либо предметом (оригиналом или дубликатом) находится другое волшебное зеркало, дубликат не формируется. Оригинальный предмет может быть слева или справа от зеркала, а дубликат появится на другой стороне. Кроме того, дубликат предмета может сам дублироваться другим зеркалом. Элементы никогда не блокируют дублирование других элементов (за исключением того, что они находятся непосредственно на позиции потенциального дубликата).
вход
Ваш ввод - это строка, состоящая из символов .#|
, которые представляют пустое пространство, предметы и магические зеркала. На входе всегда будет хотя бы одно волшебное зеркало.
Выход
В результате вы получите еще одну строку, в которой каждое волшебное зеркало дублирует каждый элемент, в соответствии с приведенными выше правилами. Вы можете предположить, что на месте, где появляется дубликат, всегда будет пустое место (чтобы они не выходили за пределы).
Примеры
Рассмотрим входную строку
.#.|.....|......#
A B C D
где мы отметили некоторые позиции для ясности. Зеркало B
дублирует элемент A
, который заканчивается справа от него:
.#.|.#...|......#
A B C D
C
Затем зеркало дублирует новый элемент:
.#.|.#...|...#..#
A B C D
Зеркало C
не может дублировать предмет A
, так как зеркало B
мешает. Он также не может дублировать элемент D
, так как зеркало B
находится на пути с другой стороны. Аналогично, зеркало B
не может дублировать элемент D
или дубликат рядом с ним, так как зеркало C
мешает, так что это правильный вывод.
Для другого примера рассмотрим ввод
.##..#...|#..##...|..##....#.
AB C DE FG H IJ K
Зеркало D
можно дублировать A
и B
вправо, E
и G
влево.
C
и F
уже дублируют друг друга. Строка становится
.##.##..#|#..##.##|..##....#.
AB C DE FG H IJ K
Зеркало H
может дублировать E
, F
и дубликаты A
и B
вправо, и I
влево.
G
и J
уже дублируют друг друга, а зеркало D
стоит на пути K
. Теперь у нас есть
.##.##..#|#..#####|#####..##.
AB C DE FG H IJ K
Наконец, зеркало D
может дублировать копию I
слева. Мы заканчиваем с
.#####..#|#..#####|#####..##.
AB C DE FG H IJ K
Правила и оценки
Вы можете написать либо полную программу, либо функцию. Побеждает самое низкое число байтов. Работы, в которых не используются движки регулярных выражений, конкурируют отдельно от тех, которые используют регулярные выражения, и могут быть помечены (без регулярных выражений) .
Контрольные примеры
"|" -> "|"
"..|.." -> "..|.."
".#.|..." -> ".#.|.#."
"..#|.#." -> ".##|##."
".#..|....|.." -> ".#..|..#.|.#"
".|..|.#....." -> "#|#.|.#....."
"...|.#...|....#" -> ".##|##...|...##"
"......#|......." -> "......#|#......"
".#.|.....|......#" -> ".#.|.#...|...#..#"
".......|...#.##|...." -> "##.#...|...#.##|##.#"
"...#..||.......#..#...#" -> "...#..||.......#..#...#"
".##|.#....||#||......#|.#" -> ".##|##....||#||.....##|##"
".##..#...|#..##...|..##....#." -> ".#####..#|#..#####|#####..##."
".#|...||...|#...|..##...|#...." -> ".#|#..||.##|##..|..##..#|#..##"
"....#.|...#.|..|.|.....|..#......" -> "..#.#.|.#.#.|.#|#|#.#..|..#.#...."
"..|....|.....#.|.....|...|.#.|..|.|...#......" -> ".#|#...|...#.#.|.#.#.|.#.|.#.|.#|#|#..#......"
Ответы:
Сетчатка , 50 байт
Попробуйте онлайн! (Первая строка включает набор тестов, разделенных переводом строки.)
Я думаю, что это противоположность (без регулярного выражения) представления.
объяснение
Это просто подстановка регулярного выражения, которая применяется повторно (
+
), пока строка не перестанет изменяться. Я использую балансировочные группы, чтобы убедиться, что две зеркальные позиции находятся на одинаковом расстоянии от данного зеркала (обратные ссылки не подойдут, поскольку точная строка с обеих сторон|
может отличаться).Это заменяется на,
#$2#
который просто заменяет и первый и последний символ матча с#
.источник
Perl, 49 байт
Полная благодарность @Martin Ender за того, кто предложил это регулярное выражение на 15 байт короче моего.
47 байт кода +
-pl
флагиЧтобы запустить это:
Части first (
([.#])
) и last ((?!\1)[^|]
) такие же, как в ответе Retina (см. Объяснение там).Средняя часть (
(\||[^|](?2)[^|])
) использует perl recursion ((?2)
) для сопоставления либо зеркала (\|
), либо (|
) с двумя не-зеркалами-символами ([^|]
), разделенными тем же шаблоном ((?2)
).Моя старая (и более уродливая) версия:
s/([.#])(([^|]*)\|(??{$3=~s%.%[^|]%gr}))(?!\1)[^|]/#$2#/&&redo
источник
Haskell (без регулярных выражений), 117 байт
источник
PHP,
123117100 байтПрограмма принимает аргумент командной строки, регулярное выражение взято из @Martin Ender / Dada. Беги с
-r
.источник
C 176 байт
Ungolfed
источник
'#'
и'.'
с35
и46
соответственно.x,i,j;void t(char*a){while(a[i]++)if(a[i]=='|'){for(j=x;a[j++]&&j<=i*2-x;j++){if((a[j]==35)&&(a[2*i-j]==46)){a[2*i-j]=35;i=-1;break;}if((i-j)&&(a[j]=='|'))break;}x=i+1;}}
- 170 байтJavaScript (ES6), 170 байт
Ungolfed:
источник