Resolver um anagrama

9

Veja também: Granma ama Ana

Você receberá uma sequência de letras ASCII em minúsculas. Usando este arquivo de dicionário (ATUALIZADO), sua tarefa é resolver o anagrama. Para resolver um anagrama, você deve imprimir todas as palavras ou grupos de palavras que podem ser formadas usando cada letra da sequência de entrada exatamente uma vez, separadas por novas linhas. Grupos das mesmas palavras em uma ordem diferente não são exclusivos e não devem ser exibidos separadamente; no entanto, a ordem das palavras não importa . A ordem das soluções de saída também não importa . Se a entrada não puder formar uma palavra, não produza nada.

Alguns casos de teste úteis:

Input:  viinlg
Output: living

Input:  fceodglo
Output: code golf

Input:  flogflog
Output: golf golf

Input:  ahwhygi
Output: highway
        high way

Input:  bbbbbb
Output: 

Regras / advertências:

  • Você pode acessar a lista de dicionários da maneira que desejar. Argumentos na linha de comando, stdin, leitura de arquivo ou leitura da Internet são aceitáveis.

  • A entrada consistirá apenas em letras ASCII minúsculas. Você não é obrigado a produzir resultados em nenhum caso específico.

  • Você não receberá uma sequência que já forma uma palavra válida (você pode, no entanto, receber uma sequência que forma várias palavras, como bluehouse).

  • Novas linhas à direita são permitidas, mas não necessárias.

  • Aplicam-se brechas padrão.

Isso é . O menor código em bytes vence. Boa sorte!

dispersar
fonte
Devemos usar 1 espaço para separar conjuntos de palavras ou qualquer separador que não seja da letra é suficiente?
Erik the Outgolfer
@EriktheOutgolfer Para separar conjuntos de palavras, qualquer separador é adequado ; no entanto, você ainda deve separar as palavras em uma única solução com um espaço.
scatter
As Regras @ Christian dizem que você deve separar conjuntos de palavras com novas linhas.
Erik o Outgolfer
@EriktheOutgolfer Então, por que você perguntou "Devemos usar 1 espaço para separar conjuntos de palavras"? Sua pergunta me confundiu, e não deve haver razão para preferir nada a novas linhas para separar conjuntos. Eu diria que atenha-se às especificações.
scatter

Respostas:

2

Python 2 , 341 327 337 320 bytes

Esta solução supõe que o dicionário seja armazenado em uma variável wcomo um conjunto de seqüências de caracteres. O primeiro conjunto de combinationsnão precisa ser usado combinations_with_replacement, mas o último salva bytes.

from itertools import*
d,o,j,c={},sorted,''.join,combinations_with_replacement
s,w=o(raw_input()),input()
l=len(s)
r=range(l)
for x in w:d.setdefault(j(o(x)),[]).append(x)
b=set(chain(*[d[j(x)]for y in r for x in c(s,y+1)if j(x) in d]))
print'\n'.join(' '.join(x)for y in r for x in c(b,y+1)if(len(j(x)),o(j(x)))==(l,s))

Experimente online!

Entrada - Palavra anagramas seguida pelo dicionário de palavras como um conjunto:

anagram_word
{'entry1', 'entry2', ...., 'entryN'}

Editar: entradas atualizadas.

Sunny Patel
fonte
1

Python 3 , 248 202 bytes

from itertools import*
A=set()
def f(s,*G,i=1,A=A):
 if' '>s:A|={' '.join(sorted(G))}
 for _ in s:s[:i]in S and f(s[i:],s[:i],*G);i+=1
I,*S=iter(input,'')
for p in permutations(I):f(''.join(p))
print(A)

Experimente online!

A entrada é a seguinte:

word_input
dic_entry_1
dic_entry_2
....
dic_entry_N
                 # <<< empty line + \n

Acelerando:

Para fins de teste, se você mudar de I,*S=iter(input,'')para I=input();S=set(iter(input,'')), o tempo de execução será reduzido drasticamente e a saída será a mesma.

Explicação:

Em toda permutação da entrada, ela tenta dividir recursivamente a permutação em todos os locais possíveis, começando da esquerda para a direita, sem pular letras, com palavras que estão no dicionário. Se uma combinação dividida corresponder a toda a permutação de entrada, as palavras divididas serão classificadas e adicionadas a uma setque será impressa na e da avaliação.

Felipe Nardi Batista
fonte
1

Javascript, 139 137 129 bytes

-2 Bytes graças a @FelipeNardiBatista

-8 bytes graças à leitura dos documentos;)

k=>w=>{t=w;return k.reduce((a,v)=>{r=([...v].every(c=>w.includes(c)&&((w=w.replace(c,""))||!0)))?a.concat(v):a;w=t;return r},[])}

Recebe no dicionário como entrada na forma de uma matriz de seqüências de caracteres.

var arr = ["living", "code", "golf", "highway", "high", "way"];

var _=
k=>w=>{t=w;return k.reduce((a,v)=>{r=([...v].every(c=>w.includes(c)&&((w=w.replace(c,""))||!0)))?a.concat(v):a;w=t;return r},[])};

console.log(_(arr)("viinlg"));
console.log(_(arr)("fceodglo"));

Explicação:

Para cada palavra no dicionário, verifique se todas as letras estão contidas na palavra escolhida e, ao mesmo tempo, remova-a da palavra. No final de cada entrada do dicionário, restaure a palavra no estado inalterado para verificar se há outras correspondências.

Hankrecords
fonte
@FelipeNardiBatista Você está certo, eu esqueci de jogar esse nome. Obrigado :)
Hankrecords