Isso é concatenável de forma única?

10

Nesse desafio sobre o código de prefixo , aprendemos que os códigos de prefixo são concatenáveis ​​exclusivamente.

Isso significa que eles podem ser unidos sem separador e sem ambiguidade.

Por exemplo, como [1,2,45] é um código de prefixo, eu posso uni-los sem separador, como tal: 1245245112145, e não haverá ambiguidade.

No entanto, o inverso nem sempre é verdadeiro.

Por exemplo, [3,34] não é um código de prefixo. No entanto, posso fazer o mesmo: 3333434334333 e não haverá ambiguidade. Você precisaria apenas de um analisador mais inteligente.

No entanto, [1,11] não é concatenável de forma única, porque 1111 pode ser interpretado de 5 maneiras.

Objetivo

Sua tarefa é escrever um programa / função que use uma lista de seqüências de caracteres (ASCII) como entrada e determinar se elas são concatenáveis ​​exclusivamente.

Detalhes

Duplicar conta como falso.

Pontuação

Isso é . A solução mais curta em bytes vence.

Casos de teste

Verdade:

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

Falso:

[1,1]
[1,2,112]
[1,23,4,12,34]
[1,2,35,4,123,58,8]
Freira Furada
fonte
Apenas para ter certeza de que entendi o desafio corretamente, não é concatenável exclusivamente se uma das seqüências de caracteres for composta por alguma combinação das outras? Você deve deixar esses detalhes mais claros.
James
Tem certeza de que isso não equivale ao problema da parada?
feersum
Você pode demonstrar por que isso é equivalente ao problema da parada?
Freira Furada
Eu não disse que era, mas imaginei que poderia ser. Depois de pensar um pouco mais, acredito que não.
feersum
@feersum Aqui está um algoritmo de tempo poli para este problema: en.wikipedia.org/wiki/Sardinas%E2%80%93Patterson_algorithm
isaacg

Respostas:

5

05AB1E , 15 bytes

No telefone, a explicação terá que seguir mais tarde. Código:

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

Usa a codificação CP-1252 . Experimente online! .

Consome muita memória para o último caso de teste, portanto, isso pode não funcionar ...

Adnan
fonte
3
É extremamente impressionante que você possa digitar isso no seu telefone.
James
3
@DrGreenEggsandHamDJ Demorou cerca de 40 minutos ...
Adnan
2
@Adnan Eu me pergunto o preditor de texto do seu teclado do telefone pensa em tudo o que os símbolos de lixo :-)
Luis Mendo
11
@LuisMendo Haha, só aconteceu uma vez que enviei um programa 05AB1E aleatório para um amigo.
Adnan
Suponho que isso funcione colocando um limite superior no comprimento da colisão mais curta. Estou certo?
Peter Taylor
4

CJam (54 bytes)

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

Recebe entrada no stdin como lista separada por nova linha.

Demonstração online

Se não precisássemos lidar com palavras-chave duplicadas, isso poderia ser reduzido para 44:

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

Ou se CJam tivesse uma subtração de matriz que removesse apenas um item da primeira lista para cada item na segunda, poderia ser 48 ...

Dissecação

Este é o algoritmo Sardinas-Patterson mas des otimizado. Como cada sufixo dangling é exibido apenas no máximo uma vez, a execução do loop principal quantas vezes houver caracteres na entrada (incluindo separadores) garante ser suficiente.

Observe que eu tive que contornar o que é indiscutivelmente um bug no intérprete 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

Portanto, a verificação do prefixo é complicada em 1$,<=vez de\#!

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*&!
Peter Taylor
fonte