Mnemonik dla zapamiętywania 23940

19

Główny układ jest pamięciowy urządzenia do przekształcania numerów słowami, więc mogą być zapamiętane łatwiej.

Opiera się na tym, jak słowa brzmią fonetycznie, ale aby uprościć sprawę, zajmiemy się tylko pisownią słów. Oznacza to, że będą jakieś nieprawidłowe konwersje, ale to w porządku.

Aby przekonwertować liczbę na słowo za pomocą naszego uproszczonego systemu głównego:

  • Wymień każdy 0z slub z. (Niektóre mogą być, sa niektóre mogą z. To samo idzie poniżej.)
  • Zamień 1je na tlub dlub th.
  • Wymień każdy 2z n.
  • Wymień każdy 3z m.
  • Wymień każdy 4z r.
  • Wymień każdy 5z l.
  • Zamień 6je na jlub shlub ch.
  • Zamień 7je na klub club glub q.
  • Wymień każdy 8z flub v.
  • Wymień każdy 9z plub b.
  • Dodaj litery w aehiouwxydowolnym miejscu w dowolnych ilościach, aby, jeśli to możliwe, stworzyć prawdziwe angielskie słowo .
    Jedynym wyjątkiem jest to, że hnie można wstawić po slub c.

Liczba może być w rzeczywistości dowolnym ciągiem cyfr od 0 do 9 (brak miejsc po przecinku, przecinki lub znaki).
Słowo może zawierać tylko małe litery az.

Przykłady

Liczbę 32należy przekonwertować jako ?m?n?, gdzie ?reprezentuje dowolny skończony ciąg wykonany z liter aehiouwxy(ciąg z wolnej monoidy, jeśli wolisz). Istnieje wiele sposobów, to może być wykonane do prawdziwego angielskiego słowa: mane, moon, yeoman, itd.

Liczba 05może być przekonwertowana jako ?s?l?lub ?z?l?. Niektóre możliwości są easily, hasslei hazel. Słowo shawljest niedozwolone, ponieważ hnie może zostać umieszczone po s; byłby błędnie odczytany jako 65.

Wyzwanie

Napisz program lub funkcję, która pobiera ciąg cyfr 0–9 i znajdzie wszystkie słowa, na które można by je przekonwertować, używając uproszczonego głównego systemu mnemonicznego.

Twój program ma dostęp do pliku tekstowego z listą słów, który określa, jakie są wszystkie „prawdziwe” angielskie słowa. W każdym wierszu tego pliku znajduje się jedno małe słowo az, a opcjonalnie można założyć, że ma on końcowy znak nowej linii. Oto lista prawdziwych słów, których możesz użyć do testowania. Możesz założyć, że ten plik listy słów nazywa się f(lub coś dłuższego) i znajduje się w dowolnym wygodnym katalogu.

W przypadku kary 35 bajtów (dodaj 35 do wyniku) możesz założyć, że lista słów jest już załadowana do zmiennej jako lista ciągów znaków. Dotyczy to głównie języków, które nie potrafią odczytać plików, ale każde przesłanie może z nich skorzystać.

Twój program musi wypisać wszystkie słowa z listy słów, na które można przekonwertować numer wejściowy. Powinny być drukowane na standardowym (lub podobnym), po jednym w wierszu (z opcjonalnym końcowym znakiem nowej linii), lub mogą zostać zwrócone jako lista ciągów, jeśli zdecydujesz się napisać funkcję. Lista słów nie musi być alfabetycznie, a wynik nie musi być.

Jeśli nie ma możliwych słów, wynik (lub lista) będzie pusty. Dane wyjściowe są również puste, jeśli wprowadzono pusty ciąg.

Weź dane wejściowe za pomocą stdin, wiersza poleceń lub jako argument ciągu funkcji. Lista słów lub nazwa pliku nie powinny być częścią wejścia, a jedynie ciąg cyfr.

Pasujesz tylko pojedyncze słowa na liście słów, a nie sekwencje słów. Słowo noonprawdopodobnie będzie jednym z wyników 22, ale sekwencja słów no onenie.

Przypadki testowe

Załóżmy, że jest to lista słów:

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

Wejście 0123456789powinno dać wszystkie z wyjątkiem długich słów zdnmrlshchvbi shthnmrlchgvb:

stnmrljkfp
zthnmrlshqfb
asatanamaralajakafapa
aizxydwwwnhimouooraleshhhcavabe
zdnmrlshcvb
sthnmrlchgvb

Dane wejściowe 99powinny dać:

bob
pop
bop
bopy

(Słowa wyjściowe mogą być w dowolnej kolejności.)

Punktacja

Najkrótsze przesłanie w bajtach wygrywa. Tiebreaker przechodzi do przesłanego posta jako pierwszego.

Powiązana strona: numzi.com .

Hobby Calvina
źródło
1
Czy wpadłeś na pomysł tego wyzwania z tego filmu ? Bo faktycznie tylko obserwował, że wczoraj. : P
Klamka
1
@Doorknob Nie ten film, ale ten facet. Wiele lat temu dostałem jeden z jego wykładów na temat wielkich kursów . Jest trochę szalony, ale robi naprawdę fajne rzeczy. :)
Calvin's Hobbies
1
Uwaga dla osób zainteresowanych używaniem mnemonicznego głównego systemu w prawdziwym życiu: liczy się tylko dźwięk , a nie pisownia. Zatem „c”, choć wymienione tutaj jako znaczenie 7, może w rzeczywistości oznaczać 0, jeśli w słowie jest wymawiane z dźwiękiem „s” (jak w „ace” = 0). Jestem jednak pewien, że OP uprościło wyzwanie, ponieważ słownik z pełną fonetyką jest znacznie trudniejszy do zdobycia niż prosta lista słów. Aha, a jeden rendering z 23940 to „liczby”.
ErikE
@ErikE Oświadczam, że używamy wersji opartej na pisowni w drugim zdaniu wpisu ...
Hobby Calvina
Widzę to teraz, choć na początku mi tego brakowało - ale nadal wydaje mi się, że twoje wyjaśnienie może być jeszcze bardziej szczegółowe i podany przykład lub dwa.
ErikE

Odpowiedzi:

6

Perl, 87 84

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

Pobiera dane wejściowe jako parametr wiersza poleceń:

$perl m.pl 23940

Może być nieco krótszy, jeśli lista słów byłaby dozwolona na standardowym wejściu:

$perl -lnE'INIT{$;=pop}$;eq s/[cs]h/j/gr=~y/stnmrljkfpzdcgqvba-z/0-90177789/dr&&say' 99 <f
nutki
źródło
Co Aoznacza w open A,f?
feersum
@feersum Uchwyt pliku używany później do odczytu pliku ( <A>).
nutki
4

Python 2, 215 208 bajtów

To rozwiązanie Pythona tworzy wyrażenie regularne z części indeksowanych argumentem wiersza poleceń, a następnie testuje każde słowo za pomocą tego (raczej dużego) wyrażenia regularnego.

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

Oryginalne źródło przed minifikatorem:

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

Na przykład wyrażenie regularne testu 99to:

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

Ten (?<![sc])hbit jest komponentem „patrz za asercją negatywną”, który zapewnia, że ​​a hnie następuje pos lub cw ogólnych części wypełniacza.

Dzięki Calvin. To wyzwanie zmotywowało mnie do odświeżenia moich zardzewiałych umiejętności wyrażania regularnego.

Logic Knight
źródło
b=c='((?<![sc])h|[aeiouwxy])*'zapisze dwa bajty.
matsjoyce
t|th -> th?zapisuje bajt
Sp3000,
Możesz uniknąć mapy, biorąc bezpośrednio int (i).
xnor
Dzięki matsjoyce, Sp3000 i xnor za przydatne wskazówki dotyczące gry w golfa. Teraz edytowane z zaimplementowanymi sugestiami.
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='')

Wersja do odczytu:

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

Kod korzysta z faktu, że thjest zbędny (ponieważ odwzorowuje na ten sam numer co ti hjest znakiem dopełniającym).

Funkcja statyczna maketranstworzy tabelę odwzorowującą znaki pierwszego argumentu na znaki drugiego argumentu oraz znaki trzeciego argumentu na None(co spowoduje usunięcie tych znaków).

Ostateczny kod może zostać skrócony o kilka bajtów, tworząc tabelę jako bezpośredni argument translate.

ekhumoro
źródło
Możesz zapisać kilka bajtów, używając input () zamiast sys.argv [1] i „[sc] h” dla wyrażenia regularnego.
swstephe
@swstephe. Dzięki za opinie, ale nie sądzę, że input()można z nich skorzystać, ponieważ nazywa się je w pętli. Ponadto sugerowana regex ma taką samą długość jak ta, której już używam (5 bajtów).
ekhumoro
Myślałem o czymś takim jak „z, t = input (), str.maketrans ...”, a następnie po prostu użyj z zamiast sys.argv. OK, myślałem, że moje wyrażenie regularne ma 4 bajty.
swstephe
2

sed, pasta, grep, cut - 109

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

Pobiera plik „w”, konwertuje każde słowo na jego numer, wkleja z powrotem do oryginału, grep dla liczby i zwraca pasujące słowo. Zauważ, że biały znak po cytacie po grep jest tabulatorem, domyślnym ogranicznikiem wklejania.

Wiem, że Perl jest daleko przed nami, chciałem na przykład lepszej wersji powłoki.

O tak, część 1 $ oznacza, że ​​należy go uruchamiać ze skryptu powłoki (większość powłok powinna działać), więc wymaga argumentu wiersza poleceń.

swstephe
źródło
Myślałem o przekonwertowaniu mojej odpowiedzi na czystą, sedaby uniknąć otwartego i @ARGVnarzutu Perla , ale brak zakresów i funkcji kasowania y///to psuje. Zaskakujące jest jednak to, że mimo braku zmiennych można bezpośrednio wyrazić logikę sed. Oto moje 92 rozwiązanie:sed -e'h;s/[sc]h/6/g;y/sztdnmrljkcqgfvpb/00112345677778899/;s/[^0-9]*//g;T;s/^$1$//;x;t;d' f
nutki
Wydaje się, że działa, dlaczego nie dać odpowiedzi?
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
  • Lista słów w pliku o nazwie w
  • Najbardziej wewnętrzna sedzastępuje cyfry ich możliwymi zamiennikami
  • The eval printf zastosowania powłoki nawiasy rozszerzyć na wszystkie możliwe substytucje
  • Drugi sedw pierwszym wierszu usuwa aeiouwxyi h(jeśli nie jest poprzedzony [sc]) z listy słów
  • Grep drukuje wszystkie dopasowania z numerami linii
  • Ponieważ usunęliśmy aeiouwxyi hz listy słów, ostatni sedzamienia wyniki grep (numery wierszy każdego dopasowania) na inne sedwyrażenie, które jest przetwarzane przez najbardziej zewnętrzne, sedaby odsłonić wszystkie możliwe słowa z listy słów.

Wynik:

Plik listy słów jest określony jako arg wiersza polecenia, po którym następuje liczba mnemoniczna:

ubuntu@ubuntu:~$ ./numzi.sh 99
bob
pop
bop
bopy
boppy
$ ./numzi.sh 0123456789
stnmrljkfp
zthnmrlshqfb
asatanamaralajakafapa
aizxydwwwnhimouooraleshhhcavabe
zdnmrlshcvb
sthnmrlchgvb
$ 
Cyfrowa trauma
źródło
@ Calvin'sHobbies Done.
Cyfrowa trauma
Wygląda na to, że zapomniałeś zaktualizować swój przykład.
Calvin's Hobbies
-1

tr, sed, grep, xargs, sh, 77

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

Oczekuje liczby w stdin, a lista słów powinna być zapisana w pliku f.

Nie używa wszystkich zamienników (1 zawsze będzie z, 7 zawsze będzie k), więc można go nazwać leniwym rozwiązaniem, ale znajduje co najmniej jeden mnemonik dla 95 liczb w [1-100].

pgy
źródło
3
Pytanie wymaga znalezienia wszystkich pasujących słów na liście słów. Nie możesz sprawić, że 1zawsze będziesz zalbo 7zawsze k. To jest nieprawidłowe.
Calvin's Hobbies
W porządku, usunę moją odpowiedź.
pgy