Trova tutti i prefissi non ambigui di un set di stringhe


12

Per questa sfida, è necessario implementare il Abbrevmodulo di Ruby nel minor numero di codice possibile.

Sfida

  • L'input sarà qualunque sia la tua lingua come array (array, elenco, sequenza, ecc.) Di stringhe. È possibile scrivere una funzione o accettare parole separate da virgola su STDIN.

  • È quindi necessario calcolare l'insieme di prefissi non ambigui per tali stringhe. Ciò significa che devi restituire un hash (o mappa, oggetto, ecc.) Di abbreviazioni alle loro stringhe originali.

    • Un "prefisso" è una sottostringa della stringa originale che inizia all'inizio della stringa. Ad esempio, "pref" è un prefisso della parola "prefisso".

    • Un prefisso inequivocabile è un prefisso che può significare solo una parola. Ad esempio, se il tuo input è car,cat, allora canon è un prefisso inequivocabile perché potrebbe significare "auto" o "gatto".

    • L'eccezione a questa regola è che una parola è sempre un prefisso di se stessa. Ad esempio, se si dispone di input come car,carpet, car:cardeve essere nell'output.

  • È quindi possibile restituire l'hash / map / object / etc. dalla tua funzione (o esegui l'equivalente nella tua lingua) o stampalo su STDOUT in key:valuecoppia sotto forma di f:foo,fo:foo,.... (Le coppie chiave-valore possono anche essere separate da spazi bianchi se abbrevia il codice.)

Casi test

Input  code,golf,going
Output c:code,co:code,cod:code,code:code,gol:golf,golf:golf,goi:going,goin:going,going:going

Input  pie
Output p:pie,pi:pie,pie:pie

Input  pie,pier,pierre
Output pie:pie,pier:pier,pierr:pierre,pierre:pierre

Input  a,dog
Output a:a,d:dog,do:dog,dog:dog

Regole

  • L'input non conterrà elementi duplicati.

  • Il tuo output potrebbe essere in qualsiasi ordine; non devi ordinarlo.

  • Non puoi usare un Abbrevmodulo / funzione / cosa incorporato come Ruby.

  • Questo è , quindi vincerà il codice più breve in byte!


Lo stdout deve essere esattamente quel formato? O posso fare key:value\nkey:value\nkey:value...?
undergroundmonorail,

4
Invece di ridefinire l' abbreviazione della parola, potresti semplicemente usare il prefisso con il suo significato standard. E penso che inequivocabile trasmetta la proprietà desiderata dei tasti più efficacemente di univoca , per la quale la mia prima intuizione è stata che volevi un solo prefisso per parola di input.
Peter Taylor,

@PeterTaylor Buona idea; modificato.
Maniglia della porta

1
È possibile stampare più volte la stessa chiave (con lo stesso valore)?
xnor

Risposte:


1

APL (46)

(Sì, il set di caratteri APL si adatta a un byte, con spazio libero).

{↑{∆/⍨2=⍴∆←(⊂⍵),∆/⍨⊃¨⍵∘⍷¨∆}¨∪⊃,/{↑∘⍵¨⍳⍴⍵}¨∆←⍵}

Questa è una funzione che accetta un elenco di stringhe e restituisce una matrice 2 per N, in cui ogni riga contiene un prefisso non ambiguo e la parola a cui appartiene:

{↑{∆/⍨2=⍴∆←(⊂⍵),∆/⍨⊃¨⍵∘⍷¨∆}¨∪⊃,/{↑∘⍵¨⍳⍴⍵}¨∆←⍵}'code' 'golf' 'going'
 c      code  
 co     code  
 cod    code  
 code   code   
 gol    golf  
 golf   golf  
 goi    going 
 goin   going 
 going  going 

Spiegazione:

  • ∆←⍵: memorizza l'argomento giusto in .
  • {↑∘⍵¨⍳⍴⍵}¨∆: per ogni elemento di , ottieni i possibili prefissi di quell'elemento:
    • ⍳⍴⍵: ottenere un elenco dalla 1lunghezza di
    • ↑∘⍵¨: per ciascuno di quei numeri, ottieni tanti elementi da .
  • ∪⊃,/: concatena le liste insieme e accetta i valori univoci.
  • {... : per ciascuno dei prefissi univoci:
    • ∆/⍨⊃¨⍵∘⍷¨∆: seleziona le parole che iniziano con quel prefisso
    • (⊂⍵),: racchiude anche il prefisso e concatena
    • ∆/⍨2=⍴∆←: restituisce l'elenco solo se ci sono due elementi (il prefisso e una parola corrispondente)
  • : trasforma l'elenco delle tuple in una matrice

Il link non funziona adesso ...
user202729

3

Python 2.7 - 146 141 byte

l=raw_input().split(',')
for w in l:
 for a in range(len(w)):
    e=w[:a+1]
    if e==w or len(filter(lambda b:b.startswith(e),l))==1:print e+':'+w

Si noti che il rientro sulle righe 4 e 5 non è di 4 spazi, questo è un effetto collaterale dell'interprete markdown di SE. È un carattere di tabulazione letterale, quindi solo un byte.

Questo non è tecnicamente all'altezza delle specifiche, ma lo cambierò se Doorknob chiarisce. Usa newline invece di virgole per separare l'output. Per esempio:

$ python2 abbreviations.py <<< code,golf,golfing
c:code
co:code
cod:code
code:code
golf:golf
golfi:golfing
golfin:golfing
golfing:golfing

Novità: sono stato in grado di eliminare 5 caratteri assegnando la stringa che sto controllando a una variabile e. Ciò significa che devo solo digitare eanziché w[:a]tre volte. Significa anche che salvo i personaggi facendo e=w[:a+1]e cambiando ...range(1,len(w)+1)in range(len(w)).


Spiegazione:

l=raw_input().split(',') # Gets a line of input from stdin and splits it at every ',' to make a list
for w in l: # For each word in that list...

 for a in range(1,len(w)+1): # For each number a from 1 to the length of that word...

    if (w[:a]==w # w[:a] gets the string w up to the ath index. For example, 'aeiou'[:3] == 'aei'.
                 # We're testing every possible w[:a] to see if it's a unique abbreviation.
                 # However, a word is always its own abbreviation, so we hardcode that in by testing
                 # if w[:a] is the same as w.

or len(filter( # filter takes a function and an iterable as an argument, and returns a list of every
               # element of that iterable where that_function(that_element) returns a True-y value

lambda b:b.startswith(w[:a]),l) # We define an anonymous function that returns True for any string
                                # that begins with our current w[:a]. We filter for words that return
                                # True.

)==1): # If exactly one word returns True for this, it's a unique abbreviation!

     print w[:a]+':'+w # Print the abbreviation, a colon, and the full word.

È possibile utilizzare sum(b.startswith(e) for b in l)invece dilen(filter(lambda b:b.startswith(e),l))
Niklas B.

È inoltre possibile ridurre b.startswith(e)al b.find(e)==0o b[:a+1]==e, e verificare <2sul conteggio al posto di ==1.
xnor

Fai anche e=""\n for a in w:\n\te+=ainvece di for a in range(len(w)):\n\te=w[:a+1]come salva 10 caratteri
WorldSEnder

Ho realizzato una versione non consolidata qui per chiunque ne abbia bisogno gist.github.com/stuaxo/c371b2d410191a575b763b74719856c8
Stuart Axon

3

J - 47 caratteri

(,.~~.@,~[:(#~1-1({.\e."_1]\.){."1)@;(<\,.<)&.>)

J vede le stringhe come solo vettori di caratteri, il che significa che quando cerca di creare un elenco di stringhe finisce per creare una tabella di caratteri, quindi le estremità vengono riempite di spazi. La soluzione di J a questo si chiama box , quindi questa funzione prende come argomento un elenco di stringhe in box, in modo da preservare la lunghezza.

   'code';'golf';'going'
+----+----+-----+
|code|golf|going|
+----+----+-----+

Inoltre, a J manca un tipo di hash, quindi il più vicino a ciò è una tabella di elementi a due colonne, ad esempio stringhe in scatola. Se ciò è inaccettabile e devo impostare automaticamente il modulo valore-chiave, posso riformattare l'output in questo modulo con un totale di 67 caratteri :

;@|.@,@((<&>',:'),."1,.~~.@,[:(#~1-1({.\e."_1]\.){:"1)@;(<,.<\)&.>)

Spiegazione per esplosione:

(,.~~.@,[:(#~1-1({.\e."_1]\.){."1)@;(<\,.<)&.>) NB. unambiguous prefixes
                                    (     )&.>  NB. for each string:
                                     <\         NB.   take all prefixes
                                       ,.<      NB.   pair each with string
        [:                         ;            NB. gather up "partial" hashes
          (#~1-                  )@             NB. remove those rows where:
               1({.\        ){."1               NB.   each key
                    e."_1                       NB.   is an element of
               1(        ]\.){."1               NB.   the rest of the keys
 ,.~                                            NB. hash each word to itself
       ,                                        NB. add these rows to hash
    ~.@                                         NB. remove duplicate rows

Esempi:

   (,.~~.@,[:(#~1-1({.\e."_1]\.){."1)@;(<\,.<)&.>) 'pie';'pier';'pierre'
+------+------+
|pie   |pie   |
+------+------+
|pier  |pier  |
+------+------+
|pierre|pierre|
+------+------+
|pierr |pierre|
+------+------+
   NB. 1-char words have to be made into lists with ,
   (,.~~.@,[:(#~1-1({.\e."_1]\.){."1)@;(<\,.<)&.>) (,'a');'dog'
+---+---+
|a  |a  |
+---+---+
|dog|dog|
+---+---+
|d  |dog|
+---+---+
|do |dog|
+---+---+
   NB. "key:value," format, reversed order to save chars
   ;@|.@,@((<&>',:'),."1,.~~.@,[:(#~1-1({.\e."_1]\.){:"1)@;(<,.<\)&.>) 'code';'golf';'going'
goin:going,goi:going,gol:golf,cod:code,co:code,c:code,going:going,golf:golf,code:code,

2

Haskell 96 87

import Data.List
i=inits
f a=a>>= \x->[(y,x)|y<-i x,y/="",y`notElem`(a>>=i)\\i x||y==x]

Versione non golfata:

 import Data.List
 f a = concatMap (\x ->
     [(y, x) |
      y <- inits x,
      y /= "",
      y `notElem` concatMap inits a \\ inits x || y == x]
     ) a

Esempio:

> f ["pi","pier","pierre"]
[("pi","pi"),("pier","pier"),("pierr","pierre"),("pierre","pierre")]

Ho usato la initsfunzione, che trova tutti i prefissi di un elenco / stringa. Conta come barare?


1
Puoi sostituirlo concatMapcon (=<<), che si trova nel Preludio. Ti salva 10 caratteri.
Rhymoid,

@Rhymoid Grazie. Ho rimosso concatMapma non riesco a salvare più di 9 caratteri.
Lortabac,

Oh aspetta, hai ragione; Haskell considera >>=\ come un singolo lessema. Scusami per questo ...
Rhymoid,

2

Python 3 (97)

c=','
S=c+input()
for w in S.split(c):
 e=w
 while e:e<w<w*S.count(c+e)or print(e+':'+w);e=e[:-1]

Esaminiamo i prefissi di ogni parola nell'input, stampando la corrispondente coppia prefisso / parola se appare esattamente una volta o è su una parola intera. Approfittiamo del comportamento in cortocircuito di or(ed printessendo una funzione) per stampare solo se una di queste condizioni è soddisfatta.

Il whileciclo interrompe ripetutamente l'ultimo carattere per creare prefissi sempre più corti, terminando quando rimane la stringa vuota. Questa è l'unica volta che indicizziamo o suddividiamo qualcosa.

Si contano le occorrenze del prefisso enell'input ricercando la stringa di input separata da virgole originale Sper sottostringhe ','+e. Anticipiamo una virgola alla stringa di input beaforehand. Questa aggiunta provoca un elemento stringa extra vuoto quando noi split, ma questo non ha alcun effetto perché non ha sottostringhe non vuote.

Per verificare il caso in cui la sottostringa eè l'intera parola w, li confrontiamo usando l'operatore di confronto delle stringhe. Questo confronta lessicograficamente, quindi i prefissi più brevi sono più piccoli. Il doppio confronto fallisce se uno e==wo S.count(c+e)<2.

Se e,wfosse consentito stampare output nel modulo , salverei un personaggio scrivendo e+c+w.

Ringraziamo undergroundmonorail dalla cui risposta ho basato la mia struttura di codice generale.


(e<w)*S.count(c+e)>1può essere giocato a golf e<w<w*S.count(c+e)per salvare 2 personaggi.
isaacg,

@isaacg Grazie! Ho aggiunto la tua ottimizzazione.
xnor

1

Ruby, 114

def f(l);h={};l.each{|w|w.size.times{|i|k=w[0..i];h[k]=h[k]&&0||w}};h.delete_if{|k,v|v==0};l.each{|w|h[w]=w};h end

Ungolfed:

def f(list)
  hash = {}
  list.each do |word|
    word.size.times do |i|
      key = word[0..i]
      h[key] = (hash[key] && 0) || word
    end
  end
  hash.delete_if{|key, value| v==0}
  list.each{|word| hash[word] = word}
  hash 
end

1

k4 (70)

non particolarmente golf; sono sicuro che potrebbe essere più breve

abbastanza simile al J impl. sopra, penso - fondamentalmente raccoglie solo tutti i (propri) prefissi, rimuove di nuovo le parole dai prefissi (per gestire il "car"/ "carpet"case), le raggruppa in classi di equivalenza, seleziona le classi con un solo elemento, le riduce dalle liste a stringhe e aggiunge nella mappa da stringhe a se stessi.

f:{(x!x),*:'{(&1=#:'x)#x}{x@=y@:&~y in x}.,/'+{1_'(c#,x;(!c:#x)#\:x)}'x}

alcuni casi di test

notare che in k/ q, una stringa è un elenco di caratteri, quindi una stringa contenente solo un singolo carattere deve essere contrassegnata come tale usando la ,funzione unaria ; & mmwrt un elenco di stringhe che contiene solo una singola stringa

queste usano qla showfunzione, che ha una formattazione integrata per alcune strutture di dati, per rendere più leggibili i risultati:

  .q.show f("code";"golf";"going")
"code" | "code"
"golf" | "golf"
"going"| "going"
,"c"   | "code"
"co"   | "code"
"cod"  | "code"
"gol"  | "golf"
"goi"  | "going"
"goin" | "going"
  .q.show f@,"pie"
"pie"| "pie"
,"p" | "pie"
"pi" | "pie"
  .q.show f("pie";"pier";"pierre")
"pie"   | "pie"
"pier"  | "pier"
"pierre"| "pierre"
"pierr" | "pierre"
  .q.show f(,"a";"dog")
,"a" | ,"a"
"dog"| "dog"
,"d" | "dog"
"do" | "dog"
  .q.show f("car";"carpet")
"car"   | "car"
"carpet"| "carpet"
"carp"  | "carpet"
"carpe" | "carpet"

1

JavaScript - 212

w=prompt(o=[]).split(",");w.map(function(k,l){for(i=0;++i<k.length;){p=k.slice(0,i);if(w.filter(function(r,t){return t!=l}).every(function(r){return r.indexOf(p)}))o.push(p+":"+k)}o.push(k+":"+k)});console.log(o)

Golf iniziale.

Ingresso:

code,golf,going

Produzione:

["c:code", "co:code", "cod:code", "code:code", "gol:golf", "golf:golf", "goi:going", "goin:going", "going:going"]


1

Perl, 93 77

Con newline e rientro per la leggibilità:

sub f{
    (map{
        $h{$x}=[($x=$`.$&,$_)x!$h{$x}]while/./g;
        $_,$_
    }@_),map@$_,values%h
}

Un po 'troppo tardi e troppo lungo, ma sono contento che sia finalmente arrivato sotto 100. La funzione restituisce un elenco che può essere assegnato alla variabile hash:

%h = f(qw/code golf going pie pier pierre/);
print "$_ $h{$_}\n" for sort keys %h;

e

perl prefix.pl
c code
co code
cod code
code code
goi going
goin going
going going
gol golf
golf golf
pie pie
pier pier
pierr pierre
pierre pierre

In realtà, l'elenco restituito non è ancora filtrato - la costruzione dell'hash è completata al momento della sua assegnazione, ovvero funzione esterna. Se non è abbastanza pulito / equo, aggiungi 3 per contare e metti il ​​contenuto della funzione tra parentesi graffe, anteponendo +- quindi la funzione restituisce un riferimento hash 'vero'.


1

Q: 44 byte

{x!p@'(?0,&:)'p in\:&1=#:'=,/p:`$(-1_)\'$x}

APPUNTI

  • Il linguaggio Q ha un nucleo interno chiamato internamente K4 (usato in questa risposta e in un'altra risposta precedentemente a questa domanda)

  • Per testare il codice, scarica l'interprete (kx.com, gratuito per uso non commerciale, supporto per Windows, Linux, Mac)

L'interprete ammette due sintassi:

  • dettagliato (nomi più leggibili, nomi distinti per moands e diad, più librerie, ...). Carica il file di origine con estensione q o interprete interattivo

  • compatto (nucleo interno funzionale, operatori di una lettera, stessa lettera per entrambi usa monade / diad, ...). Carica il file di origine con estensione k o l'interprete interattivo in modalità k (scrivi \ al prompt). Il codice deve essere testato in questa modalità

Il codice definisce un lambda (funzione anonima). Per dare il nome alla funzione abbiamo bisogno del nome del prefisso: (ex f: {..}), quindi richiede 46 byte

TEST

(assumendo la funzione nominata: altrimenti sostituisci f con il codice)

f `code`golf`going

`code`golf`going!(`code`cod`co`c;`golf`gol;`going`goin`goi)

restituisce un dizionario (chiavi di sintassi! valori). Le chiavi sono un elenco di simboli (`symb`symb ..) e danno un elenco di un elenco di simboli. Se eseguiamo il sentente presso l'interprete interattivo, abbiamo una presentazione più conveniente (ogni chiave e associa i valori su una riga diversa)

code | `code`cod`co`c
golf | `golf`gol
going| `going`goin`goi

SPIEGAZIONE

x è l'argomento implicito della lambda

$x converti l'elenco dei simboli in un elenco di stringhe

(-1_)\ scorre su ogni elemento dell'elenco dei simboli

(legge come per ogni stringa calcola i prefissi (a iterazione mangia l'ultimo carattere della stringa (-1_), fino a quando la stringa vuota)

$ si trasforma nuovamente in un elenco di simboli (elenco di tutti i prefissi)

p: e assegna a p

,/ rasa tutto (concatena e crea una struttura a un livello)

= classifica -> per ogni prefisso univoco, associa le parole corrispondenti

#:' calcola la lunghezza (numero di parole associate a ciascun prefisso)

1= vero se lunghezza = 1 (non ambiguo), falso altrimenti

& dove -> indice di elementi veri

p in\: determina per tutti i prefissi se si trovano in un prefisso non ambiguo

(..)' si applica (..) a ciascun valore a destra (prefisso non ambiguo)

?0,&: -> distinto 0 concatenato dove (per far fronte alle parole come prefisso di se stesso)

p@ trasforma gli indici in simboli

x!.. costruire un dizionario con x (parole) come chiavi e .. come valori

Leggi come:

  • Costruisci e restituisce un dizionario con le parole come chiavi e valori.

  • ... valori di indici in posizioni distinte 0 (tutte le parole) e dove prefisso non ambiguo

  • ... inequivocabile calcolato come prefissi che compaiono solo in una parola (l'elenco di parole associato a ciascun simbolo ha una lunghezza)

  • ... elenca il risultato della classificazione di tutti i simboli univoci con le parole corrispondenti

  • ... prefissi calcolati ripetendo drop l'ultimo carattere di ogni parola


1

PHP 7.0, 67 byte (postdata la sfida)

for(;a&$c=$s[++$k]??($s=$argv[++$i])[$k=+$t=!1];)echo$t.=$c,":$s,";

accetta input dagli argomenti della riga di comando; stampa una virgola finale; corri con -nr.

per PHP più recente , aggiungi un byte: sostituisci &acon ""<.

per PHP più vecchi, usa questi 70 byte:

PHP, 70 byte

for(;a&$s=$argv[++$i];)for($k=+$t="";a&$c=$s[$k++];)echo$t.=$c,":$s,";

1

Brachylog , 23 byte

∋Xa₀Y;?↔⟨∋a₀⟩ᶜ1∧Y;X|∋gj

Provalo online!

Prende l'input come un elenco attraverso la variabile di input e genera un elenco di [key, value]coppie attraverso la variabile di output. Qualsiasi stringa di input che non è un prefisso di un'altra stringa di input verrà generata come prefisso di se stessa due volte, anche se l'intestazione su TIO lo nasconde utilizzando per ottenere l'elenco completo anziché .

 X                         X
∋                          is an element of
                           the input variable
    Y                      and Y
  a₀                       is a prefix of
 X                         X.
             ᶜ             The number of ways in which
        ⟨∋  ⟩              an element can be selected from
     ;?↔⟨   ⟩              the input variable
    Y; ↔⟨ a₀⟩              such that it has Y as a prefix
              1            is equal to 1.
               ∧Y          Y is not necessarily 1,
                   |       and the output variable
                Y;X        is the list [Y, X].
                   |       If every choice from the first rule has been taken already,
                           the output variable is
                    ∋      an element of
                   |       the input variable
                     gj    paired with itself.

Se i duplicati nell'output non sono tollerati, aggiungi tre byte per racchiudere il tutto {}ᵘ, a meno che non ci sia un modo più breve per escludere qualcosa dal prefisso di se stesso o generare ogni coppia di output necessaria senza la regola aggiuntiva ∋gj.
Unrelated String


1

APL (Dyalog Classic) , 38 byte

grazie Erik Outgolfer per avermi ricordato di usare una codifica di caratteri a byte singolo

{⊃,/⍵{b,¨⍨(⊂¨⍵~⊃,/a~⊂⍵)∪b←⊂⊂⍺}¨a←,⍵}

Provalo online!


1
Um ... Non vedo nessuno dei cattivi personaggi che non puoi usare con gli SBC di Adám qui ...: P
Erik the Outgolfer

senza accorgermene, ho scelto di nuovo la versione dell'interprete sbagliata ... grazie per aver dimezzato il mio conteggio di byte :)
ngn

0

Python (127)

Quindi non ho potuto commentare @undergroundmonorail, ma ho pensato che sarebbe stato meglio adottare un approccio da dizionario? Sono sicuro che con un po 'di comprensione da elenco / dizionario potrebbe essere ridotto anche tremendamente, ma non riesco a farlo funzionare saltando fuori dal dict.

i=raw_input().split(",")
d = {}
for x in i:
    for c in range(1,len(x)+1):
        if x[:c] in d:
            del d[x[:c]]
        else:
            d[x[:c]]=x
print d

La stampa produrrà il dizionario, non ordinato.

EDIT: Ahh ho perso la macchina: auto / auto: criteri di tappeto. Forse un controllo di lunghezza?


Forse mi manca qualcosa, ma questo sembra aggiungere ed eliminare alternativamente la voce del prefisso ogni volta che viene rilevata, quindi non appare un prefisso ambiguo se si presenta in 3 parole?
xnor

0

Groovy - 212 caratteri

golfed:

c="collectEntries";f="findAll";def g={def h=[:].withDefault{[]};it.each{def w->w.size().times{ h[w[0..it]] << w}};(h."$f"{k,v->v.size()==1}."$c"{k,v->[k,v[0]]}).plus(h."$f"{k,v->v.contains(k)}."$c"{k,v->[k,k]})}

esempio di output:

println g(["code","golf","going"])

[c:code, co:code, cod:code, code:code, gol:golf, golf:golf, goi:going, goin:going, going:going]

Ungolfed:

def g = { def list ->
    def hash = [:].withDefault{[]}
    list.each {
        def word -> word.size().times{ hash[word[0..it]] << word }
    }

    def map = hash.findAll{ k,v -> v.size() == 1 }.collectEntries{ k,v -> [k,v[0]] }
    map.plus(hash.findAll{ k,v -> v.contains(k) }.collectEntries{ k,v -> [k,k] }
    map
}


0

Zsh , 95 byte

local -A m
for w;{m[$w]=$w;x=
for c (${(s::)w})x+=$c&&[ ${(M)@:#$x*} = $w ]&&m[$x]=$w
}
local m

Provalo online!

L'unico modo per "restituire" un array associativo in Bash / Zsh è dichiararlo senza la localparola chiave e quindi accedervi nell'ambito genitore. Ciò salverebbe un byte. Tuttavia, l'I / O tramite le variabili è generalmente disapprovato, quindi stampiamo invece la definizione dell'array.

local -A m                          # declare m as associative
                                    # "local" is shorter than "typeset"/"declare"
for w;{                             # for each word
    m[$w]=$w                        # the word is a prefix of itself
    x=                              # ensure x is empty
    for c (${(s::)w})               # for each character in the word
        x+=$c &&                    # append to x (building a prefix
          [ ${(M)@:#$x*} = $w ] &&  # if the only match is the word itself:
          m[$x]=$w                  # ... then x is a prefix of w
}
local m                             # print m

0

Rubino , 84 byte

Ho appena notato che esiste già una soluzione Ruby, vabbè. Ciò migliora sostanzialmente la vecchia soluzione selezionando i prefissi in modo più intelligente (eliminando la necessità di aggiungere ogni parola come "prefisso" alla fine) e contando i prefissi per verificare l'unicità prima di aggiungerli all'hash, invece di sovrascrivere il valore con un manichino se c'è un duplicato e quindi cancellare la voce.

->w{h={};w.map{|e|(1..e.size).map{|i|w.count{|d|d[0,i]==e[0,i]}<2?h[e[0,i]]=e:0}};h}

Provalo online!

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.