Это однозначно конкатенируемо?

10

В этой задаче о префиксном коде мы узнали, что префиксные коды уникально конкатенируемы.

Это означает, что они могут быть объединены без разделителя и без двусмысленности.

Например, поскольку [1,2,45] является префиксным кодом, я могу объединить их без разделителя как такового: 1245245112145, и двусмысленности не будет.

Однако обратное не всегда верно.

Например, [3,34] не является префиксным кодом. Однако я могу сделать то же самое: 3333434334333, и двусмысленности не будет. Вам просто нужен более умный парсер.

Однако [1,11] не является однозначно конкатенируемой, потому что 1111 можно интерпретировать 5 способами.

Цель

Ваша задача - написать программу / функцию, которая принимает список строк (ASCII) в качестве входных данных и определяет, являются ли они уникально конкатенируемыми.

подробности

Дубликат считается ложным.

счет

Это . Самое короткое решение в байтах побеждает.

Testcases

Правда:

[12,21,112]
[12,112,1112]
[3,4,35]
[2,3,352]

Ложь:

[1,1]
[1,2,112]
[1,23,4,12,34]
[1,2,35,4,123,58,8]
Дрянная Монахиня
источник
Просто чтобы убедиться, что я правильно понимаю задачу, она не является однозначно конкатенируемой, если одна из строк состоит из какой-либо комбинации других? Вы должны сделать эти детали более понятными.
Джеймс
Вы уверены, что это не эквивалентно проблеме остановки?
feersum
Можете ли вы продемонстрировать, почему это эквивалентно проблеме остановки?
Утренняя монахиня
Я не сказал, что это так, но подумал, что это может быть. После еще одной мысли я верю, что это не так.
feersum
@feersum Вот временный алгоритм для этой проблемы: en.wikipedia.org/wiki/Sardinas%E2%80%93Patterson_algorithm
isaacg

Ответы:

5

05AB1E , 15 байтов

По телефону, поэтому объяснение придется последовать позже. Код:

gF¹N>ã})€`€JDÚQ

Использует кодировку CP-1252 . Попробуйте онлайн! ,

Занимает слишком много памяти для последнего контрольного примера, чтобы он не работал ...

Аднан
источник
3
Это очень впечатляет, что вы можете напечатать это на своем телефоне.
Джеймс
3
@DrGreenEggsandHamDJ Это заняло около 40 минут ...
Аднан
2
@Adnan Интересно, что предиктор текста на клавиатуре телефона думает обо всех этих символах мусора :-)
Луис Мендо
1
@ LuisMendo Ха-ха, только однажды я отправил случайную программу 05AB1E другу.
Аднан
Я предполагаю, что это работает, устанавливая верхнюю границу длины кратчайшего столкновения. Я прав?
Питер Тейлор
4

CJam (54 байта)

q_N/:A\,{_Am*:${~1$,<=},{~\,>}%La:L-}*A,A_&,-A*](\M*&!

Принимает ввод в stdin как список, разделенный символом новой строки.

Онлайн демо

Если бы нам не приходилось обрабатывать дублирующиеся кодовые слова, это можно было бы сократить до 44:

q_N/\,{_W$m*:${~1$,<=},{~\,>}%La:L-}*](\M*&!

Или, если у CJam есть вычитание массива, которое удаляет только один элемент из первого списка для каждого элемента во втором, это может быть 48 ...

рассечение

Это алгоритм Сардинаса-Паттерсона, но не оптимизированный. Поскольку каждый свисающий суффикс встречается не более одного раза, выполнение основного цикла столько раз, сколько символов на входе (включая разделители) гарантирует достаточность.

Обратите внимание, что мне пришлось обойти то, что, возможно, является ошибкой в ​​интерпретаторе CJam:

"abc" "a" #   e# gives 0 as the index at which "a" is found
"abc" "d" #   e# gives -1 as the index at which "d" is found
"abc" ""  #   e# gives an error

Таким образом, проверка префикса сложна 1$,<=вместо\#!

e# Take input, split, loop once per char
q_N/\,{
  e# Build the suffixes corresponding to top-of-stack and bottom-of-stack
  _W$m*
  e# Map each pair of Cartesian product to the suffix if one is the prefix of the other;
  e# otherwise remove from the array
  :${~1$,<=},{~\,>}%
  e# Filter out empty suffixes iff it's the first time round the loop
  La:L-
}*
e# If we generated an empty suffix then we've also looped enough times to generate all
e# of the keywords as suffixes corresponding to the empty fix, so do a set intersection
e# to test this condition.
](\M*&!
Питер Тейлор
источник