Угадайте, как произносится немецкие слова

37

Введение

В отличие от английского, немецкий язык имеет довольно фонемную систему письма . Это означает, что соответствие между правописанием и произношением близко. Учитывая любое слово, с которым вы не знакомы, вы все равно знаете, как произносить его из-за системы орфографии. Это означает, что компьютер должен быть в состоянии сделать это тоже правильно?

Вызов

Напишите программу или функцию, которая принимает в качестве входных данных строку, представляющую немецкое слово, и печатает или возвращает ее произношение в международном фонетическом алфавите (IPA) .

Я, конечно, не собираюсь заставлять вас изучать немецкий язык или полный IPA . Этот один раздел Википедии содержит почти все правила немецкого языка для IPA, которые вам нужны, и я кодировал справочную реализацию C # .

В этой ссылке также приведен список из 400 распространенных немецких слов и их произношение IPA (необходимо для проверки). Если взять пример из этого списка, если вход - solltestправильный вывод ˈzɔltəst.

Реализованная реализация добавляет два полезных правила, не упомянутых в разделе Википедии: предполагается, что ударение в слове находится в первом слоге (очень вероятно, на немецком языке), и использует лучшую эвристику для определения, когда буква «е» представляет звук шва / ə /. Он также реализует специальную обработку префиксов, но это не улучшило результаты так сильно, как я думал.

Детали

Чтобы программа считалась действительной, ваша программа должна соответствовать следующим требованиям:

  • Выходные данные IPA должны точно соответствовать не менее 300 из 400 слов в списке контрольных слов (эталонная реализация получает 333 правильных значения)
  • Ваша программа должна угадать любое правдоподобное немецкое слово. Таким образом, у нас есть техническое требование, это будет означать, что для любого ввода, которое соответствует регулярному выражению [a-zA-ZäÄöÖüÜ][a-zäöüß]*и имеет хотя бы один гласный (aeiouyäöü), вы должны производить вывод без пробелов, а не выводить ошибки.
  • Программа должна быть детерминированной (всегда давать один и тот же результат при одинаковых входных данных)
  • В противном случае стандартные лазейки запрещены (особенно те, что касаются извлечения ресурсов за пределами площадки).

Разные вещи, которые вам разрешено делать:

  • Иметь пробелы в начале и в конце, если необходимо
  • Используйте любую ранее существующую кодировку символов в выходных данных (я не могу представить, чтобы что-то кроме Unicode работало хорошо, но если вы можете, поздравляю)
  • Предположим, что ввод находится в некоторой нормализованной форме, такой как формы нормализации Unicode NFD, NFC и т. Д. Например, записан ли ä как отдельный символ или базовый символ + символ объединения?
  • Используйте стандартные методы ввода и вывода

Скоринг и персонажи МФА

Оценка в байтах. Имейте в виду, что немецкие символы и символы IPA являются 2 байтами в UTF-8. Кроме того, символ IPA U + 0327 COMBINING INVERTED BREVE НИЖЕ (̯) является символом объединения Unicode и представляет собой 2-байтовый символ UTF-8 сам по себе. Это означает, что что-то вроде ɐ̯ будет считаться 4 байтами в UTF-8. Для любопытных этот символ означает, что гласный не образует ядро ​​слога (вместо этого формируется предыдущий).

Также остерегайтесь этих символов IPA, которые в некоторых шрифтах похожи на другие символы ASCII: ɡ, ɪ, ʏ, ː (обозначает длинный гласный),) (обозначает, какой слог имеет ударение в многосложном слове).

Как был создан список контрольных слов

В этом разделе дополнительная информация не нужна для вызова.

Список слов был взят из этого списка частот слов Викисловаря , удаляя повторы из-за разницы в регистре и двух слов, которые не имели немецких записей в английском Викисловарь (о, привет). IPA была от просмотра как английских, так и немецких викисловаров. Там, где предлагалось несколько вариантов произношения, я выбрал более формальное и стандартное. Если это не было ясно, я выбрал тот, который наиболее соответствует общим правилам.

Я также должен был стандартизировать, как произносится буква «р». То, как произносится это письмо, сильно зависит от региона, и Викисловарь совершенно не соответствует тому, в каком письме оно выбрано. Я чувствовал, что это имеет тенденцию к следующему: «r» произносится / ɐ̯ /, когда следует длинный гласный, а гласный не следует, в противном случае это otherwise. Итак, я изменил все из них, чтобы следовать этому правилу, за исключением префиксов ver и er, которые были достаточно последовательно / (f) ɛɐ̯ /. Точно так же я стандартизировал «ес» как / ɔʏ̯ /.

DPenner1
источник
16
Mathematica имеет встроенную функцию this ( #~WordData~"PhoneticForm"&), но она работает только для английских слов.
JungHwan Мин
29
@JungHwanMin Я прочитал ваш комментарий следующим образом: Немедленный сердечный приступ, вздох облегчения.
DPenner1
1
Откуда мне знать, что «gestern» произносится как «GHES-tern» вместо «ge-SHTERN»? "bester" как "BEST-er", а не "be-SHTER"?
Утренняя монахиня
@LeakyNun Нет 100% алгоритма для этого, но ваша реализация должна получить только 75%. Моя эталонная реализация также неправильно понимает эти слова.
DPenner1
@LeakyNun Ну, ваша программа также сможет работать с немецкими диалектами, поэтому она более мощная.
P.

Ответы:

9

PHP, 3311 2988 2916 2845 2759 2671 2667 2509 2484 байт, передача 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ø]);}

Определяет pronounce(string $word).

Использование:

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

Одно замечание: 3 префикса и 33 слова жестко запрограммированы, а часть кода слегка оптимизирована под список тестирования.

Код тестирования здесь , хотя он зависит от этого файла .

Тестировать:

php test.php all

Работает на слезах троичных заявлений.

РЕДАКТИРОВАТЬ 7 : сжал ~ 170 байт, записав препроцессор в программу. Как следствие, настоящая программа (все после __halt_compiler();) довольно трудно читать. Если вы хотите необработанную программу, переключитесь evalс помощью printв третьем утверждении.

Электра
источник
Это на самом деле 2667 байт, а не 2671 (при условии UTF-8)
caird coinheringaahing