Est-ce uniquement concaténable?

10

Dans ce défi sur le code préfixe , nous avons appris que les codes de préfixe sont uniquement concaténables.

Cela signifie qu'ils peuvent être réunis sans séparateur et sans ambiguïté.

Par exemple, puisque [1,2,45] est un code préfixe, je peux les joindre ensemble sans séparateur en tant que tel: 1245245112145, et il n'y aura aucune ambiguïté.

Cependant, l'inverse n'est pas toujours vrai.

Par exemple, [3,34] n'est pas un code de préfixe. Cependant, je peux faire la même chose: 3333434334333, et il n'y aura aucune ambiguïté. Vous auriez juste besoin d'un analyseur plus intelligent.

Cependant, [1,11] n'est pas uniquement concaténable, car 1111 peut être interprété de 5 manières.

Objectif

Votre tâche consiste à écrire un programme / une fonction qui prend en entrée une liste de chaînes (ASCII) et à déterminer si elles sont uniquement concaténables.

Détails

Le double compte comme faux.

Notation

C'est du . La solution la plus courte en octets gagne.

Cas de test

Vrai:

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

Faux:

[1,1]
[1,2,112]
[1,23,4,12,34]
[1,2,35,4,123,58,8]
Leaky Nun
la source
Juste pour m'assurer que je comprends bien le défi, il n'est pas uniquement concaténable si l'une des chaînes est composée d'une combinaison des autres? Vous devriez clarifier ces détails.
James
Êtes-vous sûr que ce n'est pas équivalent au problème d'arrêt?
feersum
Pouvez-vous démontrer pourquoi cela équivaut au problème d'arrêt?
Leaky Nun
Je n'ai pas dit que c'était le cas, mais je me demandais si ça pouvait l'être. Après réflexion, je crois que non.
feersum
@feersum Voici un algorithme de temps poly pour ce problème: en.wikipedia.org/wiki/Sardinas%E2%80%93Patterson_algorithm
isaacg

Réponses:

5

05AB1E , 15 octets

Au téléphone, l'explication devra suivre plus tard. Code:

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

Utilise l' encodage CP-1252 . Essayez-le en ligne! .

Prend trop de mémoire pour le dernier cas de test, donc cela pourrait ne pas fonctionner ...

Adnan
la source
3
Il est extrêmement impressionnant de pouvoir taper cela sur votre téléphone.
James
3
@DrGreenEggsandHamDJ Il a fallu environ 40 minutes ...
Adnan
2
@Adnan Je me demande ce que le prédicteur de texte du clavier de votre téléphone pense de tous ces symboles de poubelle :-)
Luis Mendo
1
@LuisMendo Haha, il n'est arrivé qu'une fois que j'ai envoyé un programme aléatoire 05AB1E à un ami.
Adnan
Je suppose que cela fonctionne en plaçant une limite supérieure sur la longueur de la collision la plus courte. Ai-je raison?
Peter Taylor
4

CJam (54 octets)

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

Prend l'entrée sur stdin en tant que liste séparée par des sauts de ligne.

Démo en ligne

Si nous n'avions pas à gérer les mots de code en double, cela pourrait être raccourci à 44:

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

Ou si CJam avait une soustraction de tableau qui ne supprimait qu'un seul élément de la première liste pour chaque élément de la seconde, ce pourrait être 48 ...

Dissection

Il s'agit de l' algorithme Sardinas-Patterson mais désoptimisé. Étant donné que chaque suffixe pendant ne s'affiche qu'une seule fois, l'exécution de la boucle principale autant de fois qu'il y a de caractères dans l'entrée (y compris les séparateurs) garantit qu'elle est suffisante.

Notez que j'ai dû contourner ce qui est sans doute un bogue dans l'interpréteur 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

La vérification du préfixe est donc compliquée au 1$,<=lieu 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
la source