È un prefisso?


33

Nella teoria dell'informazione, un "codice prefisso" è un dizionario in cui nessuna delle chiavi è un prefisso di un'altra. In altre parole, ciò significa che nessuna delle stringhe inizia con nessuna delle altre.

Ad esempio, {"9", "55"}è un prefisso, ma {"5", "9", "55"}non lo è.

Il più grande vantaggio di ciò è che il testo codificato può essere trascritto senza separatori tra loro, e sarà comunque unicamente decifrabile. Ciò si manifesta in algoritmi di compressione come la codifica Huffman , che genera sempre il prefisso ottimale.

Il tuo compito è semplice: dato un elenco di stringhe, determinare se si tratta o meno di un codice prefisso valido.

Il tuo input:

  • Sarà un elenco di stringhe in qualsiasi formato ragionevole .

  • Conterrà solo stringhe ASCII stampabili.

  • Non conterrà stringhe vuote.

Il tuo output sarà un valore di verità / falsità : verità se è un prefisso valido e falsa se non lo è.

Ecco alcuni veri casi di test:

["Hello", "World"]                      
["Code", "Golf", "Is", "Cool"]
["1", "2", "3", "4", "5"]
["This", "test", "case", "is", "true"]          

["111", "010", "000", "1101", "1010", "1000", "0111", "0010", "1011", 
 "0110", "11001", "00110", "10011", "11000", "00111", "10010"]

Ecco alcuni casi di test falsi:

["4", "42"]                             
["1", "2", "3", "34"]                   
["This", "test", "case", "is", "false", "t"]
["He", "said", "Hello"]
["0", "00", "00001"]
["Duplicate", "Duplicate", "Keys", "Keys"]

Si tratta di code-golf, quindi si applicano scappatoie standard e vince la risposta più breve in byte.


Vuoi un valore di verità coerente o potrebbe essere ad esempio "un numero intero positivo" (che può variare tra diversi input).
Martin Ender,


@DrGreenEggsandHamDJ Non credo che la risposta abbia lo scopo di affrontare la coerenza degli output, quindi la domanda. ;)
Martin Ender

Solo per curiosità: la sfida dice: "Il più grande vantaggio di questo, è che il testo codificato può essere scritto senza separatori tra loro, e sarà comunque unicamente decifrabile". In che modo qualcosa di simile 001sarebbe decifrabile in modo univoco? Potrebbe essere 00, 1o 0, 11.
Joba,

2
@Joba Dipende da quali sono le tue chiavi. Se hai 0, 00, 1, 11tutti come chiavi, questo non è un prefisso-codice perché 0 è un prefisso di 00 e 1 è un prefisso di 11. Un prefisso è dove nessuna delle chiavi inizia con un'altra chiave. Quindi, ad esempio, se le tue chiavi sono 0, 10, 11questo è un prefisso e univocabilmente decifrabile. 001non è un messaggio valido, ma 0011o 0010è unicamente decifrabile.
DJMcMayhem

Risposte:


11

Pyth, 8 byte

.AxM.PQ2

Suite di test

Prendi tutte e 2 le permutazioni degli elementi dell'input, mappale ognuna sull'indice di una stringa nell'altra (0 per un prefisso) e restituisci se tutti i risultati sono veritieri (diversi da zero).


12

Haskell, 37 byte

f l=[x|x<-l,y<-l,zip x x==zip x y]==l

Ogni elemento xdi lviene ripetuto una volta per ogni elemento di cui è un prefisso, che è esattamente una volta per un elenco privo di prefissi, fornendo l'elenco originale. La proprietà del prefisso viene controllata zippando entrambi gli elenchi con x, che taglia gli elementi oltre la lunghezza di x.


Questa è una soluzione elegante (+1)
Michael Klein,

9

Java, 128 127 126 125 124 121 byte

(Grazie @Kenny Lau, @Maltysen, @Patrick Roberts, @Joba)

Object a(String[]a){for(int i=0,j,l=a.length;i<l;i++)for(j=0;j<l;)if(i!=j&a[j++].startsWith(a[i]))return 1<0;return 1>0;}

Ungolfed

Object a(String[] a) {
    for (int i = 0, j, l = a.length; i < l; i++) 
        for (j = 0; j < l;) 
            if (i != j & a[j++].startsWith(a[i])) return 1<0;
    return 1>0;
}

Produzione

[Hello, World]
true

[Code, Golf, Is, Cool]
true

[1, 2, 3, 4, 5]
true

[This, test, case, is, true]
true

[111, 010, 000, 1101, 1010, 1000, 0111, 0010, 1011, 0110, 11001, 00110, 10011, 11000, 00111, 10010]
true

[4, 42]
false

[1, 2, 3, 34]
false

[This, test, case, is, false, t]
false

[He, said, Hello]
false

[0, 00, 00001]
false

[Duplicate, Duplicate, Keys, Keys]
false

1
idk su java, ma avrebbe &funzionato invece di &&?
Maltysen,

1
A destra, salva un altro byte. In Java, l'utilizzo di operatori bit a bit con operandi booleani si comporta esattamente come i normali operatori logici, tranne per il fatto che non presentano cortocircuiti che non sono necessari in questo caso.
Marv,

Non potresti semplicemente cambiare il tipo di ritorno della funzione in inte return 0e 1? Ciò consentirebbe di risparmiare diversi byte. Anche io ricordo se questo è valido in Java, ma se si dichiara i, je lall'interno del esterna forciclo che avrebbe salvato un byte da una virgola in meno.
Patrick Roberts,

@PatrickRoberts Maltysen lo ha suggerito prima, ma questo non è valido secondo la definizione più votata di verità / falsità . Mettere le dichiarazioni nel ciclo tuttavia è perfettamente valido e abbastanza ovvio ora che ci penso. Ecco cosa ottieni giocando a golf alle 4 del mattino: ^)
Marv,

3
@Joba Abbastanza sicuro che non sia valido poiché indexOf restituisce -1 quando la stringa non viene trovata; dovrebbe essere indexOf(a[i])==0nel qual caso non ci sono risparmi.
Pokechu22,

6

Python 2, 48 51 byte

lambda l:all(1/map(a.find,l).count(0)for a in l)

Per ogni elemento adi l, la funzione a.findtrova l'indice della prima occorrenza di anella stringa di input, fornendo -1un'assenza. Quindi, 0indica un prefisso. In un elenco privo di prefissi, la mappatura di questa funzione restituisce solo una sola 0per asé. La funzione verifica che questo sia il caso per tutti a.


51 byte:

lambda l:[a for a in l for b in l if b<=a<b+'~']==l

Sostituisci ~con un carattere con codice ASCII 128 o successivo.

Per ogni elemento ain l, è inclusa una copia per ogni elemento che ne sia un prefisso. Per un elenco privo di prefissi, l'unico elemento di questo tipo è esso astesso, quindi questo fornisce l'elenco originale.


4

CJam, 14 byte

q~$W%2ew::#0&!

Suite di test.

Spiegazione

q~   e# Read and evaluate input.
$    e# Sort strings. If a prefix exists it will end up directly in front 
     e# of a string which contains it.
W%   e# Reverse list.
2ew  e# Get all consecutive pairs of strings.
::#  e# For each pair, find the first occurrence of the second string in the first.
     e# If a prefix exists that will result in a 0, otherwise in something non-zero.
0&   e# Set intersection with 0, yielding [0] for falsy cases and [] for truthy ones.
!    e# Logical NOT.

4

JavaScript ES6, 65 43 40 byte

a=>!/(.*)\1/.test(''+a.sort().join``)
      ^            ^               ^ embedded NUL characters

La mia soluzione precedente, che gestiva array di stringhe di tutti i caratteri UTF-8:

a=>!/[^\\]("([^"]*\\")*[^\\])",\1/.test(JSON.stringify(a.sort()))

Sono stato in grado di evitarlo JSON.stringifypoiché la sfida specifica solo caratteri ASCII stampabili.

Test

f=a=>!/(\0.*)\1/.test('\0'+a.sort().join`\0`) // since stackexchange removes embedded NUL characters

O.textContent += 'OK: '+
[["Hello", "World"]                      
,["Code", "Golf", "Is", "Cool"]
,["1", "2", "3", "4", "5"]
,["This", "test", "case", "is", "true"]          
,["111", "010", "000", "1101", "1010", "1000", "0111", "0010", "1011", 
 "0110", "11001", "00110", "10011", "11000", "00111", "10010"]
].map(a=>f(a)) 

O.textContent += '\nKO: '+
[["4", "42"]                             
,["1", "2", "3", "34"]                   
,["This", "test", "case", "is", "false", "t"]
,["He", "said", "Hello"]
,["0", "00", "00001"]
,["Duplicate", "Duplicate", "Keys", "Keys"]
].map(a=>f(a))
<pre id=O></pre>


3

Haskell, 49 byte

g x=[1|z<-map((and.).zipWith(==))x<*>x,z]==(1<$x)

Questo ha un paio di parti:

-- Are two lists (or strings) equal for their first min(length_of_1,length_of_2) elements, i.e. is one the prefix of the other?
(and.).zipWith(==)

-- Check whether one element is the prefix of the other, for all pairs of elements (including equal pairs)
map((and.).zipWith(==))x<*>x

-- This is a list of 1's of length (number of elements that are the prefix of the other)
[1|z<-map((and.).zipWith(==))x<*>x,z]

-- This is the input list, with all the elements replaced with 1's
(1<$x)

Se le due liste sono uguali, un elemento è solo il prefisso di se stesso ed è valido.


3

Retina , 19 byte

Il conteggio dei byte presuppone la codifica ISO 8859-1.

O`.+
Mm1`^(.+)¶\1
0

L'ingresso deve essere separato dall'alimentazione di linea. L'output è 0per falsy e1 verità.

Provalo online!(Leggermente modificato per supportare più casi di test separati da spazi.)

Spiegazione

O`.+

Ordina le linee nell'input. Se esiste un prefisso, finirà direttamente davanti a una stringa che lo contiene.

Mm1`^(.+)¶\1

Prova ad abbinare ( M) una linea completa che si trova anche all'inizio della riga successiva. L' mattiva modalità multi tale che ^inizi linea corrispondenze e le 1assicura che contano solo al massimo un match così che l'uscita è 0o 1.

0

Per scambiare 0e 1nel risultato, contiamo il numero di 0s.


3

Java, 97 byte

Object a(String[]a){for(String t:a)for(String e:a)if(t!=e&t.startsWith(e))return 1<0;return 1>0;}

Utilizza la maggior parte dei trucchi trovati nella risposta di @ Marv , ma utilizza anche il ciclo foreach e l'uguaglianza di riferimento delle stringhe.

Unminified:

Object a(String[]a){
    for (String t : a)
        for (String e : a)
            if (t != e & t.startsWith(e))
                return 1<0;
    return 1>0;
}

Si noti che, come ho detto, questo utilizza l'uguaglianza di riferimento di stringa. Ciò significa che il codice può comportarsi in modo strano a causa dell'internazionale String . Il codice funziona quando si usano gli argomenti passati dalla riga di comando e anche quando si usa qualcosa di letto dalla riga di comando. Se si desidera codificare i valori da testare, tuttavia, è necessario chiamare manualmente il costruttore String per forzare il mancato interning:

System.out.println(a(new String[] {new String("Hello"), new String("World")}));
System.out.println(a(new String[] {new String("Code"), new String("Golf"), new String("Is"), new String("Cool")}));
System.out.println(a(new String[] {new String("1"), new String("2"), new String("3"), new String("4"), new String("5")}));
System.out.println(a(new String[] {new String("This"), new String("test"), new String("case"), new String("is"), new String("true")}));
System.out.println(a(new String[] {new String("111"), new String("010"), new String("000"), new String("1101"), new String("1010"), new String("1000"), new String("0111"), new String("0010"), new String("1011"), new String("0110"), new String("11001"), new String("00110"), new String("10011"), new String("11000"), new String("00111"), new String("10010")}));
System.out.println(a(new String[] {new String("4"), new String("42")}));
System.out.println(a(new String[] {new String("1"), new String("2"), new String("3"), new String("34")}));
System.out.println(a(new String[] {new String("This"), new String("test"), new String("case"), new String("is"), new String("false"), new String("t")}));
System.out.println(a(new String[] {new String("He"), new String("said"), new String("Hello")}));
System.out.println(a(new String[] {new String("0"), new String("00"), new String("00001")}));
System.out.println(a(new String[] {new String("Duplicate"), new String("Duplicate"), new String("Keys"), new String("Keys")}));

@Jo King Vedi la seconda metà della mia risposta; è un po 'complicato e dipende da come viene specificato l'input. Non mi ricordo in realtà la scrittura di questo, anche se
Pokechu22

3

PostgreSQL, 186 , 173 byte

WITH y AS(SELECT * FROM t,LATERAL unnest(c)WITH ORDINALITY s(z,r))
SELECT y.c,EVERY(u.z IS NULL)
FROM y LEFT JOIN y u ON y.i=u.i AND y.r<>u.r AND y.z LIKE u.z||'%' GROUP BY y.c

Produzione:

enter image description here

Nessuna demo live questa volta. http://sqlfiddle.com supporta solo 9.3 e per eseguire questa demo 9.4 è necessario.

Come funziona:

  1. Dividi array di stringhe con numero e denominalo y
  2. Prendi tutto y
  3. LEFT OUTER JOINalla stessa tabella derivata basata sullo stesso i(id), ma con diversooridinal che iniziano con il prefissoy.z LIKE u.z||'%'
  4. Raggruppa il risultato in base a c(array iniziale) e usa la EVERYfunzione di raggruppamento. Se ogni riga della seconda tabella IS NULLsignifica che non ci sono prefissi.

Inserisci se qualcuno è interessato:

CREATE TABLE t(i SERIAL,c text[]);

INSERT INTO t(c)
SELECT '{"Hello", "World"}'::text[]
UNION ALL SELECT  '{"Code", "Golf", "Is", "Cool"}'
UNION ALL SELECT  '{"1", "2", "3", "4", "5"}'
UNION ALL SELECT  '{"This", "test", "case", "is", "true"}'         
UNION ALL SELECT  '{"111", "010", "000", "1101", "1010", "1000", "0111", "0010", "1011","0110", "11001", "00110", "10011", "11000", "00111", "10010"}'
UNION ALL SELECT  '{"4", "42"}'
UNION ALL SELECT  '{"1", "2", "3", "34"}'                   
UNION ALL SELECT  '{"This", "test", "case", "is", "false", "t"}'
UNION ALL SELECT  '{"He", "said", "Hello"}'
UNION ALL SELECT  '{"0", "00", "00001"}'
UNION ALL SELECT  '{"Duplicate", "Duplicate", "Keys", "Keys"}';

MODIFICARE:

SQL Server 2016+ implementazione:

WITH y AS (SELECT *,z=value,r=ROW_NUMBER()OVER(ORDER BY 1/0) FROM #t CROSS APPLY STRING_SPLIT(c,','))
SELECT y.c, IIF(COUNT(u.z)>0,'F','T')
FROM y LEFT JOIN y u ON y.i=u.i AND y.r<>u.r AND y.z LIKE u.z+'%' 
GROUP BY y.c;

LiveDemo

Nota: è un elenco separato da virgole, non un array reale. Ma l'idea principale è la stessa di PostgreSQL.


MODIFICA 2:

In realtà WITH ORDINALITYpotrebbe essere sostituito:

WITH y AS(SELECT *,ROW_NUMBER()OVER()r FROM t,LATERAL unnest(c)z)
SELECT y.c,EVERY(u.z IS NULL)
FROM y LEFT JOIN y u ON y.i=u.i AND y.r<>u.r AND y.z LIKE u.z||'%' GROUP BY y.c

SqlFiddleDemo


3

Brachylog , 8 byte

¬(⊇pa₀ᵈ)

Provalo online!

Output attraverso successo / fallimento predicato. Richiede più di 60 secondi sull'ultimo caso di test veritiero, ["111","010","000","1101","1010","1000","0111","0010","1011","0110","11001","00110","10011","11000","00111","10010"] ma lo passa rapidamente con un byte aggiunto che elimina un gran numero di possibilità prima del programma ( Ċprima di controllare le permutazioni piuttosto che dopo aver verificato le permutazioni, per limitare la lunghezza dell'elenco secondario a Due).

¬(     )    It cannot be shown that
   p        a permutation of
  ⊇         a sublist of the input
      ᵈ     is a pair of values [A,B] such that
    a₀      A is a prefix of B.

Meno banale 9 byte varianti di ¬(⊇Ċpa₀ᵈ)cui esecuzione in tempi ragionevoli sono ¬(⊇o₁a₀ᵈ), ¬(⊇o↔a₀ᵈ)e ¬(⊇oa₀ᵈ¹).


Se questa sfida utilizzava "due valori distinti e coerenti" anziché "verità / falsità", ciò richiederebbe solo 5 byte.
Corda non correlata

2

Perl 6 , 24 byte

{.all.starts-with(.one)}

Provalo online!

Wow, sorprendentemente corto mentre si utilizza un lungo incorporato.

Spiegazione

{                      }  # Anonymous code block taking a list
 .all                     # Do all of the strings
     .starts-with(    )   # Start with
                  .one    # Only one other string (i.e. itself)

Ho scritto una risposta da 50 byte, ma la tua ha appena fatto esplodere la mia dall'acqua.
bb94,

1
@ bb94 Sì, ho iniziato con una risposta simile ma ho riscontrato lo stesso problema del tuo con set con chiavi duplicate che restituivano verità. Scrivere questa risposta è stato incredibilmente soddisfacente
Jo King il

1

Racchetta, 70 byte

(λ(l)(andmap(λ(e)(not(ormap(curryr string-prefix? e)(remv e l))))l))

1

Python, 58 55 byte

lambda l:sum(0==a.find(b)for a in l for b in l)==len(l)

a.index(b)==0è un po 'più corto. In alternativa, potresti farlo 0**sum(a.index(b)for a in l for b in l).
Mego

@Mego Non funziona perché indexgenera un'eccezione quando bnon viene trovata. E perché dovrebbe essere ==, no >=. Tuttavia, findfunziona. (Ed è anche più breve!)
DJMcMayhem

Spiacenti, intendevo scrivere find. Il cervello assonnato è assonnato. Anche la seconda versione dovrebbe funzionare find.
Mego

@Mego Non sono sicuro di ottenere la seconda versione. Non restituirebbe sempre 0?
DJMcMayhem

@Mego Funziona solo se ogni stringa è uguale. Il motivo per cui lo confrontiamo len(l)è dal momento che stiamo ripetendo tutte le bs su ciascuna a, ci sarà sempre almeno una corrispondenza per a. Quindi controlliamo se il numero di corrispondenze è uguale al numero di elementi.
DJMcMayhem

1

JavaScript (ES6), 52 54

Modifica 2 byte salvati grazie a @Neil

a=>!a.some((w,i)=>a.some((v,j)=>i-j&&!w.indexOf(v)))

Test

f=a=>!a.some((w,i)=>a.some((v,j)=>i-j&&!w.indexOf(v)))

O.textContent += 'OK: '+
[["Hello", "World"]                      
,["Code", "Golf", "Is", "Cool"]
,["1", "2", "3", "4", "5"]
,["This", "test", "case", "is", "true"]          
,["111", "010", "000", "1101", "1010", "1000", "0111", "0010", "1011", 
 "0110", "11001", "00110", "10011", "11000", "00111", "10010"]
].map(a=>f(a)) 

O.textContent += '\nKO: '+
[["4", "42"]                             
,["1", "2", "3", "34"]                   
,["This", "test", "case", "is", "false", "t"]
,["He", "said", "Hello"]
,["0", "00", "00001"]
,["Duplicate", "Duplicate", "Keys", "Keys"]
].map(a=>f(a))
<pre id=O></pre>


!w.indexOf(v)?
Neil,

@Neil giusto, grazie
edc65,

1

Mathematica 75 69 68 byte

Loquace come al solito. Ma Martin B è stato in grado di ridurre il codice di 7 byte.

Metodo 1: Memorizzazione dell'output in un Array

(68 byte)

f@a_:=!Or@@(Join@@Array[a~Drop~{#}~StringStartsQ~a[[#]]&,Length@a])

f@{"111", "010", "000", "1101", "1010", "1000", "0111", "0010", "1011", "0110", "11001", "00110", "10011", "11000", "00111", "10010"}

Vero


f@{"He", "said", "Hello"}

falso


Metodo 2: memorizzazione dell'output in a List

(69 byte)

f@a_:=!Or@@Flatten[a~Drop~{#}~StringStartsQ~a[[#]]&/@Range@Length@a]

Le regole di precedenza dovrebbero a~Drop~{#}~StringStartsQ~a[[#]]funzionare. ArrayDovresti anche salvare alcuni byte Length, soprattutto perché ti permetterà di usare Join@@invece di Flatten@(a condizione che tu stia usando Flattensolo per un singolo livello).
Martin Ender,

Grazie per il suggerimento Ci penserò Arraypiù tardi.
DavidC,

1

Mathematica, 41 byte

!Or@@StringStartsQ@@@Reverse@Sort@#~Subsets~{2}&

1

APL (Dyalog Unicode) , 13 byte SBCS

-2 byte:

≢=∘≢∘⍸∘.(⊃⍷)⍨

Provalo online!

Spiegazione:

≢=∘≢∘⍸∘.(⊃⍷)⍨   Monadic function train
               "Find": Convert the right argument into a boolean vector,
                where ones correspond to instances of the left argument
              Take the first item of the above vector (i.e., only prefixes)
     ∘.(  )⍨   Commutative outer product: take the above function and apply
               it for each possible pair of elements in the input
               If the input is a prefix code, the above should have a number of ones
               equal to the length of the input (i.e., each item is a prefix of only itself)
               To test this...
              Find the location of all ones in the above
   ≢∘          Take the length of the above
≢=∘            Compare to the length of the input

~2∊+\⊃¨∘.⍷⍨⎕­
ngn

1

J, 17 bytes

#=1#.1#.{.@E.&>/~

Try it online!

Note: I actually wrote this before looking at the APL answer, to approach it without bias. Turns out the approaches are almost identical, which is interesting. I guess this is the natural "array thinknig" solution

Take boxed input because the strings are of unequal length.

Create a self-function table /~ of each element paired with each element and see if there is a match at the start {.@E.. This will produce a matrix of 1-0 results.

Sum it twice 1#.1#. to get a single number representing "all ones in the matrix", and see if that number is the same as the length of the input #=. If it is, the only prefix matches are self matches, ie, we have a prefix code.

sorting solution, 18 bytes

0=1#.2{.@E.&>/\/:~

Attempt at different approach. This solution sorts and looks at adjacent pairs.

Try it online!


1

R, 48 bytes

function(s)sum(outer(s,s,startsWith))==length(s)

Try it online!

Explanation: outer(s,s,startsWith) outputs a matrix of logicals checking whether s[i] is a prefix of s[j]. If s is a prefix code, then there are exactly length(s) TRUE elements in the result, corresponding to the diagonal elements (s[i] is a prefix of itself).


1
I've found a bunch of other 48 byte alternatives, like function(s)all(colSums(outer(s,s,startsWith))<2) but it remains that startsWith is a function I didn't know about! Nice find.
Giuseppe

1
@Giuseppe I tried several ways of checking whether the matrix is an identity matrix, but couldn't get it under 48 bytes either. I thought this way was the easiest to understand, but I'm sure someone will golf it down!
Robin Ryder

47 bytes by inverting TRUE and FALSE...
Giuseppe

@Giuseppe Is that allowed? The rules explicitly ask for truthy when the input is a valid prefix code. (Also your link is to the 48 byte version, but I am guessing that your suggestion is to replace == with >. :-) )
Robin Ryder


0

Ruby, 48 bytes

Uses arguments as input and stdout as output.

p !$*.map{a,*b=$*.rotate!
a.start_with? *b}.any?

0

Scala, 71 bytes

(s:Seq[String])=>(for{x<-s;y<-s}yield x!=y&&x.startsWith(y)).forall(!_)

0

Racket 130 bytes

(define g #t)(for((n(length l)))(for((i(length l))#:unless(= i n))(when(string-prefix?(list-ref l i)(list-ref l n))(set! g #f))))g

Ungolfed:

(define(f l)
  (define g #t)
  (for ((n (length l)))
    (for ((i (length l)) #:unless (= i n))
      (when (string-prefix? (list-ref l i) (list-ref l n))
        (set! g #f))))g)

Testing:

(f [list "Hello" "World"])             
(f [list "Code" "Golf" "Is" "Cool"])
(f [list "1" "2" "3" "4" "5"])
(f [list "This" "test" "case" "is" "true"])          
(f [list "111" "010" "000" "1101" "1010" "1000" "0111" "0010" "1011" 
         "0110" "11001" "00110" "10011" "11000" "00111" "10010"])

(f [list "4" "42"])                             
(f [list "1" "2" "3" "34"])                   
(f [list "This" "test" "case" "is" "false" "t"])
(f [list "He" "said" "Hello"])
(f [list "0" "00" "00001"])
(f [list "Duplicate" "Duplicate" "Keys" "Keys"])

Output:

#t
#t
#t
#t
#t
#f
#f
#f
#f
#f
#f

0

C (gcc), 93 bytes

p(r,e,f,i,x)char**r;{for(f=i=0;i<e;++i)for(x=0;x<e;++x)f|=x!=i&&strstr(r[i],r[x])==r[i];r=f;}

Try it online!

Simple double for loop using strstr(a,b)==a to check for prefices. Mainly added since there doesn't seem to be a C answer yet.



0

05AB1E, 13 bytes

2.ÆDí«ε`Å?}O_

Too long.. Initially I had a 9-byte solution, but it failed for the duplicated key test case.

Try it online or verify all test cases.

Explanation:

2.Æ             # Get all combinations of two elements from the (implicit) input-list
   Dí           # Duplicate and reverse each pair
     «          # Merge the lists of pairs together
      ε         # Map each pair to:
       `        #  Push both strings to the stack
        Å?      #  And check if the first starts with the second
          }O    # After the map: sum to count all truthy values
            _   # And convert it to truthy if it's 0 or falsey if it's any other integer
                # (which is output implicitly as result)

0

Japt, 8 bytes

á2 ËrbÃe

Try it

á2 ËrbÃe     :Implicit input of array
á2           :Permutations of length 2
   Ë         :Map each pair
    r        :  Reduce by
     b       :  Get the index of the second in the first - 0 (falsey) if it's a prefix
      Ã      :End map
       e     :All truthy (-1 or >0)


0

Stax, 6 bytes

å·↑↑¶Ω

Run and debug it

This produces non-zero for truthy.

The general idea is to consider every pair of strings in the input. If the substring index of one in the other is ever zero, then it's not a valid prefix code. In stax, index of a non-existing substring yields -1. This way, all the pair-wise substring indices can be multiplied together.

This is the same algorithm as isaacg's pyth solution, but I developed it independently.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.