Uma palavra composta é uma palavra que contém 2 ou mais palavras. Podemos fazer melhor que isso, no entanto. Precisamos que você crie 1 palavra (sem sentido) que contenha todas as palavras .
No entanto, queremos que essa palavra seja o mais curta possível. Podemos usar letras sobrepostas para conseguir isso.
Por exemplo, se sua lista de palavras fosse ["cat", "atom", "a"]
, você desejaria retornar "catom"
.
Entrada / Saída
Seu programa precisará pegar uma lista de palavras como entrada e retornar uma palavra composta como saída.
A lista de palavras que você usará são as 10000 palavras mais importantes em inglês, de acordo com o Google (se essa lista for muito fácil, posso alterá-la para uma mais longa). Para referência, basta adicionar cada palavra para obter uma pontuação de 65888.
Sua pontuação é o número de letras em sua palavra final, quanto menor, melhor. O desempatador vai para o primeiro pôster.
fonte
Respostas:
C ++, comprimento da palavra final: 38272
(a versão otimizada levou cerca de 20 minutos)
Base única de verificação:
Também produziu algumas palavras muito legais em andamento. Aqui estão alguns dos meus favoritos:
E:
A saída final está em pastebin aqui: http://pastebin.com/j3qYb65b
fonte
max_word_length - overlap(word[i], word[j])
(ondeoverlap
verifica a sobreposição à direita do primeiro argumento à esquerda do segundo). Resolver isso (boa sorte!) E depois cortar o loop resultante com o custo mais alto (sobreposição mais baixa) fornecerá uma lista ordenada de palavras que podem ser mescladas para fornecer uma solução ideal.C ++ 11, 38272 letras, comprovadamente ideal
Esse algoritmo é garantido para fornecer um limite inferior à solução. Nesse caso, ele é capaz de atingir o limite inferior e gerar uma solução ótima de 38272 letras. (Isso corresponde à solução encontrada pelo algoritmo ganancioso de Dave. Fiquei surpreso e um pouco decepcionado ao descobrir que é o ideal, mas aqui estamos.)
Ele funciona resolvendo o problema de fluxo de custo mínimo na rede criada da seguinte maneira.
Qualquer cadeia de comprimento n que contenha cada palavra pode ser convertida em um fluxo nessa rede com custo no máximo n . Portanto, o fluxo de custo mínimo nessa rede é um limite mais baixo no comprimento da string mais curta.
Se tivermos sorte - e, neste caso, tivermos -, depois de redirecionarmos o fluxo que entra em w _1 de w _0, encontraremos um fluxo ideal que tem apenas um componente conectado e que passa pelo nó para o vazio corda. Nesse caso, ele conterá um circuito euleriano que começa e termina aí. Esse circuito euleriano pode ser lido de volta como uma sequência de comprimento ideal.
Se não tivermos sorte, adicione alguns arcos extras entre a cadeia vazia e as cadeias mais curtas nos outros componentes conectados para garantir a existência de um circuito euleriano. A cadeia de caracteres não seria mais necessariamente ideal nesse caso.
Eu uso a biblioteca LEMON para seus algoritmos de fluxo de custo mínimo e de circuito euleriano. (Esta foi a primeira vez que eu usei essa biblioteca e fiquei impressionado - eu definitivamente a utilizarei novamente para futuras necessidades de algoritmos gráficos.) O LEMON vem com quatro algoritmos diferentes de fluxo de custo mínimo; você pode experimentá-los aqui com
--net
,--cost
,--cap
, e--cycle
(default).O programa é executado em 0,5 segundos , produzindo essa sequência de saída .
fonte
Java 8, ~ 5 minutos, comprimento de 39.279
Entrada:
Saída:
fonte
26,609
personagens.Python 2, 39254 caracteres
Leva de 1 a 2 minutos para rodar na minha máquina, funciona usando a palavra mais longa e sempre adicionando a palavra à sequência de resultados que possui mais sequências em comum. (Antes disso, todas as palavras que são substrings de outras palavras são removidas para evitar a adição desnecessária à string.)
Atualização: tentei olhar nas duas direções, mas isso não melhora. (talvez esteja usando palavras que possam ser usadas melhor mais tarde?)
Link para a palavra em pastebin.
100 primeiros caracteres:
Código:
fonte
Ruby, 39222 caracteres
Usa uma abordagem semelhante ao @KarlKastor em sua resposta em Python, mas a string inicial é uma das menores palavras em vez das maiores. Outra otimização (não sei o quanto isso ajuda) é que, entre cada adição, remove todas as palavras que já possam ter sido incluídas na string devido a sobreposição de palavras.
É executado em pouco mais de 4 minutos na minha máquina, sem contar a solicitação da Web para recuperar a lista de palavras, mas não com as 4:20.
A palavra em Pastebin.
fonte
PowerShell v2 +, 46152 caracteres
Pega a entrada como uma lista e a lança em um ArrayList (para que possamos manipulá-la). Nós
sort
que porlength
em-des
ordem cending. Então,while
ainda temos palavras em nossa matriz de entrada, faça um loop. Cada iteração, define o auxiliar$x
como igual ao número que resta, adere no próximo item da lista à nossa saída$o
e, em seguida, vasculha tudo o que ainda está em nossa lista. Se.IndexOf
não for igual a-1
(ou seja, a palavra foi encontrada em algum lugar$o
), removemos essa palavra da nossa lista de palavras restantes. Finalmente, no final, saída$o
.Eu não tenho acesso a um Pastebin ou similar, então aqui está o começo e o fim da palavra para temporário -
telecommunicationscharacterizationresponsibilitiessublimedirectory...fcmxvtwvfxwujmjsuhjjrxjdbkdxqc
. Acho que isso eliminou cerca de 20.000 caracteres da entrada, então não é tão ruim assim, suponho.Estou trabalhando em refinamentos.
fonte
PHP 46612 caracteres
Isto é só o começo. Espero melhorá-lo. Tudo o que fiz até agora foi remover qualquer palavra que seja uma sub-string de outra palavra. Estou trabalhando em 3 cópias da matriz, mas a memória não parece ser um problema.
fonte