Encuentra todos los prefijos inequívocos de un conjunto de cadenas

12

Para este desafío, debe implementar el Abbrevmódulo de Ruby en el menor código posible.

Desafío

  • La entrada será lo que su idioma tenga como una matriz (matriz, lista, secuencia, etc.) de cadenas. Puede escribir una función, o puede aceptar palabras separadas por comas en STDIN.

  • Luego debe calcular el conjunto de prefijos inequívocos para esas cadenas. Esto significa que debe devolver un hash (o mapa, objeto, etc.) de abreviaturas a sus cadenas originales.

    • Un "prefijo" es una subcadena de la cadena original que comienza al principio de la cadena. Por ejemplo, "pref" es un prefijo de la palabra "prefijo".

    • Un prefijo inequívoco es uno que solo puede significar una palabra. Por ejemplo, si su entrada es car,cat, entonces cano es un prefijo inequívoco porque podría significar "auto" o "gato".

    • La excepción a esta regla es que una palabra es siempre un prefijo de sí misma. Por ejemplo, si tiene una entrada como car,carpet, car:cardebe estar en su salida.

  • Luego puede devolver el hash / map / object / etc. desde su función (o haga el equivalente en su idioma), o imprímalo en STDOUT en key:valuepares en forma de f:foo,fo:foo,.... (Los pares clave-valor también pueden estar separados por espacios en blanco si acorta el código).

Casos de prueba

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

Reglas

  • La entrada no contendrá elementos duplicados.

  • Su salida puede estar en cualquier orden; No tienes que ordenarlo.

  • No puede usar un Abbrevmódulo / función / cosa incorporada como Ruby's.

  • Este es el , ¡así que el código más corto en bytes ganará!

Pomo de la puerta
fuente
¿Stdout tiene que ser exactamente ese formato? ¿O puedo hacer key:value\nkey:value\nkey:value...?
undergroundmonorail
44
En lugar de redefinir la abreviatura de la palabra , podría usar el prefijo con su significado estándar. Y creo que inequívoco transmite la propiedad deseada de las teclas de manera más efectiva que única , por lo que mi primera intuición fue que solo quería un prefijo por palabra de entrada.
Peter Taylor
@PeterTaylor Buena idea; editado
Pomo de la puerta
1
¿Se puede imprimir la misma clave varias veces (con el mismo valor)?
xnor

Respuestas:

1

APL (46)

(Sí, el juego de caracteres APL cabe en un byte, con espacio de sobra).

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

Esta es una función que toma una lista de cadenas y devuelve una matriz de 2 por N, donde cada fila contiene un prefijo inequívoco y la palabra a la que pertenece:

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

Explicación:

  • ∆←⍵: almacena el argumento correcto en .
  • {↑∘⍵¨⍳⍴⍵}¨∆: para cada elemento de , obtenga los posibles prefijos de ese elemento:
    • ⍳⍴⍵: obtener una lista de 1la longitud de
    • ↑∘⍵¨: para cada uno de esos números, obtenga tantos elementos de .
  • ∪⊃,/: concatenar las listas juntas y tomar los valores únicos.
  • {... : para cada uno de los prefijos únicos:
    • ∆/⍨⊃¨⍵∘⍷¨∆: seleccione las palabras que comienzan con ese prefijo
    • (⊂⍵),: también encierra el prefijo y concatena
    • ∆/⍨2=⍴∆←: solo devuelve la lista si hay dos elementos (el prefijo y una palabra coincidente)
  • : convierte la lista de tuplas en una matriz
marinus
fuente
El enlace está roto ahora ...
user202729
3

Python 2.7 - 146 141 bytes

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

Tenga en cuenta que la sangría en las líneas 4 y 5 no es 4 espacios, eso es un efecto secundario del intérprete de rebajas de SE. Ese es un carácter de tabulación literal, por lo que solo un byte.

Esto no está técnicamente a la altura, pero lo cambiaré si Doorknob lo aclara. Utiliza líneas nuevas en lugar de comas para separar la salida. Por ejemplo:

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

Nuevo: pude deshacerme de 5 caracteres asignando la cadena que estoy comprobando a una variable e. Esto significa que solo tengo que escribir en elugar de w[:a]tres veces. También significa que guardo personajes haciendo e=w[:a+1]y cambiando ...range(1,len(w)+1)a range(len(w)).


Explicación:

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.
metro subterráneo
fuente
Podrías usar en sum(b.startswith(e) for b in l)lugar delen(filter(lambda b:b.startswith(e),l))
Niklas B.
También puede acortar b.startswith(e)a b.find(e)==0o b[:a+1]==e, y verificar <2el recuento en lugar de ==1.
xnor
También hazlo en e=""\n for a in w:\n\te+=alugar de for a in range(len(w)):\n\te=w[:a+1]ahorrar 10 caracteres
WorldSEnder
He hecho una versión sin revelar aquí para cualquiera que lo necesite gist.github.com/stuaxo/c371b2d410191a575b763b74719856c8
Stuart Axon
3

J - 47 char

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

J ve las cadenas como simples vectores de caracteres, lo que significa que cuando intenta hacer una lista de cadenas, en realidad termina haciendo una tabla de caracteres, por lo que los extremos se rellenan con espacios. La solución de J a esto se llama caja , por lo que esta función toma como argumento una lista de cadenas en caja, para preservar la longitud.

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

Además, J carece de un tipo hash, por lo que lo más parecido a eso es una tabla de elementos de dos columnas, por ejemplo, cadenas en recuadro. Si eso es inaceptable y tengo que usar el formulario clave-valor por defecto, puedo reformatear la salida a este formulario en 67 caracteres en total:

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

Explicación por explosión:

(,.~~.@,[:(#~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

Ejemplos:

   (,.~~.@,[:(#~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,
Algoritmo de tiburón
fuente
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]

Versión sin golf:

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

Ejemplo:

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

Usé la initsfunción, que encuentra todos los prefijos de una lista / cadena. ¿Cuenta como trampa?

lortabac
fuente
1
Puede reemplazar concatMappor (=<<), que está en el Preludio. Te ahorra 10 personajes.
Rhymoid
@ Rhymoid Gracias. Eliminé concatMappero no puedo guardar más de 9 caracteres.
lortabac
Oh espera, tienes razón; Haskell lo considera >>=\ como un solo lexema. Lo siento por eso ...
Rhymoid
2

Pitón 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]

Repetimos los prefijos de cada palabra en la entrada, imprimiendo el par de prefijo / palabra correspondiente si aparece exactamente una vez o si corresponde a una palabra completa. Aprovechamos el comportamiento de cortocircuito de or(y printser una función) para imprimir solo si se cumple una de estas condiciones.

El whilebucle corta repetidamente el último carácter para crear prefijos cada vez más cortos, terminando cuando la cadena vacía permanece. Esta es la única vez que indexamos o dividimos en algo.

Contamos las ocurrencias del prefijo een la entrada buscando Ssubcadenas en la cadena de entrada original separada por comas ','+e. Anteponemos una coma a la cadena de entrada de antemano. Esta adición causa un elemento de cadena vacío adicional cuando nosotros split, pero esto no tiene ningún efecto porque no tiene subcadenas no vacías.

Para verificar el caso cuando la subcadena ees la palabra completa w, las comparamos utilizando el operador de comparación de cadenas. Esto se compara lexicográficamente, por lo que los prefijos más cortos son más pequeños. La doble comparación falla si e==wo bien S.count(c+e)<2.

Si e,wse permitieran las salidas de impresión en el formulario , en su lugar guardaría un carácter escribiendo e+c+w.

Crédito a undergroundmonorail de cuya respuesta basé mi estructura general de código.

xnor
fuente
(e<w)*S.count(c+e)>1se puede jugar al golf e<w<w*S.count(c+e)para guardar 2 caracteres.
isaacg
@isaacg ¡Gracias! He añadido tu optimización.
xnor
1

Rubí, 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

Sin golf:

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
dtldarek
fuente
1

k4 (70)

no particularmente golfizado; estoy seguro de que podría ser más corto

bastante similar a la J impl. Creo que antes, básicamente, solo recopila todos los prefijos (apropiados), elimina las palabras de los prefijos nuevamente (para manejar el caso "car"/ "carpet"), las agrupa en clases de equivalencia, selecciona las clases con un solo elemento, las reduce de las listas a cadenas y agrega en el mapa de cadenas a sí mismos.

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

algunos casos de prueba

tenga en cuenta que en k/ q, una cadena es una lista de caracteres, por lo que una cadena que contiene un solo carácter debe marcarse como tal utilizando la ,función unaria ; & mmwrt una lista de cadenas que contiene una sola cadena

Estos utilizan qla showfunción, que tiene un formato incorporado para algunas estructuras de datos, para hacer que los resultados sean más legibles:

  .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"
Aaron Davies
fuente
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 inicial

Entrada:

code,golf,going

Salida:

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

Mate
fuente
1

Perl, 93 77

Con nuevas líneas y sangría para facilitar la lectura:

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

Un poco tarde y demasiado largo, pero me alegro de que finalmente haya llegado a menos de 100. La función devuelve una lista que se puede asignar a la variable hash:

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

y

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

En realidad, la lista devuelta aún no se filtra; la construcción de hash se completa en el momento de su asignación, es decir, la función externa. SI no es lo suficientemente limpio / justo, agregue 3 para contar y coloque el contenido de la función en llaves, precediendo +, luego la función devuelve la referencia hash 'verdadera'.

usuario2846289
fuente
1

Q: 44 bytes

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

Notas

  • El lenguaje Q tiene un núcleo interno llamado internamente K4 (usado en esta respuesta y otra respuesta previa a esta pregunta)

  • Para probar el código, descargue el intérprete (kx.com, gratuito para uso no comercial, soporte para Windows, Linux, Mac)

El intérprete admite dos sintaxis:

  • detallado (nombres más legibles, nombres distintos para montañas y diads, más bibliotecas, ...). Cargar archivo fuente con extensión q o intérprete interactivo

  • compacto (núcleo interno funcional, operadores de una letra, misma letra para ambos usos mónada / diad, ...). Cargue el archivo fuente con la extensión k, o el intérprete interactivo en modo k (escriba \ en el indicador). El código debe ser probado en este modo

El código define una lambda (función anónima). Para dar nombre a la función, necesitamos el nombre del prefijo: (ex f: {..}), por lo que requiere 46 bytes

PRUEBA

(suponiendo una función con nombre: de lo contrario, sustituya f por el código)

f `code`golf`going

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

devuelve un diccionario (claves de sintaxis! valores). Las teclas son una lista de símbolos (`symb`symb ..), y valora una lista de símbolos. Si ejecutamos la sentencia en el intérprete interactivo, tenemos una presentación más conveniente (cada clave y valores asociados en una línea diferente)

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

EXPLICACIÓN

x es el argumento implícito de la lambda

$x convertir lista de símbolos a lista de cadenas

(-1_)\ itera sobre cada elemento de la lista de símbolos

(se lee como para cada cadena calcula prefijos (en la iteración de comer cae el último carácter de la cadena (-1_), hasta que la cadena esté vacía)

$ se transforma de nuevo en una lista de símbolos (lista de todos los prefijos)

p: y asigna a p

,/ arrasar todo (concatena y crea una estructura de un nivel)

= clasifica -> para cada prefijo único, asocia las palabras correspondientes

#:' calcula la longitud (número de palabras asociadas a cada prefijo)

1= verdadero si longitud = 1 (inequívoco), falso de lo contrario

& donde -> índice de elementos verdaderos

p in\: determina para todos los prefijos si están en un prefijo inequívoco

(..)' se aplica (..) a cada valor a la derecha (prefijo inequívoco)

?0,&: -> distinto 0 concatenado donde (para hacer frente a las palabras como prefijo de sí mismo)

p@ transformar índices en símbolos

x!.. construir un diccionario con x (palabras) como claves y .. como valores

Leído como:

  • Construye y devuelve un diccionario con las palabras como claves y valores.

  • ... valores de índices en posiciones distintas 0 (todas las palabras) y donde prefijo inequívoco

  • ... inequívoco calculado como prefijos que aparecen solo en una palabra (la lista de palabras se asocia a cada símbolo tiene una longitud)

  • ... listas resultantes de clasificar todos los símbolos únicos con las palabras correspondientes

  • ... prefijos calculados repitiendo drop last char de cada palabra

J. Sendra
fuente
1

PHP 7.0, 67 bytes (es posterior al desafío)

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

toma datos de los argumentos de la línea de comandos; imprime una coma final; correr con -nr.

para PHP más nuevo , agregue un byte: Reemplace &acon ""<.

para PHP anterior, use estos 70 bytes:

PHP, 70 bytes

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

Brachylog , 23 bytes

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

Pruébalo en línea!

Toma la entrada como una lista a través de la variable de entrada y genera una lista de [key, value]pares a través de la variable de salida. Cualquier cadena de entrada que no sea un prefijo de otra cadena de entrada se generará como un prefijo de sí misma dos veces, aunque el encabezado en TIO lo oculta usando para obtener la lista completa en lugar de .

 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.
Cadena no relacionada
fuente
Si no se toleran los duplicados en la salida, agregue tres bytes para envolver todo {}ᵘ, a menos que haya una forma más corta de excluir que algo sea un prefijo de sí mismo o generar todos los pares de salida necesarios sin la regla adicional ∋gj.
Cadena no relacionada
1

APL (Dyalog Classic) , 38 bytes

gracias Erik the Outgolfer por recordarme que use una codificación de caracteres de un solo byte

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

Pruébalo en línea!

ngn
fuente
1
Um ... No veo ninguno de los personajes malos que no puedes usar con el SBCS de Adám aquí ...: P
Erik the Outgolfer
sin darme cuenta, he elegido de nuevo la versión incorrecta del intérprete ... gracias por reducir a la mitad mi recuento de bytes :)
ngn
0

Pitón (127)

¿Entonces no pude comentar @undergroundmonorail, pero pensé que sería mejor adoptar un enfoque de diccionario? Estoy seguro de que con un poco de comprensión de listas / diccionarios también podría reducirse enormemente, pero no puedo hacer que funcione con estallidos del 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 impresión generará el diccionario, sin ordenar.

EDITAR: Ahh, perdí el auto: auto / auto: criterio de alfombra. Tal vez una verificación de longitud?

jaybee3
fuente
Tal vez me falta algo, pero esto parece agregar y eliminar alternativamente la entrada de prefijo cada vez que se encuentra, entonces, ¿no aparecería un prefijo ambiguo si aparece en 3 palabras?
xnor
0

Groovy - 212 caracteres

Golfizado:

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]})}

salida de ejemplo:

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

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

Sin golf:

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
}
Michael Easter
fuente
0

Zsh , 95 bytes

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

Pruébalo en línea!

La única forma de "devolver" una matriz asociativa en Bash / Zsh es declarándola sin la localpalabra clave y luego accediendo a ella en el ámbito primario. Esto ahorraría un byte. Sin embargo, la E / S a través de variables generalmente está mal vista, por lo que imprimimos la definición de matriz en su lugar.

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
Función Gamma
fuente
0

Ruby , 84 bytes

Acabo de notar que ya existe una solución Ruby, oh bueno. Básicamente, esto mejora la solución anterior al elegir prefijos de una manera más inteligente (eliminando la necesidad de agregar cada palabra como "prefijo" al final) y contando los prefijos para verificar la unicidad antes de agregarlos al hash, en lugar de sobrescribir el valor con un maniquí si hay un duplicado y luego borrando la entrada.

->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}

Pruébalo en línea!

Tinta de valor
fuente