Un mot composé est un mot qui contient 2 mots ou plus. Mais nous pouvons faire mieux que cela. Nous avons besoin de vous pour créer 1 mot (absurde) qui contient chaque mot .
Cependant, nous voulons que ce mot soit aussi court que possible. Nous pouvons utiliser des lettres qui se chevauchent pour y parvenir.
Par exemple, si votre liste de mots était ["cat", "atom", "a"]
, vous voudriez revenir "catom"
.
Entrée sortie
Votre programme devra prendre une liste de mots en entrée et renvoyer un mot composé en sortie.
La liste de mots que vous utiliserez est les 10000 premiers mots en anglais, selon Google (si cette liste s'avère trop facile, je peux la changer en une plus longue). Pour référence, le simple fait d'ajouter chaque mot vous donne un score de 65888.
Votre score est le nombre de lettres de votre dernier mot, plus c'est bas, mieux c'est. Le bris d'égalité va à la première affiche.
la source
Réponses:
C ++, longueur du dernier mot: 38272
(la version optimisée a pris environ 20 minutes)
Vérification bash one-liner:
Il a également produit des mots en cours assez cool. Voici quelques-uns de mes favoris:
Et:
La sortie finale est sur pastebin ici: http://pastebin.com/j3qYb65b
la source
max_word_length - overlap(word[i], word[j])
(oùoverlap
vérifie le chevauchement à droite de la premier argument à gauche du second). Résoudre cela (bonne chance!) Puis couper la boucle résultante au coût le plus élevé (chevauchement le plus faible) donnera une liste ordonnée de mots qui peuvent être fusionnés pour donner une solution optimale.C ++ 11, 38272 lettres, optimales prouvées
Cet algorithme est garanti pour fournir une limite inférieure sur la solution. Dans ce cas, il est capable d'atteindre la limite inférieure et de produire une solution optimale de 38272 lettres. (Cela correspond à la solution trouvée par l'algorithme gourmand de Dave. J'ai été surpris et un peu déçu de découvrir que c'est optimal, mais nous y voilà.)
Il fonctionne en résolvant le problème de flux à coût minimum sur le réseau construit comme suit.
Toute chaîne de longueur n qui contient chaque mot peut être convertie en un flux sur ce réseau avec un coût au plus n . Par conséquent, le flux de coûts minimum sur ce réseau est une limite inférieure sur la longueur de la chaîne la plus courte.
Si nous sommes chanceux - et dans ce cas, nous le sommes - alors après avoir redirigé le flux entrant dans w _1 de retour de w _0, nous trouverons un flux optimal qui n'a qu'un seul composant connecté et qui traverse le nœud pour le vide chaîne. Si c'est le cas, il contiendra un circuit eulérien commençant et se terminant là. Un tel circuit eulérien peut être lu comme une chaîne de longueur optimale.
Si nous n'avons pas eu de chance, ajoutez des arcs supplémentaires entre la chaîne vide et les chaînes les plus courtes des autres composants connectés afin de garantir l'existence d'un circuit eulérien. La chaîne ne serait plus nécessairement optimale dans ce cas.
J'utilise la bibliothèque LEMON pour ses algorithmes de flux à moindre coût et de circuit eulérien. (C'était la première fois que j'utilisais cette bibliothèque, et j'ai été impressionné — je vais certainement l'utiliser à nouveau pour les futurs besoins d'algorithmes de graphes.) LEMON est livré avec quatre algorithmes de flux à coût minimum différents; vous pouvez les essayer ici avec
--net
,--cost
,--cap
et--cycle
(par défaut).Le programme s'exécute en 0,5 seconde , produisant cette chaîne de sortie .
la source
Java 8, ~ 5 minutes, durée de 39 279
Contribution:
Sortie:
la source
26,609
personnages.Python 2, 39254 caractères
Prend 1-2 minutes pour fonctionner sur ma machine, fonctionne en prenant le mot le plus long puis en ajoutant toujours le mot à la chaîne de résultat qui a le plus de chaînes en commun. (Avant cela, tous les mots qui sont des sous-chaînes d'autres mots sont supprimés pour éviter des ajouts inutiles à la chaîne.)
Mise à jour: J'ai essayé de regarder dans les deux sens, mais cela ne fait pas mieux. (peut-être utilise-t-il des mots qui peuvent être mieux utilisés plus tard?)
Lien vers le mot sur pastebin.
100 premiers caractères:
Code:
la source
Ruby, 39222 caractères
Utilise une approche similaire à @KarlKastor dans sa réponse Python, mais la chaîne de départ est l'un des plus petits mots au lieu du plus grand. Une autre optimisation (je ne sais pas combien cela aide) est qu'entre chaque ajout, il élague tous les mots qui ont peut-être déjà été inclus dans la chaîne en raison de chevauchements de mots.
Fonctionne en un peu plus de 4 minutes sur ma machine, sans compter la requête Web pour récupérer la liste des mots, mais pas tout à fait 4:20.
Le mot sur Pastebin.
la source
PowerShell v2 +, 46152 caractères
Prend l'entrée sous forme de liste, la transforme en ArrayList (afin que nous puissions la manipuler). Nous
sort
parlength
dans l'-des
ordre cending. Ensuite,while
nous avons encore des mots dans notre tableau d'entrée, faites une boucle. À chaque itération, définissez helper$x
comme étant égal au nombre restant, clouez le prochain élément de la liste à notre sortie$o
, puis parcourez tout ce qui se trouve encore dans notre liste. Si le.IndexOf
n'est pas égal à-1
(c'est- à -dire que le mot a été trouvé quelque part$o
), nous supprimons ce mot de notre liste de mots restants. Enfin, à la fin, la sortie$o
.Je n'ai pas accès à un Pastebin ou similaire, alors voici le début et la fin du mot pour temporaire -
telecommunicationscharacterizationresponsibilitiessublimedirectory...fcmxvtwvfxwujmjsuhjjrxjdbkdxqc
. Ce qui, je suppose, a rasé environ 20 000 caractères de l'entrée, donc pas si mal, je suppose.Je travaille sur des améliorations.
la source
PHP 46612 caractères
Ceci est juste un début. J'espère l'améliorer. Tout ce que j'ai fait jusqu'à présent est de supprimer tout mot qui est une sous-chaîne d'un autre mot. Je travaille sur 3 copies du tableau, mais la mémoire ne semble pas être un problème.
la source