L'autre jour, nous écrivions des phrases avec ma fille avec une lettre d'aimant de réfrigérateur. Bien que nous ayons pu en faire ( I love cat
), nous n’avions pas assez de lettres pour faire les autres ( I love you too
) en raison du nombre insuffisant de lettres o
(4)
J'ai ensuite découvert que si un jeu comprenait 3 e
lettres, il n'en avait que 2 o
. Probablement inspiré par http://en.wikipedia.org/wiki/Letter_frequency, cela ne refléterait toujours pas la situation réelle "sur le réfrigérateur".
Problème
Étant donné le fichier texte dans lequel chaque ligne contient un "exemple de phrase", vous souhaitez écrire sur le réfrigérateur, proposez un jeu d’alphabets comprenant un minimum de lettres mais suffisant pour écrire chaque phrase individuellement.
Remarque: ignorez les cas, toutes les lettres magnétiques sont des majuscules.
Contribution
Le fichier contient des phrases séparées par une nouvelle ligne:
hello
i love cat
i love dog
i love mommy
mommy loves daddy
Sortie
Fournissez une liste de lettres triée en ordre, chaque lettre apparaissant autant de fois qu'il est suffisant pour écrire une phrase:
acdddeghillmmmoostvyy
(merci, isaacg!)
Gagnant
Mise en oeuvre la plus courte (code)
MISE À JOUR: Test
J'ai créé un test supplémentaire et essayé avec diverses réponses ici:
v
dans la sortie;)M
pour unW
ou un côtéN
pour unZ
? ;-)I
s._\¯
Réponses:
GolfScript, 28/34 caractères
Le programme de 28 caractères ci-dessus suppose que toutes les lettres entrées sont dans le même cas. Si ce n'est pas nécessairement le cas, nous pouvons les forcer en majuscules en ajoutant
{95&}%
le code au préalable , pour un total de 34 caractères:Remarques:
Pour un fonctionnement correct, l'entrée doit inclure au moins une nouvelle ligne. Cela sera vrai pour les fichiers texte normaux avec des nouvelles lignes à la fin de chaque ligne, mais peut ne pas l'être si l'entrée est composée d'une seule ligne sans fin de ligne. Cela pourrait être fixé au prix de deux caractères supplémentaires, en ajoutant
n+
le code au début .La majuscule utilisée dans la version à 34 caractères est très grossière: elle mappe les lettres ASCII minuscules en leurs équivalents majuscules (et les espaces en
NUL
s), mais crée un fouillis complet de chiffres et de la plupart des signes de ponctuation. Je suppose que l'entrée ne comprendra aucun de ces caractères.La version à 28 caractères traite tous les caractères saisis (à l'exception des sauts de lignes et des
NUL
s). En particulier, si l'entrée contient des espaces, certains apparaîtront également dans la sortie. commodément, ils trieront avant tout autre caractère ASCII imprimable. La version à 34 caractères, cependant, ignore les espaces (car il s’avère que je peux le faire sans que cela ne me coûte aucun caractère supplémentaire).Explication:
Le
{95&}%
préfixe facultatif majuscule l'entrée en mettant à zéro le sixième bit du code ASCII de chaque entrée byte ( ). Cela mappe les lettres ASCII minuscules en majuscules, les espaces en octets nuls et laisse les nouvelles lignes inchangées.95 = 64 + 31 = 10111112
n/
divise l'entrée aux nouvelles lignes et:a
affecte le tableau résultant à la variablea
. Puis{|}*
calcule l’union des chaînes dans le tableau (qui suppose (si le tableau comporte au moins deux éléments)) une chaîne contenant tous les caractères uniques (autres que les caractères de nouvelle ligne) de l’entrée.La
{ }%
boucle suivante parcourt ensuite chacun de ces caractères uniques. À l'intérieur du corps de la boucle, la boucle internea{.[2$]--}%
parcourt les chaînes du tableaua
, supprimant de chaque chaîne tous les caractères différents de celui sur lequel la boucle externe effectue une itération.La boucle interne laisse le code ASCII du caractère actuel sur la pile, sous le tableau filtré. Nous nous en servons en répétant le tableau filtré autant de fois que le indique le code ASCII (
*
) avant de le trier ($
) et de prendre le dernier élément (-1=
). En effet, cela produit la chaîne la plus longue du tableau filtré (toutes les répétitions du même caractère étant triées par le même caractère, le tri lexicographique les trie simplement par longueur), sauf si le caractère a le code ASCII zéro, auquel cas il ne produit rien.Enfin, la
$
fin trie simplement la sortie par ordre alphabétique.la source
n/:a{|}*{{{=}+,}+a%$-1=}%$
.J - 37 caractères
Lit à partir de stdin, sorties sur la console.
1!:1]3
est l'appel à stdin.tolower;._2
effectue une double tâche en scindant les lignes et en les minuscules simultanément. Ensuite, nous comptons le nombre de fois qu'un caractère apparaît dans chaque ligne+/"2=/&a.
et prenons le maximum de point par point sur toutes les lignes>./
.Enfin, nous extrayons autant de caractères de chaque caractère de l'alphabet
#&a.
. Cela inclut les espaces - tous trouvés à l'avant en raison de leur faible valeur ASCII - nous supprimons donc simplement les espaces en début de ligne avecdlb
.la source
JavaScript (ECMAScript 6) -
148139135 caractèresVersion 2:
Mis à jour pour utiliser la compréhension du tableau:
Version 1:
Suppose que:
s
;Avec des commentaires:
Si tu veux:
.join('')
la fin.s
variable parprompt()
; ouf
puis ajoutez-lef=s=>
au début.Fonctionnement:
Donne la sortie:
la source
/\s*/
à/ */
et enlever les parens autourj=0
...
au lieu deapply
?...
) est un opérateur que je n’ai jamais rencontré auparavant.[].concat(...s.split`N`.map(x=>x.split(/ */).map((x,i,a)=>x+(a[x]=a[x]?++j:j=1)))).sort().map((x,i,a)=>a[i-1]<x?x[0]:'').join``;
Perl - 46 octets
Compter le shebang comme 1. Ceci est une traduction en vrac de la solution Ruby ci-dessous.
Ruby 1.8 - 72 octets
L'entrée est prise de
stdin
.Exemple d'utilisation:
la source
/i
etfor
.Python -
206204199177145129117 1179488 caractèresJe ne savais pas comment je devais obtenir le nom du fichier, donc pour le moment le code suppose qu'il est contenu dans une variable nommée
f
. S'il vous plaît laissez-moi savoir si je dois changer cela.la source
f
que le nom de fichier soit entré et en utilisant des majuscules (toutes les lettres de l'aimant sont majuscules, de toute façon), vous pouvez le réduire à 91:print(''.join([chr(i)*max(l.upper().count(chr(i))for l in open(f))for i in range(65,91)]))
Ruby 1.9+, 51 (ou 58 ou 60)
Suppose que tout est en minuscule. L’insensibilité à la casse coûte 7 caractères via
.upcase
, tandis que l’insensibilité à la casse et les minuscules coûtent 9 caractères via.downcase
.la source
R (156, y compris lecture de fichier)
Avec table, je construis la table de fréquence des lettres pour chaque phrase. Ensuite, je finis par prendre pour chaque lettre la valeur maximale.
Ungolfed:
Solution:
la source
a=unlist(lapply(readLines(fn),function(x)table(strsplit(tolower(x),""))));a=tapply(seq(a),names(a),function(i)max(a[i]))[-1];cat(rep(names(a),a),sep="")
, mais ce n'est que 3 caractères plus courtcat(unlist(sapply(letters,function(i)rep(i,max(sapply(gregexpr(i,readLines(f)),function(x)sum(x>0)))))),sep="")
partons du principef
est le nom du fichierHaskell,
109108Le programme lit à partir de stdin et écrit à sdtout.
C'est assez simple: il divise la chaîne en une liste de lignes et la reconstruit en itérant sur la liste et en ajoutant les nouvelles lettres contenues dans chaque ligne.
la source
Perl 6:
5653 caractères;5855 octetsPour chaque ligne, cela passe au peigne fin pour les caractères sans espace de la chaîne (
comb /\S/,.lc
) minuscule , et crée unBag
ou une collection de chaque caractère et son nombre de fois.[∪]
prend l'union duBag
s sur toutes les lignes, ce qui donne le nombre maximum d'occurrences du caractère..pick(*)
hack-y est ici, mais c’est le moyen le plus rapide d’obtenir tous les caractères de laBag
réplique par le nombre de fois où elle s’est produite.EDIT: Pour voir si ce serait plus court, j'ai essayé de traduire la réponse de histocrat à Ruby . C'est 63 caractères, mais j'aime toujours beaucoup l'approche:
la source
Haskell,
183 162159En supposant que le fichier est dans
file.txt
!Si fichier.txt contient, par exemple
Le script va sortir
Fondamentalement, j'ajoute l'alphabet entier à chaque ligne, de sorte que lors du regroupement et du tri, je suis sûr que je vais me retrouver avec une liste contenant 27 éléments. Ensuite, je transpose le "tableau des fréquences", de sorte que chaque ligne de ce tableau se compose des fréquences d'une seule lettre dans chaque ligne, par exemple
["a","","aaa","aa","aaaa"]
. Je choisis ensuite le maximum de chaque tableau (ce qui fonctionne exactement comme je le souhaite en raison du fonctionnement deOrd
-instance of Strings), puis supprime la lettre que j'ai ajoutée au début, supprime les espaces et affiche le résultat.la source
drop 1
, utilisez simplementtail
C, 99 caractères
Il se bloque si moins d'une nouvelle ligne est fournie. Je pense que cela pourrait être résolu assez facilement.
la source
kdb (q / k): 59 caractères:
-1 ajoute une nouvelle ligne, utiliser 1 enregistre un caractère mais ne génère pas la sortie spécifiée. Si seulement je pouvais me débarrasser du passe-partout .z.pi / .z.exit, qui enlèverait 14 caractères.
Edit: évitez d’utiliser inter / asc en utilisant un dictionnaire de base.
la source
Perl, 46
Voici une autre solution Perl, lue dans STDIN, nécessite un
-n
commutateur (+1 pour compter), une égalité avec le score de primo mais fonctionne sans problème :-). Il exploite le fait queor
le résultat de bitwise a une longueur d'argument de chaîne plus longue.la source
J'ajoute ma propre solution:
Bash - 72
Suppose que l'entrée est dans le fichier "i"
Explication
Pour chaque lettre possible, filtre uniquement du fichier d'entrée, ce qui donne un résultat similaire à celui-ci:
Ensuite, le résultat est trié et la ligne la plus longue est sélectionnée.
echo -n
est là pour supprimer les nouvelles lignes.la source
Bash,
171159158, 138 avec sortie indésirableNécessite une entrée en minuscule seulement. Suppose que le fichier est appelé
_
(trait de soulignement). Maximum de 26 lignes dans le fichier d'entrée en raison des noms de fichiers gênants quisplit
créent (xaa, xab ... xaz, ???).Dans
bash
,{a..z}
sortiesa b c d e f ...
.Échantillon de sortie
Explication
Créez des fichiers que nous lirons plus tard pour que bash ne se plaint pas qu'ils n'existent pas. Si vous supprimez cette ligne, vous enregistrez 13 caractères, mais vous obtenez beaucoup de sorties indésirables.
Fractionner le fichier d'entrée en sections, chacune stockant 1 ligne. Les fichiers créés par cette commande sont nommés xaa, xab, xac, etc., je ne sais pas pourquoi.
Pour chaque lettre,
$l
parcourez toutes les lignes stockées dans les fichiersxa$s
.Supprimez le
-s
commutateur pour enregistrer 1 caractère et obtenir beaucoup de sortie indésirable. Cela empêchegrep
de se plaindre de fichiers inexistants (cela se produira sauf si vous avez 26 lignes d’entrée). Cela traite le fichierxa$s
, en supprimant tout sauf les occurrences$l
et en envoyant une sortie au fichierb$l
. Donc, "j'aime maman" devient "mmm" avec de nouvelles lignes après chaque lettre quand$l
est m.Si le nombre de lignes dans le fichier que nous venons de créer est supérieur ou égal à (c.-à-d. Plus de lettres puisqu'il y a une lettre par ligne), le nombre de lignes dans notre résultat le plus élevé jusqu'à présent (stocké dans
$l
) ...... enregistrez notre nouvel enregistrement dans le fichier
$l
. À la fin de cette boucle, lorsque nous avons parcouru toutes les lignes, le fichier$l
stockera x lignes contenant chacune la lettre$l
, x étant le nombre le plus élevé d'occurrences de cette lettre sur une seule ligne.Exportez le contenu de notre fichier pour cette lettre en supprimant les nouvelles lignes. Si vous ne voulez pas supprimer les nouvelles lignes, changez la ligne en
tr
enecho $l
sauvegardant 6 caractères.la source
split
(de coreutils). Je suis actuellement sous GNU bash 4.3.8 et GNU coreutils 8.21 sur Ubuntu 14.04 et cela fonctionne bien (cela fonctionnait également sur Ubuntu 13.10 avant la mise à niveau). Cependant, j'ai dû placer le programme et le fichier d'entrée dans un répertoire distinct pour que tout fonctionne correctement. Je suppose que cela était dû uniquement aux millions de fichiers indésirables de mon dossier personnel .split _ -l1
et vous remarquez que votre entrée est sauvegardée sur-l1aa
, je pense que votre version desplit
ne reconnaît pas l'-l1
option comme une option , mais la considère plutôt comme un préfixe pour la sortie. . Essayez de mettre un espace entre-l
et1
, ou de mettre--lines=1
ou tout simplement-1
(cela semble être une syntaxe obsolète et plus golfy avec laquelle je vais maintenant mettre à jour le post).C #, 172 octets
la source
Python 2 - 129
Idée de @Tal
Quelques autres façons de faire la même chose avec le même nombre de caractères:
Cela suppose que le fichier est enregistré en tant que f dans un répertoire accessible. Ce programme est directement exécutable, sans aucune entrée supplémentaire nécessaire.
la source
Mathematica v10 - 110
Ce n'est pas encore sorti, mais en lisant la nouvelle documentation très attentivement, je pense que cela devrait fonctionner:
la source
Scala, 125 caractères
J'ai d'abord lu l'entrée en la convertissant en minuscule et en ajoutant une ligne vide.
Ensuite, pour chaque lettre de
a
à,z
je répète le nombre maximum de fois que cette lettre apparaît dans l'une des lignes (c'est pourquoi j'ai besoin de la ligne vide:max
ne peut pas être appelée avec une entrée vide). Ensuite, je viens de joindre les résultats et imprimer sur la sortie.Pour lire à partir d'un fichier, remplacez
stdin
parfromFile("FILENAME")
, en augmentant la taille du code à 132 caractères + longueur du nom de fichier.la source
Javascript, 261 caractères
Supprimez le
eval(...)
et exécutez pour obtenir le code réel; c'est ( un peu ) compressé.s
multi-fonctions en tant que tableau de lignes et en tant que chaîne de sortie,h
contient l'histogramme des lettres par ligne etH
contient l'histogramme avec les valeurs maximales jusqu'à présent. Il est insensible à la casse et ignore tout sauf az et AZ (je pense ... les tableaux JS sont parfois bizarres).Maintenant correct :)
la source
@
Je me demandais ce qui se passait jusqu'à la fin. J'aime ça :)JavaScript ( ES5 ) 141 octets
La variable supposée
s
est la chaîne d'entrée sans exigence de vérification de la casse ni sortie de tableau:la source
PowerShell - 141
Lit le texte d'un fichier nommé 'a'.
la source
Groovy,
113/127102/116 caractèresEn supposant que le fichier est dans un cas (102 caractères):
En supposant que le fichier soit en casse mixte (116 caractères):
Fondamentalement:
t=new File('f').text
Pour obtenir le texte du fichier.t.findAll('[A-Z]').unique().sort().each{c->
Pour obtenir les caractères uniques, triez-les et effectuez une itération.print c*t.readLines()*.count(c).max()
Obtenez le maximum d'occurrences sur une seule ligne et imprimez le caractère plusieurs fois.la source
Bash (principalement awk) -
172163157Le texte doit être redirigé vers awk (ou spécifié en tant que fichier).
Exemple d'entrée
Exemple de sortie
PHP (pourrait probablement être mieux) -
174210Suppose que la chaîne est contenue dans la variable $ s
Exemple d'entrée
Exemple de sortie
la source
Je me rends compte que ce n’est probablement pas la solution la plus efficace, mais je voulais quand même essayer de résoudre le problème. Voici ma variante ObjC:
Ensuite, vous pouvez l'appeler pour n'importe quelle chaîne:
Je pensais aux applications avec de plus grandes quantités de texte et je préférerais ne pas avoir à compter mon tableau. Pour cela, j'ai ajouté à la méthode pour obtenir ceci:
Courez comme:
Te donnera:
Ce qui, à mon avis, est préférable si j'ai une très grande quantité de texte et qu'il me suffit de savoir combien de lettres il me faut.
la source
K, 34
la source
Python 2, 154 octets
la source
s
à la fin de laimport
déclaration et lewith
bloc manque d'indentation. Et puisqu'il s'agit d'un code de golf, il vous serait très utile d'éliminer les blancs inutiles dans la mesure du possible.C, 298 octets
Le tableau D contient le décompte des lettres pour chaque ligne, puis le compte maximum est copié dans C.
Remarque: je mets ma réponse hier mais ne figure pas dans la liste. Peut-être ai-je appuyé sur supprimer au lieu de modifier par erreur?
la source
int
fromint main()
etint j,n;
.PHP, 143 octets
En supposant que l'entrée est passée dans la variable
$s
:Explication
Pour chaque lettre possible, je mappe un tableau contenant une liste de chaînes grâce à une fonction définie par l'utilisateur qui remplace chaque ligne par le nombre de caractères utilisés. Pour la lettre 'd', la ligne "Maman aime papa" sera mappée en 3.
Ensuite, je trouve la valeur maximale dans un tableau et une lettre en sortie autant de fois. Voici la version multi-ligne:
la source
Python (209, avec l'échantillon inclus, 136 sans.):
Je posterai un échantillon de PYG cet après-midi.
la source