Un mnémonique pour se souvenir 23940


19

Le système principal est un dispositif mnémonique pour convertir des nombres en mots afin qu'ils puissent être mémorisés plus facilement.

Il est basé sur la façon dont les mots sonnent phonétiquement, mais pour garder les choses simples pour le défi, nous ne nous intéresserons qu'à la façon dont les mots sont orthographiés. Cela signifie qu'il y aura des conversions incorrectes, mais ça va.

Pour convertir un nombre en un mot à l'aide de notre système principal simplifié:

  • Remplacez chacun 0par sou z. (Certains pourraient l'être set d'autres pourraient l'être z. Il en va de même ci-dessous.)
  • Remplacez chacun 1par tou dou th.
  • Remplacez chacun 2par n.
  • Remplacez chacun 3par m.
  • Remplacez chacun 4par r.
  • Remplacez chacun 5par l.
  • Remplacez chacun 6par jou shou ch.
  • Remplacez chacun 7par kou cou gou q.
  • Remplacez chacun 8par fou v.
  • Remplacez chacun 9par pou b.
  • Ajoutez les lettres aehiouwxyn'importe où dans n'importe quel montant pour faire un vrai mot anglais, si possible .
    La seule exception est qu'elle hne peut pas être insérée après un sou c.

Le nombre peut en fait être n'importe quelle chaîne des chiffres 0-9 (pas de décimales, ni virgules ni signes).
Le mot ne peut contenir que les lettres minuscules az.

Exemples

Le nombre 32doit être converti comme ?m?n?, où ?représente toute chaîne finie faite à partir des lettres aehiouwxy(une chaîne du monoïde libre si vous préférez). Il y a plusieurs façons cela pourrait être transformé en un vrai mot anglais: mane, moon, yeoman, etc.

Le nombre 05peut être converti en ?s?l?ou ?z?l?. Certaines possibilités sont easily, hassleet hazel. Le mot shawln'est pas autorisé car hil ne peut pas être placé après s; il serait incorrectement lu comme 65.

Défi

Écrivez un programme ou une fonction qui prend une chaîne de chiffres 0 à 9 et trouve tous les mots dans lesquels il pourrait être converti en utilisant la mnémonique simplifiée du système principal.

Votre programme a accès à un fichier texte de liste de mots qui définit ce que sont tous les "vrais" mots anglais. Il y a un mot az en minuscules sur chaque ligne de ce fichier, et vous pouvez éventuellement supposer qu'il a une nouvelle ligne de fin. Voici une liste de vrais mots que vous pouvez utiliser pour les tests. Vous pouvez supposer que ce fichier de liste de mots est appelé f(ou quelque chose de plus long) et se trouve dans n'importe quel répertoire pratique.

Pour une pénalité de 35 octets (ajoutez 35 à votre score), vous pouvez supposer que la liste de mots est déjà chargée dans une variable en tant que liste de chaînes. C'est principalement pour les langues qui ne peuvent pas lire les fichiers, mais toute soumission peut en profiter.

Votre programme doit sortir tous les mots de la liste de mots dans lesquels le numéro d'entrée peut être converti. Ils doivent être imprimés sur stdout (ou similaire), un par ligne (avec un retour à la ligne facultatif), ou ils peuvent être renvoyés sous forme de liste de chaînes si vous choisissez d'écrire une fonction. La liste de mots n'est pas nécessairement alphabétique et la sortie n'a pas besoin d'être non plus.

S'il n'y a pas de mots possibles, la sortie (ou la liste) sera vide. La sortie est également vide si la chaîne vide est entrée.

Prenez l'entrée via stdin, la ligne de commande ou comme argument de chaîne pour une fonction. La liste de mots ou son nom de fichier ne doit pas faire partie de l'entrée, uniquement la chaîne de chiffres.

Vous ne faites correspondre que des mots simples dans la liste de mots, pas des séquences de mots. Le mot noonserait probablement l'un des résultats pour 22, mais pas la séquence de mots no one.

Cas de test

Supposons que ce soit la liste de mots:

stnmrljkfp
zthnmrlshqfb
asatanamaralajakafapa
aizxydwwwnhimouooraleshhhcavabe
zdnmrlshcvb
zdnmrlshchvb
sthnmrlchgvb
shthnmrlchgvb
bob
pop
bop
bopy
boppy

L'entrée 0123456789doit donner tous les mots longs sauf zdnmrlshchvbet shthnmrlchgvb:

stnmrljkfp
zthnmrlshqfb
asatanamaralajakafapa
aizxydwwwnhimouooraleshhhcavabe
zdnmrlshcvb
sthnmrlchgvb

L'entrée 99doit donner:

bob
pop
bop
bopy

(Les mots de sortie peuvent être dans n'importe quel ordre.)

Notation

La soumission la plus courte en octets l' emporte. Tiebreaker passe à la soumission publiée en premier.

Site lié à Nifty: numzi.com .


1
Avez-vous trouvé l'idée de ce défi dans cette vidéo ? Parce que je viens de regarder ça hier. : P
Poignée de porte

1
@ Doorknob Pas cette vidéo, mais ce type. Il y a des années, on m'a donné une de ses conférences Great Courses . Il est un peu loufoque mais fait des trucs vraiment sympas. :)
Calvin's Hobbies

1
Remarque pour ceux qui souhaitent utiliser le système majeur mnémonique dans la vie réelle: c'est seulement le son qui compte, pas l'orthographe. Ainsi, "c", bien qu'indiqué ici comme signifiant 7, pourrait en fait signifier 0 si dans le mot il est prononcé avec un son "s" (comme dans "ace" = 0). Cependant, je suis sûr que l'OP a simplifié le défi, car un dictionnaire avec une phonétique complète est beaucoup plus difficile à trouver qu'une simple liste de mots. Oh, et un rendu de 23940 est "nombres".
ErikE

@ErikE Je déclare que nous utilisons une version basée sur l'orthographe dans la deuxième phrase de l'article ...
Calvin's Hobbies

Je le vois maintenant, même si je l'ai manqué au début - mais il me semble toujours que votre explication pourrait être étoffée un peu plus et un ou deux exemples fournis.
ErikE

Réponses:


6

Perl, 87 84

open A,f;"@ARGV"eq s/[cs]h/j/gr=~y/stnmrljkfpzdcgqvb\0-z/0-90177789/dr&&print for<A>

Prend l'entrée comme paramètre de ligne de commande:

$perl m.pl 23940

Peut être raccourci un peu si la liste de mots est autorisée sur l'entrée standard:

$perl -lnE'INIT{$;=pop}$;eq s/[cs]h/j/gr=~y/stnmrljkfpzdcgqvba-z/0-90177789/dr&&say' 99 <f

Qu'est - ce que Amoyenne en open A,f?
feersum

@feersum Un descripteur de fichier utilisé plus tard pour lire le fichier ( <A>).
nutki

4

Python 2, 215 208 octets

Cette solution Python construit une expression régulière à partir des parties indexées par l'argument de ligne de commande, puis teste chaque mot avec cette expression régulière (plutôt grande).

import re,sys
a='[sz] (d|th?) n m r l (j|sh|ch) [kcgq] [fv] [pb]'.split()
b=z='((?<![sc])h|[aeiouwxy])*'
for i in sys.argv[1]:b+=a[int(i)]+z
for d in open('f'):
 d=d.strip()
 if re.match('^'+b+'$',d):print d

Source d'origine avant la minifiante:

import re,sys
regexbits = '[sz] (d|th?) n m r l (j|sh|ch) [kcgq] [fv] [pb]'.split()

regex = other = '((?<![sc])h|[aeiouwxy])*'
for i in sys.argv[1] :
    regex += regexbits[int(i)] + other
print regex     # DEBUG

for word in open('f'):
    word = word.strip()
    if re.match('^'+regex+'$', word) :
        print word

Par exemple, l'expression régulière du test 99est:

^((?<![sc])h|[aeiouwxy])*[pb]((?<![sc])h|[aeiouwxy])*[pb]((?<![sc])h|[aeiouwxy])*$

Le (?<![sc])hbit est un composant "regardez derrière l'assertion négative" qui s'assure qu'un hne suit pas uns ou cdans les pièces de remplissage générales.

Merci Calvin. Ce défi m'a motivé à perfectionner mes compétences en expression régulière rouillée.


b=c='((?<![sc])h|[aeiouwxy])*'sauvera deux octets.
matsjoyce

t|th -> th?enregistre un octet
Sp3000

Vous pouvez éviter la carte en prenant directement int (i).
xnor

Merci à matsjoyce, Sp3000 et xnor pour leurs conseils utiles sur le golf. Maintenant édité avec des suggestions implémentées.
Logic Knight

2

Python 3, 170

import sys,re
t=str.maketrans('sztdnmrljkcgqfvpb','00112345677778899','aehiouwxy\n')
for s in open('f'):re.sub('sh|ch','j',s).translate(t)!=sys.argv[1] or print(s,end='')

Version lisible:

import sys, re

table = str.maketrans('sztdnmrljkcgqfvpb', '00112345677778899', 'aehiouwxy\n')

for line in open('f'):
    line = re.sub('sh|ch', 'j', line)
    if line.translate(table) == sys.argv[1]:
        print(line, end='')

Le code utilise le fait qui thest redondant (car il correspond au même nombre que t, et hest un caractère de remplissage).

La maketransfonction statique crée une table mappant les caractères du premier argument à ceux du deuxième argument et les caractères du troisième argument à None(ce qui entraînera la suppression de ces caractères).

Le code final pourrait être raccourci de quelques octets en créant la table comme argument direct de translate.


Vous pouvez enregistrer quelques octets en utilisant input () au lieu de sys.argv [1] et '[sc] h' pour votre expression régulière.
swstephe

@swstephe. Merci pour la rétroaction, mais je ne pense pas qu'elle input()puisse être utilisée, car elle est appelée dans une boucle. En outre, votre regex suggéré est de la même longueur que celui que j'utilise déjà (5 octets).
ekhumoro

Je pensais à quelque chose comme "z, t = input (), str.maketrans ...", puis utilisez simplement z au lieu de sys.argv. D'accord, je pensais que mon expression régulière était de 4 octets.
swstephe

2

sed, coller, grep, couper - 109

sed -e 's/[sc]h/6/g;s/[aehiouwxy]//g;y/sztdnmrljkcqgfvpb/00112345677778899/' w|paste w -|grep " $1$"|cut -f1

Prend un fichier "w", convertit chaque mot en son numéro, collez-le dans l'original, recherchez le numéro et renvoyez le mot correspondant. Notez que l'espace après la citation après grep est un onglet, le délimiteur par défaut de coller.

Je sais que Perl est en avance, je voulais juste une meilleure version shell comme exemple.

Oh oui, la partie $ 1 signifie que cela est censé être exécuté à partir d'un script shell, (la plupart des shells devraient fonctionner), donc cela prend un argument de ligne de commande.


Je pensais à convertir ma réponse en pure sedpour éviter l'ouverture et la @ARGVsurcharge de Perl , mais le manque de plages et de fonctions de suppression le y///rompt. Étonnamment, même s'il n'y a pas de variables, vous pouvez exprimer directement la logique elle-même sed. Voici ma solution 92:sed -e'h;s/[sc]h/6/g;y/sztdnmrljkcqgfvpb/00112345677778899/;s/[^0-9]*//g;T;s/^$1$//;x;t;d' f
nutki

Cela semble fonctionner, pourquoi ne pas en faire une réponse?
swstephe

1

Bash + coreutils, 216

sed -n "$(sed 's/[aeiouwxy]//g
:l
s/\([^sc]\)h/\1/g
tl'<w|grep -nf <(eval printf '%s\\n' `sed 's/0/{s,z}/g
s/1/{t,th,d}/g
y/2345/nmrl/
s/6/{j,sh,ch}/g
s/7/{k,c,g,q}/g
s/8/{f,v}/g
s/9/{p,b}/g'<<<$1`)|sed s/:.\*/p/)" w
  • La liste de mots dans un fichier appelé w
  • Le plus intérieur sedremplace les chiffres par leurs remplacements possibles
  • le eval printf utilisations shell extensions de contreventement pour développer toutes les substitutions possibles
  • La seconde sedsur la 1ère ligne supprime aeiouwxyet h(lorsqu'elle n'est pas précédée de[sc] ) de la liste de mots
  • Le grep imprime toutes les correspondances, avec les numéros de ligne
  • Puisque nous avons supprimé aeiouwxyet hde la liste de mots, le dernier sedtransforme les résultats de grep (numéros de ligne de chaque correspondance) en une autre sedexpression, qui est traitée par le plus sedà l'extérieur pour révéler tous les mots possibles de la liste de mots.

Production:

Le fichier de liste de mots est spécifié comme un argument de ligne de commande, suivi du nombre à mnémoniciser:

ubuntu@ubuntu:~$ ./numzi.sh 99
bob
pop
bop
bopy
boppy
$ ./numzi.sh 0123456789
stnmrljkfp
zthnmrlshqfb
asatanamaralajakafapa
aizxydwwwnhimouooraleshhhcavabe
zdnmrlshcvb
sthnmrlchgvb
$ 

@ Calvin'sHobbies Done.
Digital Trauma

On dirait que vous avez oublié de mettre à jour votre exemple.
Les loisirs de Calvin le

-1

tr, sed, grep, xargs, sh, 77

tr 0123456789 ztnmrljkfp|sed 's/ */[aehiouwxy]*/g'|xargs sh -c 'grep -x $0 f'

Attend le nombre dans stdin et la liste de mots doit être stockée dans le fichier f.

N'utilise pas tous les remplacements (1 sera toujours z, 7 sera toujours k), donc cela peut être appelé une solution paresseuse, mais il trouve au moins un mnémonique pour 95 nombres dans [1-100].


3
La question vous demande de trouver tous les mots correspondants dans la liste de mots. On ne peut pas 1toujours être zou 7toujours k. Ce n'est pas valide.
Calvin's Hobbies

Très bien, je vais retirer ma réponse.
pgy
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.