Tebak cara mengucapkan kata-kata Jerman


37

pengantar

Tidak seperti bahasa Inggris, bahasa Jerman dianggap memiliki sistem penulisan fonemik yang cukup . Itu berarti bahwa korespondensi antara ejaan dan pengucapannya dekat. Mengingat kata apa pun yang tidak Anda kenal, Anda masih tahu cara mengucapkannya karena sistem ejaannya. Ini berarti komputer harus dapat melakukannya juga bukan?

Tantangan

Tulis sebuah program atau fungsi yang mengambil input string yang mewakili kata Jerman, dan mencetak atau mengembalikan pelafalannya dalam International Phonetic Alphabet (IPA) .

Saya tentu saja tidak akan membuat Anda belajar bahasa Jerman atau IPA lengkap . Bagian Wikipedia yang satu ini menyediakan hampir semua aturan Bahasa Jerman ke IPA yang Anda butuhkan, dan saya telah membuat kode implementasi referensi C # yang tidak diklik .

Juga disediakan dalam tautan itu adalah daftar 400 kata Jerman umum dan pelafalan IPA mereka (diperlukan untuk validasi). Mengambil contoh dari daftar itu, jika inputnya adalah solltest, output yang benar adalah ˈzɔltəst.

Implementasi referensi menambahkan dua aturan bermanfaat yang tidak disebutkan di bagian Wikipedia: Ini mengasumsikan tekanan kata ada pada suku kata pertama (sangat mungkin dalam bahasa Jerman), dan menggunakan heuristik yang lebih baik untuk menentukan kapan huruf "e" mewakili schwa sound / ə /. Ini juga mengimplementasikan pemrosesan khusus untuk awalan, tetapi itu tidak meningkatkan hasil sebanyak yang saya pikir akan terjadi.

Detail

Untuk dianggap sebagai entri yang valid, program Anda harus memenuhi persyaratan berikut:

  • Output IPA Anda harus sama persis dengan setidaknya 300 dari 400 kata dalam daftar kata referensi (implementasi referensi mendapatkan 333 benar)
  • Program Anda harus membuat tebakan untuk kata Jerman yang masuk akal. Jadi kami memiliki persyaratan teknis, ini berarti bahwa untuk input apa pun yang cocok dengan regex [a-zA-ZäÄöÖüÜ][a-zäöüß]*dan memiliki setidaknya satu vokal (aeiouyäöü), Anda harus menghasilkan output non-spasi-saja dan tidak kesalahan keluar.
  • Program harus deterministik (selalu menghasilkan output yang sama dengan input yang sama)
  • Kalau tidak, lubang standar dilarang (terutama yang mengambil sumber daya di luar lokasi)

Hal-hal lain yang boleh Anda lakukan:

  • Miliki memimpin dan mengikuti spasi putih di output Anda jika Anda harus
  • Gunakan pengkodean karakter yang sudah ada sebelumnya dalam output (saya tidak bisa membayangkan apa pun selain Unicode bekerja dengan baik, tetapi jika Anda bisa, selamat)
  • Asumsikan input dalam bentuk normal seperti Unicode normalisasi bentuk NFD, NFC, dll. Sebagai contoh, apakah ä ditulis sebagai karakter tunggal atau karakter dasar + karakter kombinasi?
  • Gunakan metode input dan output standar

Karakter Penilaian & IPA

Skor dalam byte. Berhati-hatilah karena karakter Jerman dan karakter IPA adalah 2 byte dalam UTF-8. Selain itu, karakter IPA U + 0327 COMBINING INVERTED BREVE BELOW (̯) adalah karakter kombinasi Unicode dan merupakan karakter 2 byte UTF-8 sendiri. Itu berarti sesuatu seperti ɐ̯ akan dihitung sebagai 4 byte dalam UTF-8. Bagi yang penasaran, simbol ini berarti vokal tidak membentuk inti suku kata (yang sebelumnya bukan).

Waspadalah terhadap karakter IPA ini yang dalam beberapa font terlihat seperti karakter ASCII lainnya: ɡ, ɪ, ʏ, ː (menandai vokal panjang), ˈ (menandai suku kata yang memiliki tekanan dalam kata yang memiliki banyak suku kata).

Bagaimana daftar kata referensi dibuat

Bagian ini adalah info tambahan yang tidak diperlukan untuk tantangan ini.

Daftar kata diambil dari daftar frekuensi kata Wiktionary ini , menghapus pengulangan karena perbedaan casing dan dua kata yang tidak memiliki entri Jerman di Wiktionary bahasa Inggris (oh & hei). IPA berasal dari melihat baik kamus bahasa Inggris maupun Jerman. Ketika banyak pengucapan dilakukan, saya memilih yang lebih formal dan standar. Jika ini tidak jelas, saya memilih yang paling sesuai dengan aturan umum.

Saya juga harus membakukan bagaimana huruf "r" diucapkan. Sangat tergantung pada wilayah bagaimana surat ini diucapkan, dan Wiktionary sama sekali tidak konsisten di mana yang dipilihnya. Saya merasa cenderung ke arah berikut: "r" diucapkan / ɐ̯ / ketika diikuti oleh vokal panjang dan vokal tidak mengikuti, jika tidak, itu adalah ʁ. Jadi, saya mengubah semuanya untuk mengikuti aturan itu, kecuali untuk awalan ver dan er yang cukup konsisten / (f) ɛɐ̯ /. Demikian pula, saya menstandarkan "eu" sebagai / ɔʏ̯ /.


16
Mathematica memiliki bawaan untuk ini ( #~WordData~"PhoneticForm"&), tetapi hanya berfungsi untuk kata-kata bahasa Inggris.
JungHwan Min

29
@JungHwanMin Saya membaca komentar Anda sebagai berikut: Serangan jantung segera, desah lega.
DPenner1

1
Bagaimana saya bisa tahu "gestern" diucapkan "GHES-tern" bukannya "ge-SHTERN"? "bester" sebagai "BEST-er" not "be-SHTER"?
Leaky Nun

@ LeakyNun Tidak ada algoritma 100% untuk ini, tetapi implementasi Anda hanya perlu mendapatkan 75%. Implementasi referensi saya juga salah kata-kata itu.
DPenner1

@ LeakyNun Ya, program Anda juga akan bisa menangani dialek Jerman, jadi lebih kuat.
P. Siehr

Jawaban:


9

PHP, 3311 2988 2916 2845 2759 2671 2667 2509 2484 byte, melampaui 301/400

<?$f=fopen(__FILE__,r);fseek($f,__COMPILER_HALT_OFFSET__);eval(strtr(stream_get_contents($f),[F=>'=>',M=>'==','&'=>'&&',H=>'function ',A_=>'array',G=>'if',4=>'for','|'=>'||','~'=>'))','%'=>str,7=>'=$',8=>'[]',9=>'!$','@'=>'count(','#'=>';$',5=>'return ',3=>':(']));__halt_compiler();define(J,[ieh,ah,aa,Ah,eh,ee,ie,ih,oh,oo,Oh,uh,Uh,au,eu,Au,ei,ai,ey,ay,a,e,i,o,u,A,O,U,y])#b7e=8;Hv($a){5in_A_($a,J);}Hn($a){5!v($a);}Hpronounce($w){global$b,$e#w=%tr(%tolower(%tr($w,[ßF1,ÄF2,äF2,ÖF0,öF0,ÜF6,üF6]~,[1FS,2FA,0FO,6FU])#W=8#L7w;while($L)4each(A__merge([tzsch,dsch,tsch,zsch,sch,chs,ch,ck,dt,ng,nk,pf,ph,qu,ss,th,tz,b,c,d,f,g,h,j,k,l,m,n,p,r,s,S,t,v,w,x,z],J)as$c){$l=%len($c);G(sub%($L,0,$l)M$c){$W87c#L=sub%($L,$l);break;}}$s=8#l=@$W);4($o7t7i=0#i<$l#i++){$c7W[$i]#p7i?$W[$i-1]:0#n7iM$l-1?0:$W[$i+1];G(9n|!(n($c)&$cM$n&n($W[$i+2]~)$s[$o]87c;G($p&((9n&v($c)&n($p~|(n($n)&v($W[$i+2]~~$s[++$o]=8;}$s[@$s)-1]|A__pop($s);4each($s as$z){$b87t#t+=@$z)#e87t;}$o=[sieFziQ,duFduQ,'die'FdiQ,derFdeQT,zuFtsuQ,wirFviQT,mirFmiQT,denFdeQn,dassFdas,erFeQT,soFzoQ,warFvaQT,fürFfyQT,jaFjaQ,wieFviQ,dirFdiQT,nurFnuQT,demFdeQm,ihnFiQn,auchFaUBx,ihrFiQT,daFdaQ,schonFʃoQn,wennFvEn,malFmaQl,gutFguQt,nachFnaQx,willFvIl,mussFmUs,habFhaQp,vorFfoQT,ihmFmiQm,tunFtuQn][$w]?:'';G($o)goto x#P7B7S7V7Z=0;@$s)>1&$o=[verFfET,daFda,geFgC][join($s[0])]#o&$P=1&A__shGt($s);(($P|@$s)M2)&$o.=W)|(@$s)>2&$d=1&$h=(int)@$s)/2)#w=A__merge(...$s);4each($w as$l){G(0<$S--)continue#n7w[$B+1]#p7w[$B-1]#f=''#Z+=in_A_($B,$b)#f7lMd&9n?t3$lMb&(9n|$nMt)?p3$lMg&(9n|$nMt)?((9n&$pMi)?K:k)3$lMc?(($nMA|$nMe|$nMi)?ts:k)3$lMch?(($pMa|$pMo|$pMu)?x:K)3$lMchs|$lMx?ks3$lMck?k3$lMdsch?dZ3$lMdt|$lMth?t3$lMph|$lMv?f39f&$lMg?g3$lMh?(v($n)?h:'')3$lMng?N3$lMnk?Nk3$lMqu?kv3$lMr?((!v($n)&9nMt)?T:R)3$lMsch?S3$lMss|$lMS?s3$lMtsch|$lMtzsch|$lMzsch?tS3$lMtz|$lMz?ts3$lMw?v3$lMs?(9p&($nMp|$nMt~?S3v($n)?z:s):$f~~~~~~~~~~)#U=0;G(v($l~{G(%len($l)>1)($f=[auFaUB,euFcYB,eiFaIB][$l])|$U=1;else{G(n($n)&((9w[$B+2]&$n!=n)|v($w[$B+2]~)$U=1;G($lMe){$U=9n?:$U;G(9w[$B+2]){G($nMr)($f=A)&$U=9S=1;G($nMm|$nMl)$f=C;}}elseG($nMch)$U=0;G(in_A_($B,$e~$U=0;}$f=($U|9Z)&9f?($l[0]MO?D3$l[0]MU?y3$l[0]MA?E:$l[0]~).Q39f?($lMe?((9n|(9w[$B+2]&($nMn|$nMs~)?C:E)3$lMA?E3$lMi?I3$lMo?c3$lMu?U3($lMU|$lMy)?Y:$l~~~:$f)#V++;}$f7f?:$l;G($d&$ZM$h)$f.=W#o.7f#B++;}G(%pos($o,W)M=false&$V>1)$o=W.$o;4(#j++<%len($o);)G($o[$j]M$o[$j+1])$o=sub%($o,0,$j).sub%($o,$j+1);x:5%tr($o,[SFʃ,ZFʒ,KFç,gFɡ,NFŋ,QF'ː',WFˈ,TFɐ̯,BF'̯',RFʁ,AFɐ,EFɛ,OFœ,IFɪ,YFʏ,UFʊ,cFɔ,CFə,DFø]);}

Mendefinisikan pronounce(string $word).

Pemakaian:

assert(
    pronounce('darüber') == "daˈʁyːbɐ"
);

Satu catatan: 3 awalan dan 33 kata adalah kode-keras, dan beberapa kode dioptimalkan secara ringan menuju daftar pengujian.

Kode pengujian ada di sini , meskipun tergantung pada file ini .

Untuk menguji:

php test.php all

Didukung oleh air mata pernyataan ternary.

EDIT 7 : Diperas ~ 170 byte dengan menulis preprocessor ke dalam program. Akibatnya, program yang sebenarnya (semuanya setelahnya __halt_compiler();) agak sulit dibaca. Jika Anda ingin program yang tidak diproses, beralihlah evaldengan printpernyataan ketiga.


Ini sebenarnya 2667 byte, bukan 2671 (dengan asumsi UTF-8)
caird coinheringaahing
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.