Devinez comment prononcer des mots allemands


37

introduction

Contrairement à l'anglais, l'allemand est considéré comme ayant un système d'écriture assez phonémique . Cela signifie que la correspondance entre l'orthographe et la prononciation est proche. Si vous connaissez un mot que vous ne connaissez pas, vous sauriez quand même le prononcer à cause du système orthographique. Cela signifie qu'un ordinateur devrait être capable de le faire aussi bien?

Défi

Ecrivez un programme ou une fonction prenant en entrée une chaîne représentant un mot allemand, puis imprimant ou renvoyant sa prononciation dans l' alphabet phonétique international (IPA) .

Je ne vais bien sûr pas vous faire apprendre l'allemand ou l'IPA complète . Cette section Wikipedia contient presque toutes les règles allemandes à IPA dont vous avez besoin, et j'ai codé une implémentation de référence C # non golfée .

Ce lien contient également une liste de 400 mots allemands courants et leur prononciation IPA (nécessaires à la validation). En prenant un exemple de cette liste, si l'entrée est solltest, le résultat correct est ˈzɔltəst.

L'implémentation de référence ajoute deux règles utiles non mentionnées dans la section Wikipedia: Elle suppose que le mot accentue se trouve sur la première syllabe (très probablement en allemand) et utilise une meilleure heuristique pour déterminer quand la lettre "e" représente le son schwa / ə /. Il implémentait également un traitement spécial pour les préfixes, mais cela n'améliorait pas les résultats autant que je ne le pensais.

Détails

Pour être considéré comme une entrée valide, votre programme doit remplir les conditions suivantes:

  • Votre sortie IPA doit correspondre exactement à au moins 300 des 400 mots de la liste des mots de référence (la mise en œuvre de référence obtient 333 correct)
  • Votre programme doit deviner tous les mots vraisemblablement allemands. Nous avons donc une exigence technique: cela signifie que pour toute entrée qui correspond à la regex [a-zA-ZäÄöÖüÜ][a-zäöüß]*et qui a au moins une voyelle (aeiouyäöü), vous devez produire une sortie ne contenant pas d’espace, et non une sortie d’erreur.
  • Le programme doit être déterministe (toujours produire la même sortie pour la même entrée)
  • Autrement, les échappatoires standard sont interdites (en particulier celle concernant l'extraction de ressources hors site)

Diverses choses que vous êtes autorisé à faire:

  • Avoir des espaces de début et de fin dans votre sortie si vous devez
  • Utilisez n'importe quel encodage de caractères préexistant dans la sortie (je ne peux pas imaginer autre chose qu'un Unicode fonctionnant bien, mais si vous le pouvez, félicitations)
  • Supposons que l'entrée se présente sous une forme normalisée telle que les formes de normalisation Unicode NFD, NFC, etc. Par exemple, ä est-il écrit sous la forme d'un seul caractère ou d'un caractère de base + d'un caractère de combinaison?
  • Utiliser des méthodes d' entrée et de sortie standard

Scoring & IPA Characters

La notation est en octets. Soyez averti que les caractères allemands et les caractères IPA sont 2 octets en UTF-8. De plus, le caractère IPA U + 0327 COMBINAISON DE BREVE INVERTED BELOW (̯) est un caractère de combinaison Unicode et est un caractère UTF-8 de 2 octets. Cela signifie que quelque chose comme compterait comme 4 octets dans UTF-8. Pour les curieux, ce symbole signifie que la voyelle ne forme pas le noyau de la syllabe (la précédente le fait).

Méfiez-vous également de ces caractères IPA qui, dans certaines polices, ressemblent à d'autres caractères ASCII: ɡ, ɪ, ʏ, v (marque une longue voyelle), (marque quelle syllabe est accentuée dans un mot multisyllable).

Comment la liste de mots de référence a été créée

Cette section contient des informations supplémentaires non nécessaires pour le défi.

La liste de mots a été extraite de cette liste de fréquences de mots Wiktionnaire , en supprimant les répétitions à cause de la différence de casse et de deux mots sans entrées en allemand dans le Wiktionnaire anglais (oh & hey). L’IPA a examiné les Wiktionnaires anglais et allemands. Lorsque plusieurs prononciations étaient proposées, j'ai choisi la plus formelle et la plus standard. Si ce n'était pas clair, j'ai choisi celui qui correspond le mieux aux règles générales.

Je devais aussi normaliser la prononciation de la lettre "r". La façon dont cette lettre a été prononcée dépend fortement de la région, et le Wiktionnaire n’a pas du tout été cohérent. Je sentais que cela tendait à ce qui suit: "r" est prononcé / ɐ̯ / suivi d’une voyelle longue et une voyelle ne suit pas, sinon c’est. Je les ai donc tous modifiés pour suivre cette règle, à l'exception des préfixes ver et er qui étaient assez cohérents / (f) ɛɐ̯ /. De même, j'ai normalisé "eu" comme / ɔʏ̯ /.


16
Mathematica a une fonction intégrée pour this ( #~WordData~"PhoneticForm"&), mais cela ne fonctionne que pour les mots anglais.
JungHwan Min

29
@JungHwanMin J'ai lu votre commentaire comme suit: Attaque cardiaque immédiate, soupir de soulagement.
DPenner1

1
Comment puis-je savoir que "gestern" est prononcé "GHES-stern" au lieu de "ge-SHTERN"? "bester" comme "BEST-er" pas "be-SHTER"?
Leaky Nun

@LeakyNun Il n'y a pas d'algorithme à 100% pour cela, mais votre implémentation n'a besoin que de 75%. Mon implémentation de référence obtient également ces mots faux.
DPenner1

@ LeakyNun Eh bien, votre programme sera également capable de traiter les dialectes allemands, il est donc plus puissant.
P. Siehr

Réponses:


9

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

Définit pronounce(string $word).

Usage:

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

Une remarque: 3 préfixes et 33 mots sont codés en dur, et une partie du code est légèrement optimisée pour la liste de test.

Le code de test est , bien que cela dépende de ce fichier .

Tester:

php test.php all

Propulsé par les larmes des déclarations ternaires.

EDIT 7 : Supprimez ~ 170 octets en écrivant un pré-processeur dans le programme. En conséquence, le programme actuel (tout après __halt_compiler();) est un peu difficile à lire. Si vous voulez que le programme non traité, passer evalavec printla troisième déclaration.


C'est en fait 2667 octets, pas 2671 (en supposant que UTF-8)
caird coinheringaahing
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.