Indovina come pronunciare le parole tedesche


37

introduzione

A differenza dell'inglese, il tedesco è considerato un sistema di scrittura abbastanza fonemico . Ciò significa che la corrispondenza tra ortografia e pronuncia è stretta. Data qualsiasi parola con cui non hai familiarità, sapresti comunque come pronunciare a causa del sistema di ortografia. Questo significa che un computer dovrebbe essere in grado di farlo anche nel modo giusto?

Sfida

Scrivi un programma o una funzione che accetta come input una stringa che rappresenta una parola tedesca e stampa o restituisce la sua pronuncia in International Phonetic Alphabet (IPA) .

Non ho intenzione di farti imparare il tedesco o l'IPA completo . Questa sezione di Wikipedia fornisce quasi tutte le regole da tedesco a IPA necessarie e ho codificato un'implementazione di riferimento C # non controllata .

In questo link è anche incluso un elenco di 400 parole tedesche comuni e la loro pronuncia IPA (necessaria per la convalida). Prendendo un esempio da quell'elenco, se l'input è solltest, l'output corretto è ˈzɔltəst.

L'implementazione di riferimento aggiunge due utili regole non menzionate nella sezione Wikipedia: presuppone che la parola stress sia sulla prima sillaba (molto probabilmente in tedesco) e utilizza una migliore euristica per determinare quando la lettera "e" rappresenta il suono schwa / ə /. Implementa anche l'elaborazione speciale per i prefissi, ma ciò non ha migliorato i risultati tanto quanto pensavo.

Dettagli

Per essere considerato una voce valida, il tuo programma deve soddisfare i seguenti requisiti:

  • L'output IPA deve corrispondere esattamente a almeno 300 delle 400 parole nell'elenco delle parole di riferimento (l'implementazione di riferimento ottiene 333 corretti)
  • Il tuo programma deve fare un'ipotesi per qualsiasi parola plausibilmente tedesca. Quindi abbiamo un requisito tecnico, questo significherà che per qualsiasi input che corrisponda al regex [a-zA-ZäÄöÖüÜ][a-zäöüß]*e abbia almeno una vocale (aeiouyäöü), è necessario produrre output non solo per gli spazi bianchi e non errori.
  • Il programma deve essere deterministico (produce sempre lo stesso output dato lo stesso input)
  • Altrimenti, le scappatoie standard sono vietate (in particolare quella sul recupero delle risorse fuori sede)

Cose varie che ti è permesso fare:

  • Se necessario, inserisci spazi bianchi iniziali e finali nell'output
  • Usa qualsiasi codifica di caratteri preesistente nell'output (non riesco a immaginare niente di diverso da Unicode che funzioni bene, ma se puoi, congratulazioni)
  • Supponiamo che l'input sia in una forma normalizzata come le forme di normalizzazione Unicode NFD, NFC, ecc. Ad esempio, è scritto come un singolo carattere o un carattere di base + un carattere combinato?
  • Utilizzare metodi di input e output standard

Punteggio e personaggi IPA

Il punteggio è in byte. Tieni presente che i caratteri tedeschi e IPA sono 2 byte in UTF-8. Inoltre, il carattere IPA U + 0327 COMBINING INVERTED BREVE SOTTO (̯) è un carattere che combina Unicode ed è un carattere UTF-8 da 2 byte a sé stante. Ciò significa che qualcosa come ɐ̯ conterebbe come 4 byte in UTF-8. Per i curiosi, questo simbolo indica che la vocale non forma il nucleo della sillaba (invece il precedente).

Inoltre, fai attenzione a questi caratteri IPA che in alcuni caratteri assomigliano ad altri caratteri ASCII: ɡ, ɪ, ʏ, ː (segna una vocale lunga), ˈ (segna quale sillaba ha lo stress in una parola multisillaba).

Come è stato creato l'elenco delle parole di riferimento

Questa sezione contiene informazioni extra non necessarie per la sfida.

L'elenco di parole è stato preso da questo elenco di frequenze di parole di Wikizionario , rimuovendo le ripetizioni a causa della differenza di maiuscole e due parole che non avevano voci tedesche nel Wikizionario inglese (oh & hey). L'IPA è stato analizzato dai Wikizionario in inglese e in tedesco. Dove sono state offerte più pronunce, ho scelto quella più formale e standard. Se ciò non fosse chiaro, ho scelto quello più adatto alle regole generali.

Ho anche dovuto standardizzare la pronuncia della lettera "r". Dipende fortemente dalla regione in cui si pronunciava questa lettera, e Wikizionario non era affatto coerente in quale scegliesse. Ho sentito che tendeva verso quanto segue: "r" è pronunciato / ɐ̯ / quando seguito da una vocale lunga e una vocale non segue, altrimenti è ʁ. Quindi, ho cambiato tutti per seguire quella regola, ad eccezione dei ver- e dei prefissi che erano abbastanza coerenti / (f) ɛɐ̯ /. Allo stesso modo, ho standardizzato "eu" come / ɔʏ̯ /.


16
Mathematica ha un built-in per questo ( #~WordData~"PhoneticForm"&), ma funziona solo con parole inglesi.
JungHwan Min,

29
@JungHwanMin Ho letto il tuo commento come segue: attacco cardiaco immediato, sospiro di sollievo.
DPenner1,

1
Come devo sapere che "gestern" è pronunciato "GHES-tern" anziché "ge-SHTERN"? "bester" come "BEST-er" non "be-SHTER"?
Leaky Nun,

@LeakyNun Non esiste un algoritmo al 100% per questo, ma l'implementazione deve solo ottenere il 75%. La mia implementazione di riferimento fa anche sbagliare quelle parole.
DPenner1

@LeakyNun Bene, il tuo programma sarà anche in grado di gestire i dialetti tedeschi, quindi è più potente.
P. Siehr,

Risposte:


9

PHP, 3311 2988 2916 2845 2759 2671 2667 2509 2484 byte, passando 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ø]);}

Definisce pronounce(string $word).

Uso:

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

Una nota: 3 prefissi e 33 parole sono hardcoded e parte del codice è leggermente ottimizzato verso l'elenco dei test.

Il codice di test è qui , anche se dipende da questo file .

Testare:

php test.php all

Alimentato dalle lacrime delle dichiarazioni ternarie.

EDIT 7 : cancellato ~ 170 byte scrivendo un preprocessore nel programma. Di conseguenza, il programma reale (tutto dopo __halt_compiler();) è un po 'difficile da leggere. Se si desidera il programma non elaborato, passare evalcon printnella terza istruzione.


Questo in realtà è 2667 byte, non 2671 (supponendo UTF-8)
caird coinheringaahing
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.