Sebuah Mnemonic untuk Mengingat 23940

19

Sistem utama adalah perangkat mnemonik untuk mengubah angka menjadi kata-kata sehingga dapat dihafal lebih mudah.

Ini didasarkan pada bagaimana kata-kata terdengar secara fonetis, tetapi untuk membuat hal-hal sederhana untuk tantangan kita hanya akan peduli dengan bagaimana kata-kata dieja. Ini berarti akan ada beberapa konversi yang salah, tetapi tidak apa-apa.

Untuk mengonversi angka menjadi kata menggunakan sistem utama kami yang disederhanakan:

  • Ganti masing 0- masing dengan satau z. (Beberapa bisa jadi sdan ada yang bisa z. Sama juga di bawah.)
  • Mengganti setiap 1dengan tatau datau th.
  • Ganti masing 2- masing dengan n.
  • Ganti masing 3- masing dengan m.
  • Ganti masing 4- masing dengan r.
  • Ganti masing 5- masing dengan l.
  • Mengganti setiap 6dengan jatau shatau ch.
  • Mengganti setiap 7dengan katau catau gatau q.
  • Ganti masing 8- masing dengan fatau v.
  • Ganti masing 9- masing dengan patau b.
  • Tambahkan huruf aehiouwxymana saja dalam jumlah berapa pun untuk membuat kata bahasa Inggris yang nyata, jika memungkinkan .
    Satu-satunya pengecualian adalah yang hmungkin tidak dimasukkan setelah satau c.

Jumlahnya mungkin sebenarnya adalah string angka 0-9 (tidak ada desimal atau koma atau tanda).
Kata hanya dapat berisi huruf kecil az.

Contohnya

Nomor tersebut 32harus dikonversi sebagai ?m?n?, di mana ?merupakan string terbatas yang dibuat dari huruf-huruf aehiouwxy(string dari monoid gratis jika Anda mau). Ada banyak cara ini bisa dibuat menjadi sebuah kata bahasa Inggris yang nyata: mane, moon, yeoman, dll

Jumlahnya 05dapat dikonversi sebagai ?s?l?atau ?z?l?. Beberapa kemungkinan adalah easily, hassle, dan hazel. Kata shawlitu tidak diizinkan karena htidak boleh ditempatkan setelah s; itu akan salah dibaca sebagai 65.

Tantangan

Tulis program atau fungsi yang mengambil string angka 0-9 dan temukan semua kata yang dapat dikonversi menjadi menggunakan mnemonic sistem utama yang disederhanakan.

Program Anda memiliki akses ke file teks daftar kata yang mendefinisikan apa semua kata bahasa Inggris "asli". Ada satu kata az huruf kecil pada setiap baris file ini, dan Anda dapat mengasumsikan memiliki baris tambahan. Berikut adalah daftar kata-kata nyata yang dapat Anda gunakan untuk pengujian. Anda dapat menganggap file daftar kata ini disebut f(atau sesuatu yang lebih panjang) dan terletak di direktori yang sesuai.

Untuk penalti 35 byte (tambahkan 35 ke skor Anda), Anda dapat menganggap daftar kata sudah dimasukkan ke dalam variabel sebagai daftar string. Ini terutama untuk bahasa yang tidak dapat membaca file, tetapi pengiriman apa pun dapat memanfaatkannya.

Program Anda harus menampilkan semua kata dalam daftar kata yang dapat dikonversi menjadi nomor input. Mereka harus dicetak ke stdout (atau serupa), satu per baris (dengan baris tambahan opsional), atau mereka dapat dikembalikan sebagai daftar string jika Anda memilih untuk menulis suatu fungsi. Daftar kata tidak harus berdasarkan abjad dan hasilnya tidak perlu salah.

Jika tidak ada kata yang mungkin maka output (atau daftar) akan kosong. Outputnya juga kosong jika string kosong dimasukkan.

Ambil input melalui stdin, baris perintah, atau sebagai argumen string ke suatu fungsi. Daftar kata, atau nama file-nya, tidak boleh menjadi bagian dari input, hanya string digit.

Anda hanya mencocokkan satu kata dalam daftar kata, bukan urutan kata. Kata noonitu mungkin akan menjadi salah satu hasil untuk 22, tetapi urutan kata no onetidak.

Uji Kasus

Misalkan ini adalah daftar kata:

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

Masukan 0123456789harus memberikan semua kata yang panjang kecuali zdnmrlshchvbdan shthnmrlchgvb:

stnmrljkfp
zthnmrlshqfb
asatanamaralajakafapa
aizxydwwwnhimouooraleshhhcavabe
zdnmrlshcvb
sthnmrlchgvb

Masukan 99harus memberi:

bob
pop
bop
bopy

(Kata-kata keluaran mungkin dalam urutan apa pun.)

Mencetak gol

Pengajuan terpendek dalam byte menang. Tiebreaker pergi ke kiriman yang diposting terlebih dahulu.

Situs bagus terkait: numzi.com .

Hobi Calvin
sumber
1
Apakah Anda mendapatkan ide untuk tantangan ini dari video ini ? Karena saya sebenarnya baru menontonnya kemarin. : P
Doorknob
1
@ Doorknob Bukan video itu, tapi pria itu. Bertahun-tahun yang lalu saya diberikan salah satu kuliah Great Course-nya . Dia agak lucu tetapi melakukan hal-hal yang sangat rapi. :)
Calvin Hobbies
1
Catatan untuk mereka yang tertarik menggunakan sistem utama mnemonic dalam kehidupan nyata: hanya suara yang penting, bukan ejaan. Jadi "c", sementara terdaftar di sini sebagai makna 7, sebenarnya bisa berarti 0 jika dalam kata itu diucapkan dengan suara "s" (seperti dalam "ace" = 0). Namun, saya yakin bahwa OP menyederhanakan tantangan, karena kamus dengan fonetik lengkap jauh lebih sulit didapat daripada daftar kata sederhana. Oh, dan satu rendering 23940 adalah "angka".
ErikE
@ErikE Saya menyatakan bahwa kami menggunakan versi berbasis ejaan dalam kalimat kedua dari pos ...
Calvin Hobbies
Saya melihat itu sekarang, meskipun saya memang merindukannya pada awalnya - tetapi bagi saya kelihatannya penjelasan Anda dapat disempurnakan sedikit lagi dan contoh atau dua disediakan.
ErikE

Jawaban:

6

Perl, 87 84

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

Mengambil input sebagai parameter baris perintah:

$perl m.pl 23940

Dapat dibuat agak lebih pendek jika daftar kata akan diizinkan pada input standar:

$perl -lnE'INIT{$;=pop}$;eq s/[cs]h/j/gr=~y/stnmrljkfpzdcgqvba-z/0-90177789/dr&&say' 99 <f
nutki
sumber
Apa Aartinya ini open A,f?
feersum
@feersum Pegangan file yang digunakan nanti untuk membaca file ( <A>).
nutki
4

Python 2, 215 208 byte

Solusi Python ini membangun regex dari bagian-bagian yang diindeks oleh argumen baris perintah, kemudian menguji setiap kata dengan regex (yang agak besar) itu.

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

Sumber asli sebelum 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

Sebagai contoh, regex untuk tes 99ini adalah:

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

The (?<![sc])hbit adalah "tampilan belakang pernyataan negatif" komponen yang membuat yakin htidak mengikuti satau cdi bagian filler umum.

Terima kasih Calvin. Tantangan ini memotivasi saya untuk meningkatkan keterampilan regex saya yang berkarat.

Ksatria Logika
sumber
b=c='((?<![sc])h|[aeiouwxy])*'akan menghemat dua byte.
matsjoyce
t|th -> th?menghemat byte
Sp3000
Anda dapat menghindari peta dengan mengambil int (i) secara langsung.
xnor
Terima kasih matsjoyce, Sp3000, dan xnor untuk tips golf yang berguna. Sekarang diedit dengan saran diimplementasikan.
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='')

Versi yang dapat dibaca:

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

Kode memanfaatkan fakta yang thberlebihan (karena memetakan ke nomor yang sama dengan t, dan hmerupakan karakter padding).

Fungsi statis maketransmembuat tabel yang memetakan karakter dari argumen pertama ke argumen kedua, dan karakter dari argumen ketiga None(yang akan mengakibatkan karakter tersebut dihapus).

Kode akhir dapat dibuat beberapa byte lebih pendek dengan membuat tabel sebagai argumen langsung translate.

ekhumoro
sumber
Anda dapat menyimpan beberapa byte menggunakan input () alih-alih sys.argv [1] dan '[sc] h' untuk ekspresi reguler Anda.
swstephe
@swstephe. Terima kasih atas umpan baliknya, tapi saya rasa tidak input()bisa digunakan, karena itu disebut di dalam loop. Juga, regex yang Anda sarankan memiliki panjang yang sama dengan yang sudah saya gunakan (5 byte).
ekhumoro
Saya sedang memikirkan sesuatu seperti "z, t = input (), str.maketrans ...", lalu gunakan saja z alih-alih sys.argv. Oke, saya pikir regex saya adalah 4-byte.
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

Membawa file "w", mengonversi setiap kata menjadi nomornya, menempel kembali ke aslinya, menerima nomor dan mengembalikan kata yang cocok. Perhatikan bahwa spasi putih setelah kutipan setelah grep adalah tab, pembatas default pasta.

Saya tahu Perl jauh di depan, hanya ingin versi shell yang lebih baik sebagai contoh.

Oh yeah, bagian $ 1 berarti bahwa ini seharusnya dijalankan dari skrip shell, (sebagian besar shell seharusnya berfungsi), jadi dibutuhkan argumen baris perintah.

swstephe
sumber
Saya sedang berpikir tentang mengubah jawaban saya menjadi murni seduntuk menghindari buka dan @ARGVoverhead Perl , tetapi kurangnya rentang dan menghapus fungsi dalam y///istirahat itu. Anehnya meskipun meskipun tidak ada variabel yang dapat mengekspresikan logika itu sendiri langsung di sed. Inilah solusi 92 saya:sed -e'h;s/[sc]h/6/g;y/sztdnmrljkcqgfvpb/00112345677778899/;s/[^0-9]*//g;T;s/^$1$//;x;t;d' f
nutki
Tampaknya berhasil, mengapa tidak menjawabnya?
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
  • Daftar kata dalam file bernama w
  • Yang paling dalam sedmenggantikan digit dengan kemungkinan penggantiannya
  • The eval printfpenggunaan shell ekspansi penjepit untuk memperluas semua substitusi yang mungkin
  • Yang kedua sedpada baris pertama menghapus aeiouwxydan h(ketika tidak didahului oleh [sc]) dari daftar kata
  • Grep mencetak semua kecocokan, dengan nomor baris
  • Karena kami telah menghapus aeiouwxydan hdari daftar kata, yang terakhir sedmengubah hasil grep (nomor baris setiap pertandingan) ke sedekspresi lain , yang diproses oleh bagian terluar seduntuk mengungkapkan semua kata yang mungkin dari daftar kata.

Keluaran:

File daftar kata ditentukan sebagai argumen baris perintah, diikuti oleh nomor yang akan di-mnemonisasi:

ubuntu@ubuntu:~$ ./numzi.sh 99
bob
pop
bop
bopy
boppy
$ ./numzi.sh 0123456789
stnmrljkfp
zthnmrlshqfb
asatanamaralajakafapa
aizxydwwwnhimouooraleshhhcavabe
zdnmrlshcvb
sthnmrlchgvb
$ 
Trauma Digital
sumber
@ CalvinHobbies Selesai.
Trauma Digital
Sepertinya Anda lupa memperbarui contoh Anda.
Calvin Hobbies
-1

tr, sed, grep, xargs, sh, 77

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

Berharap nomor dalam stdin dan daftar kata harus disimpan dalam file f.

Tidak menggunakan semua penggantian (1 akan selalu menjadi z, 7 akan selalu menjadi k), jadi ini mungkin disebut solusi malas, tetapi ia menemukan setidaknya satu mnemonik untuk 95 angka dalam [1-100].

pgy
sumber
3
Pertanyaannya menanyakan apakah Anda menemukan semua kata yang cocok dalam daftar kata. Anda tidak bisa membuat 1selalu zatau 7selalu k. Ini tidak valid.
Calvin Hobbies
Cukup adil, saya akan menghapus jawaban saya.
pgy