Para esse desafio, você deve implementar o Abbrev
módulo Ruby no menor código possível.
Desafio
A entrada será qualquer que seja o seu idioma como um array (array, lista, sequência, etc.) de strings. Você pode escrever uma função ou aceitar palavras separadas por vírgula no STDIN.
Você deve calcular o conjunto de prefixos inequívocos para essas seqüências. Isso significa que você deve retornar um hash (ou mapa, objeto etc.) de abreviações para suas strings originais.
Um "prefixo" é uma subcadeia de caracteres da string original, iniciando no início da string. Por exemplo, "pref" é um prefixo da palavra "prefix".
Um prefixo inequívoco é aquele que pode significar apenas uma palavra. Por exemplo, se sua entrada for
car,cat
,ca
não será um prefixo inequívoco, pois pode significar "carro" ou "gato".A exceção a essa regra é que uma palavra é sempre um prefixo de si mesma. Por exemplo, se você tiver uma entrada como
car,carpet
,car:car
deve estar em sua saída.
Você pode então retornar o hash / mapa / objeto / etc. da sua função (ou faça o equivalente no seu idioma) ou imprima para STDOUT em
key:value
pares na forma def:foo,fo:foo,...
. (Os pares de valores-chave também podem ser separados por espaços em branco se o código for mais curto.)
Casos de teste
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
Regras
A entrada não conterá elementos duplicados.
Sua saída pode estar em qualquer ordem; você não precisa classificá-lo.
Você não pode usar um
Abbrev
módulo / função / coisa embutida como o Ruby's.Isso é código-golfe , então o código mais curto em bytes vencerá!
key:value\nkey:value\nkey:value
...?Respostas:
APL (46)
(Sim, o conjunto de caracteres APL cabe em um byte, com espaço de sobra.)
Essa é uma função que pega uma lista de cadeias e retorna uma matriz 2 por N, onde cada linha contém um prefixo inequívoco e a palavra à qual pertence:
Explicação:
∆←⍵
: armazena o argumento correto em∆
.{↑∘⍵¨⍳⍴⍵}¨∆
: para cada elemento de∆
, obtenha os possíveis prefixos desse elemento:⍳⍴⍵
: obtenha uma lista1
com o comprimento de⍵
↑∘⍵¨
: para cada um desses números, obtenha muitos elementos⍵
.∪⊃,/
: concatene as listas e obtenha os valores exclusivos.{
...}¨
: para cada um dos prefixos exclusivos:∆/⍨⊃¨⍵∘⍷¨∆
: selecione as palavras que começam com esse prefixo(⊂⍵),
: inclua também o prefixo e concatene∆/⍨2=⍴∆←
: retorne a lista apenas se houver dois elementos (o prefixo e uma palavra correspondente)↑
: transformar a lista de tuplas em uma matrizfonte
Python 2.7 -
146141 bytesObserve que o recuo nas linhas 4 e 5 não é de 4 espaços, isso é um efeito colateral do intérprete de redução de preço da SE. Esse é um caractere de tabulação literal, portanto, apenas um byte.
Tecnicamente, isso não está de acordo com as especificações, mas vou alterá-lo se a Maçaneta da porta esclarecer. Ele usa novas linhas em vez de vírgulas para separar a saída. Por exemplo:
Novo: consegui me livrar de 5 caracteres atribuindo a string que estou verificando a uma variável
e
. Isso significa que eu só preciso digitar eme
vez dew[:a]
três vezes. Isso também significa que eu salvo os personagens fazendoe=w[:a+1]
e mudando...range(1,len(w)+1)
pararange(len(w))
.Explicação:
fonte
sum(b.startswith(e) for b in l)
em vez delen(filter(lambda b:b.startswith(e),l))
b.startswith(e)
parab.find(e)==0
oub[:a+1]==e
e verificar<2
a contagem em vez de==1
.e=""\n for a in w:\n\te+=a
vez defor a in range(len(w)):\n\te=w[:a+1]
salvar 10 caracteresJ - 47 char
J vê as strings apenas como vetores de caracteres, o que significa que, quando tenta fazer uma lista de strings, acaba criando uma tabela de caracteres, para que as extremidades fiquem preenchidas com espaços. A solução de J para isso é chamada de caixa , de modo que esta função assume como argumento uma lista de seqüências de caracteres em caixa, para preservar o comprimento.
Além disso, J não possui um tipo de hash, portanto, o mais próximo a ele é de uma tabela de itens de duas colunas, por exemplo, cadeias de caixa. Se isso for inaceitável e eu tiver que usar como padrão o formulário de valor-chave, posso reformatar a saída para este formulário em um total de 67 caracteres :
Explicação por explosão:
Exemplos:
fonte
Haskell
9687Versão não destruída:
Exemplo:
Eu usei a
inits
função, que encontra todos os prefixos de uma lista / string. Isso conta como trapaça?fonte
concatMap
por(=<<)
, que está no Prelúdio. Economiza 10 caracteres.concatMap
mas não consigo salvar mais de 9 caracteres.>>=\
como um único léxico. Desculpe por isso ...Python 3 (97)
Nós iteramos sobre os prefixos de cada palavra na entrada, imprimindo o par correspondente de prefixo / palavra se ele aparecer exatamente uma vez ou for para a palavra inteira. Aproveitamos o comportamento de curto-circuito de
or
(eprint
sendo uma função) para imprimir apenas se uma dessas condições for atendida.O
while
loop corta repetidamente o último caractere para criar prefixos cada vez mais curtos, terminando quando a string vazia permanece. Essa é a única vez que indexamos ou dividimos em algo.Contamos as ocorrências do prefixo
e
na entrada pesquisando na sequência de entrada original separada por vírgulaS
por substrings','+e
. Anexamos uma vírgula à string de entrada beaforehand. Essa adição causa um elemento de seqüência de caracteres extra vazio quando nóssplit
, mas isso não tem efeito porque não possui substrings não vazios.Para verificar o caso em que a substring
e
é a palavra inteiraw
, comparamos usando o operador de comparação de cadeias. Isso se compara lexicograficamente, portanto, prefixos mais curtos são menores. A comparação dupla falha see==w
ouS.count(c+e)<2
.Se a impressão de saídas no formulário
e,w
fosse permitida, eu salvaria um caractere escrevendoe+c+w
.Crédito para undergroundmonorail a partir de cuja resposta eu baseei minha estrutura geral de código.
fonte
(e<w)*S.count(c+e)>1
pode ser jogado no golfee<w<w*S.count(c+e)
para salvar 2 caracteres.Ruby, 114
Ungolfed:
fonte
k4 (70)
não particularmente jogado de golfe; tenho certeza que poderia ser mais curto
bem parecido com o J impl. acima, eu acho - basicamente apenas coleta todos os prefixos (apropriados), remove as palavras dos prefixos novamente (para manipular o
"car"
/"carpet"
case), agrupa-as em classes de equivalência, escolhe as classes com apenas um elemento, reduz-as das listas para strings e adiciona no mapa de strings para si mesmos.alguns casos de teste
observe que em
k
/q
, uma string é uma lista de caracteres; portanto, uma string contendo apenas um único caractere precisa ser marcada como tal usando a,
função unary ; & mmwrt uma lista de cadeias contendo apenas uma cadeiaq
ashow
função use , que possui formatação interna para algumas estruturas de dados, para tornar os resultados mais legíveis:fonte
JavaScript - 212
Golfe inicial.
Entrada:
code,golf,going
Resultado:
["c:code", "co:code", "cod:code", "code:code", "gol:golf", "golf:golf", "goi:going", "goin:going", "going:going"]
fonte
Perl,
9377Com novas linhas e recuo para facilitar a leitura:
Um pouco tarde e muito tempo, mas estou feliz que finalmente tenha ficado abaixo de 100. A função retorna uma lista que pode ser atribuída à variável de hash:
e
Na verdade, a lista retornada ainda não foi filtrada - a construção de hash é concluída no momento de sua atribuição, ou seja, função externa. Se não estiver suficientemente limpo / limpo, adicione 3 para contar e coloque o conteúdo da função entre chaves, acrescentando
+
- então a função retorna a referência de hash 'true'.fonte
Q: 44 bytes
NOTAS
A linguagem Q possui um núcleo interno chamado internamente K4 (usado nesta resposta e outra resposta anterior a esta pergunta)
Para testar o código, faça o download do interpretador (kx.com, gratuito para uso não comercial, suporte para Windows, Linux, Mac)
O intérprete admite duas sintaxes:
verbose (nomes mais legíveis, nomes distintos para moands e diads, mais bibliotecas, ...). Carregar arquivo de origem com extensão q ou intérprete interativo
compacto (núcleo interno funcional, operadores de uma letra, mesma letra para ambos os usos monad / diad, ...). Carregue o arquivo de origem com extensão k ou intérprete interativo no modo k (write \ at prompt). O código deve ser testado neste modo
O código define um lambda (função anônima). Para dar um nome à função, precisamos do nome do prefixo: (ex f: {..}), portanto, requer 46 bytes
TESTE
(assumindo a função nomeada: caso contrário, substitua f pelo código)
retorna um dicionário (chaves de sintaxe! valores). As teclas são uma lista de símbolos (`symb`symb ..) e valorizam uma lista de lista de símbolos. Se executarmos o sentente no intérprete interativo, teremos uma apresentação mais conveniente (cada chave e associar valores em uma linha diferente)
EXPLICAÇÃO
x
é o argumento implícito para o lambda$x
converter lista de símbolos em lista de cadeias(-1_)\
itera sobre cada elem da lista de símbolos(lê como para cada seqüência de caracteres calcula prefixos (na iteração final, cai o último caractere da seqüência de caracteres (-1_), até a sequência vazia))
$
transforma em uma lista de símbolos novamente (lista de todos os prefixos)p:
e atribui a p,/
arrasar tudo (concatena e cria uma estrutura de um nível)=
classificar -> para cada prefixo exclusivo, associa as palavras correspondentes#:'
calcula o comprimento (número de palavras associadas a cada prefixo)1=
verdadeiro se comprimento = 1 (inequívoco), falso caso contrário&
onde -> índice de elementos verdadeirosp in\:
determina para todos os prefixos se eles estiverem no prefixo inequívoco(..)'
aplica (..) a cada valor à direita (prefixo inequívoco)?0,&:
-> 0 distinto concatenado onde (lidar com as palavras como prefixo de si mesmo)p@
transformar índices em símbolosx!..
construa um dicionário com x (palavras) como chaves e .. como valoresLeia como:
Construa e retorne um dicionário com as palavras como chaves e valores.
... valores de índices em posições distintas 0 (todas as palavras) e em que prefixo inequívoco
... inequívoco calculado como prefixos que aparecem apenas em uma palavra (a lista de palavras associada a cada símbolo tem o comprimento um)
... lista resultante da classificação de todos os símbolos exclusivos com as palavras correspondentes
... prefixos calculados repetindo o último caractere de gota de cada palavra
fonte
PHP 7.0, 67 bytes (pós-desafio)
recebe entrada de argumentos de linha de comando; imprime uma vírgula à direita; corra com
-nr
.para PHP mais recente , adicione um byte: Substitua
&a
por""<
.para PHP antigo, use estes 70 bytes:
PHP, 70 bytes
fonte
Braquilog , 23 bytes
Experimente online!
Leva a entrada como uma lista através da variável de entrada e gera uma lista de
[key, value]
pares através da variável de saída. Qualquer string de entrada que não seja um prefixo de outra string de entrada será gerada como um prefixo de si mesma duas vezes, embora o cabeçalho no TIO oculte isso usandoᵘ
para obter a lista completa em vez deᶠ
.fonte
{}ᵘ
, a menos que haja uma maneira mais curta de excluir algo de um prefixo ou gerar cada par de saída necessário sem a regra extra∋gj
.Perl 5
-a
, 76 bytesExperimente online!
fonte
APL (Dyalog Classic) , 38 bytes
obrigado Erik, o Outgolfer, por me lembrar de usar uma codificação de caracteres de byte único
Experimente online!
fonte
Python (127)
Então não pude comentar @undergroundmonorail, mas achei que seria melhor usar uma abordagem de dicionário? Tenho certeza de que, com alguma compreensão de lista / dicionário, ele também pode ser tremendamente reduzido, mas não é possível fazê-lo funcionar com o pop do dict.
A impressão exibirá o dicionário sem ordem.
EDIT: Ahh eu perdi o carro: carro / carro: critérios de carpete. Talvez uma verificação de comprimento?
fonte
Groovy - 212 caracteres
Golfe:
saída de exemplo:
Ungolfed:
fonte
JavaScript (Node.js) , 88 bytes
Experimente online!
fonte
Zsh , 95 bytes
Experimente online!
A única maneira de "retornar" uma matriz associativa no Bash / Zsh é declarando-a sem a
local
palavra - chave e acessando-a no escopo pai. Isso economizaria um byte. No entanto, a E / S por meio de variáveis geralmente é desaprovada, portanto, imprimimos a definição da matriz.fonte
Ruby , 84 bytes
Só notei que já existe uma solução Ruby existente, tudo bem. Isso basicamente melhora a solução antiga escolhendo prefixos de maneira mais inteligente (eliminando a necessidade de adicionar cada palavra como "prefixo" no final) e contando prefixos para verificar a exclusividade antes de adicioná-los ao hash, em vez de sobrescrever o valor com um manequim se houver uma duplicata e depois apagar a entrada.
Experimente online!
fonte