Eine Mnemonik zum Erinnern an 23940

19

Das Hauptsystem ist eine mnemonic Vorrichtung zur Umwandlung von Zahlen in Worte zu fassen , so dass sie leichter gespeichert werden.

Es basiert darauf, wie Wörter phonetisch klingen, aber um die Dinge für die Herausforderung einfach zu halten, werden wir uns nur damit befassen, wie Wörter geschrieben werden. Dies bedeutet, dass es einige falsche Conversions geben wird, aber das ist in Ordnung.

So konvertieren Sie eine Zahl mit unserem vereinfachten Hauptsystem in ein Wort:

  • Ersetzen Sie jedes 0durch soder z. (Manche könnten sund manche könnten sein z. Dasselbe gilt weiter unten.)
  • Ersetzen Sie jedes 1durch toder doder th.
  • Ersetzen Sie jeweils 2durch n.
  • Ersetzen Sie jeweils 3durch m.
  • Ersetzen Sie jeweils 4durch r.
  • Ersetzen Sie jeweils 5durch l.
  • Ersetzen Sie jedes 6durch joder shoder ch.
  • Ersetzen Sie jedes 7durch koder coder goder q.
  • Ersetzen Sie jedes 8durch foder v.
  • Ersetzen Sie jedes 9durch poder b.
  • Fügen Sie die Buchstaben aehiouwxyan beliebiger Stelle hinzu, um nach Möglichkeit ein echtes englisches Wort zu erhalten .
    Die einzige Ausnahme ist, dass hnicht nach einem soder eingefügt werden darf c.

Die Zahl kann tatsächlich eine beliebige Folge der Ziffern 0-9 sein (keine Dezimalstellen, Kommas oder Zeichen).
Das Wort darf nur die Kleinbuchstaben az enthalten.

Beispiele

Die Zahl 32muss wie folgt konvertiert werden ?m?n?: Dabei handelt es sich ?um eine beliebige endliche Zeichenfolge aus den Buchstaben aehiouwxy(eine Zeichenfolge aus dem freien Monoid, wenn Sie dies vorziehen). Es gibt viele Möglichkeiten , dies zu einem echten englischen Wort gemacht werden könnte: mane, moon, yeomanetc.

Die Nummer 05könnte als ?s?l?oder konvertiert werden ?z?l?. Einige Möglichkeiten sind easily, hassleund hazel. Das Wort shawlist nicht erlaubt, da es hmöglicherweise nicht nachgestellt wird s. es würde falsch als gelesen 65.

Herausforderung

Schreiben Sie ein Programm oder eine Funktion, die eine Zeichenfolge mit den Ziffern 0-9 enthält und alle Wörter findet, in die es mithilfe der vereinfachten Hauptsystem-Mnemonik konvertiert werden könnte.

Ihr Programm hat Zugriff auf eine Wortlistentextdatei, die definiert, was alle "echten" englischen Wörter sind. In jeder Zeile dieser Datei befindet sich ein z-Wort in Kleinbuchstaben, und Sie können optional davon ausgehen, dass es eine nachgestellte neue Zeile enthält. Hier ist eine Liste von echten Wörtern, die Sie zum Testen verwenden können. Sie können davon ausgehen, dass diese Wortlistendatei aufgerufen wird f(oder etwas länger ist) und sich in einem beliebigen Verzeichnis befindet.

Für eine 35-Byte-Strafe (addiere 35 zu deiner Punktzahl) kannst du annehmen, dass die Wortliste bereits als eine Liste von Zeichenfolgen in eine Variable geladen ist. Dies gilt hauptsächlich für Sprachen, die keine Dateien lesen können.

Ihr Programm muss alle Wörter in der Wortliste ausgeben, in die die eingegebene Nummer konvertiert werden kann. Sie sollten auf stdout (oder ähnlich) gedruckt werden, eine pro Zeile (mit einem optionalen abschließenden Zeilenumbruch), oder sie können als Liste von Zeichenfolgen zurückgegeben werden, wenn Sie eine Funktion schreiben möchten. Die Wortliste muss nicht unbedingt alphabetisch sein und die Ausgabe muss auch nicht so sein.

Wenn es keine möglichen Wörter gibt, ist die Ausgabe (oder die Liste) leer. Die Ausgabe ist auch leer, wenn die leere Zeichenfolge eingegeben wird.

Übernehmen Sie die Eingabe über stdin, die Befehlszeile oder als Zeichenfolgenargument für eine Funktion. Die Wortliste oder ihr Dateiname sollte nicht Teil der Eingabe sein, sondern nur die Ziffernfolge.

Sie stimmen nur mit einzelnen Wörtern in der Wortliste überein, nicht mit Wortfolgen. Das Wort noonwäre wahrscheinlich eines der Ergebnisse für 22, aber die Wortfolge no onewürde es nicht.

Testfälle

Angenommen, dies ist die Wortliste:

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

Die Eingabe 0123456789sollte alle langen Wörter außer zdnmrlshchvbund enthalten shthnmrlchgvb:

stnmrljkfp
zthnmrlshqfb
asatanamaralajakafapa
aizxydwwwnhimouooraleshhhcavabe
zdnmrlshcvb
sthnmrlchgvb

Die Eingabe 99sollte geben:

bob
pop
bop
bopy

(Die Ausgabewörter können in beliebiger Reihenfolge sein.)

Wertung

Die kürzeste Übermittlung in Bytes gewinnt. Tiebreaker geht zu dem Beitrag, der zuerst veröffentlicht wurde.

Nifty verwandte Seite: numzi.com .

Calvins Hobbys
quelle
1
Hast du zufällig die Idee für diese Herausforderung aus diesem Video ? Weil ich das gestern gerade gesehen habe. : P
Türklinke
1
@Doorknob Nicht das Video, aber der Typ. Vor Jahren erhielt ich einen seiner Great Courses-Vorträge . Er ist ein bisschen verrückt, macht aber wirklich ordentliche Sachen. :)
Calvins Hobbys
1
Hinweis für diejenigen, die sich für die Verwendung des Mnemonic-Major-Systems im wirklichen Leben interessieren: Es kommt nur auf den Klang an , nicht auf die Schreibweise. Während "c" hier als "7" aufgeführt ist, könnte es tatsächlich 0 bedeuten, wenn es im Wort mit einem "s" -Sound ausgesprochen wird (wie in "ace" = 0). Ich bin mir jedoch sicher, dass das OP die Herausforderung vereinfacht hat, da ein Wörterbuch mit vollständiger Phonetik viel schwieriger zu bekommen ist als eine einfache Wortliste. Oh, und eine Darstellung von 23940 ist "Zahlen".
ErikE
@ErikE Ich gebe an, dass wir im zweiten Satz des Beitrags eine auf Rechtschreibung basierende Version verwenden ...
Calvins Hobbys
Ich sehe das jetzt, obwohl ich es zuerst vermisst habe - aber es scheint mir immer noch, dass Ihre Erklärung nur ein bisschen genauer ausgearbeitet und ein oder zwei Beispiele angeführt werden könnten.
ErikE

Antworten:

6

Perl, 87 84

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

Übernimmt die Eingabe als Befehlszeilenparameter:

$perl m.pl 23940

Kann etwas kürzer gemacht werden, wenn die Wortliste in der Standardeingabe erlaubt wäre:

$perl -lnE'INIT{$;=pop}$;eq s/[cs]h/j/gr=~y/stnmrljkfpzdcgqvba-z/0-90177789/dr&&say' 99 <f
nutki
quelle
Was Abedeutet in open A,f?
Feersum
@feersum Ein Datei-Handle, das später zum Lesen der Datei verwendet wird ( <A>).
Nutki
4

Python 2, 215 208 Bytes

Diese Python-Lösung erstellt einen regulären Ausdruck aus Teilen, die durch das Befehlszeilenargument indiziert werden, und testet dann jedes Wort mit diesem (ziemlich großen) regulären Ausdruck.

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

Originalquelle vor dem Minifier:

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

Der reguläre Ausdruck für den Test 99lautet beispielsweise:

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

Das (?<![sc])hBit ist eine Komponente, die "hinter negative Behauptungen schaut" und sicherstellt, dass a hnicht einem soder cin den allgemeinen Füllerteilen folgt .

Vielen Dank, Calvin. Diese Herausforderung hat mich motiviert, meine rostigen Regex-Fähigkeiten aufzufrischen.

Logik-Ritter
quelle
b=c='((?<![sc])h|[aeiouwxy])*'spart zwei Bytes.
Matsjoyce
t|th -> th?speichert ein Byte
Sp3000
Sie können die Map umgehen, indem Sie direkt int (i) nehmen.
Xnor
Vielen Dank an matsjoyce, Sp3000 und xnor für nützliche Golftipps. Jetzt bearbeitet mit Vorschlägen implementiert.
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='')

Lesbare Version:

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='')

Der Code macht sich die Tatsache thzunutze , dass er redundant ist (da er der gleichen Nummer wie zugeordnet tist und hein Füllzeichen ist).

Die statische maketransFunktion erstellt eine Tabelle, in der die Zeichen des ersten Arguments denen des zweiten Arguments und die Zeichen des dritten Arguments Nonedenen des dritten Arguments zugeordnet werden (wodurch diese Zeichen gelöscht werden).

Der endgültige Code könnte ein paar Bytes kürzer gemacht werden, indem die Tabelle als direktes Argument von erstellt wird translate.

ekhumoro
quelle
Sie könnten ein paar Bytes mit input () anstelle von sys.argv [1] und '[sc] h' für Ihren regulären Ausdruck speichern.
Swstephe
@swstephe. Vielen Dank für die Rückmeldung, aber ich glaube nicht, dass sie input()verwendet werden kann, weil sie in einer Schleife aufgerufen wird. Außerdem hat der von Ihnen vorgeschlagene reguläre Ausdruck dieselbe Länge wie der, den ich bereits verwende (5 Byte).
ekhumoro
Ich dachte mir etwas wie "z, t = input (), str.maketrans ...", dann benutze einfach z anstelle von sys.argv. Okay, ich dachte, mein Regex wäre 4 Bytes.
Swstephe
2

sed, paste, grep, cut - 109

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

Nimmt eine Datei "w", konvertiert jedes Wort in seine Nummer, fügt es wieder in das Original ein, sucht nach der Nummer und gibt das gefundene Wort zurück. Beachten Sie, dass das Leerzeichen nach dem Anführungszeichen nach grep ein Tabulator ist, der Standardbegrenzer für das Einfügen.

Ich weiß, Perl ist weit vorne, wollte nur eine bessere Shell-Version als Beispiel.

Oh ja, der $ 1-Teil bedeutet, dass dies von einem Shell-Skript ausgeführt werden soll (die meisten Shells sollten funktionieren), daher ist ein Befehlszeilenargument erforderlich.

swstephe
quelle
Ich dachte darüber nach, meine Antwort auf pure umzustellen sed, um Perls Offenheit und @ARGVOverhead zu vermeiden , aber das Fehlen von Bereichen und Löschfunktionen macht y///es kaputt. Obwohl es keine Variablen gibt, können Sie die Logik selbst überraschenderweise direkt in ausdrücken sed. Hier ist meine Lösung 92:sed -e'h;s/[sc]h/6/g;y/sztdnmrljkcqgfvpb/00112345677778899/;s/[^0-9]*//g;T;s/^$1$//;x;t;d' f
Nutki
Es scheint zu funktionieren, warum nicht eine Antwort machen?
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
  • Die Wortliste in einer Datei mit dem Namen w
  • Das Innerste sedersetzt Ziffern durch ihre möglichen Ersetzungen
  • Die eval printfverwendet Shell-Klammer-Erweiterungen, um alle möglichen Substitutionen zu erweitern
  • Die zweite sedZeile in der ersten Zeile entfernt aeiouwxyund h(wenn nicht vorangestellt [sc]) aus der Wortliste
  • Das grep druckt alle Übereinstimmungen mit Zeilennummern aus
  • Da wir aus abgestreift haben aeiouwxyund haus der Wortliste, die letzten sedzu Drehungen die Ergebnisse von grep (Zeilennummern jedes Spiel) einen anderen sedAusdruck, der durch die äußerste verarbeitet wird , sedalle möglichen Wörter aus der Wortliste zu offenbaren.

Ausgabe:

Die Wortlistendatei wird als Befehlszeilenargument angegeben, gefolgt von der zu mnemonisierenden Zahl:

ubuntu@ubuntu:~$ ./numzi.sh 99
bob
pop
bop
bopy
boppy
$ ./numzi.sh 0123456789
stnmrljkfp
zthnmrlshqfb
asatanamaralajakafapa
aizxydwwwnhimouooraleshhhcavabe
zdnmrlshcvb
sthnmrlchgvb
$ 
Digitales Trauma
quelle
@ Calvin'sHobbies Fertig.
Digital Trauma
Sie haben anscheinend vergessen, Ihr Beispiel zu aktualisieren.
Calvins Hobbys
-1

tr, sed, grep, xargs, sh, 77

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

Erwartet, dass die Nummer in stdin und die Wortliste in der Datei gespeichert werden f.

Verwendet nicht alle Ersetzungen (1 wird immer z sein, 7 wird immer k sein), so dass es eine träge Lösung genannt werden kann, aber es findet mindestens eine Mnemonik für 95 Zahlen in [1-100].

pgy
quelle
3
Die Frage fordert Sie auf, alle passenden Wörter in der Wortliste zu finden. Man kann nicht 1immer sein zoder 7immer machen k. Dies ist ungültig.
Calvins Hobbys
Fair genug, ich werde meine Antwort entfernen.
Pgy