Combinaisons de Pinyin

13

Créez une fonction qui prend une chaîne de syllabes pinyin comme argument et renvoie vrai de la combinaison existe, faux sinon.

Utilisez "v" pour "ü".

Voici une liste complète des combinaisons. http://www.pinyin.info/rules/initials_finals.html

Exemples

f("bu") == true
f("zheng") == true
f("nv") == true
f("ri") == true
f("cei") == false
f("ia") == false
f("kian") == false
f("qa") == false

S'il vous plaît, ne faites pas de choses comme gratter des pages Web ou lire des fichiers de méthode d'entrée pour réduire le nombre de caractères. (Si vous le faites, la longueur des données sera prise en compte dans le nombre de caractères) L'un des objectifs de ce code golf est de voir comment les règles peuvent être simplifiées. Le code le plus court gagne.

Ming-Tang
la source
Et quelque chose comme ça nar? : P
JiminP
1
Tout comme une note, malgré ce que disent les exemples, je ne crois pas que ce nvisoit une combinaison valable.
rintaun
Si la page liée indique déjà »  er a été omis de ce tableau« ne devrait-elle pas être incluse également? (Après tout, c'était un chiffre, si je me souviens bien ;-))
Joey

Réponses:

4

JavaScript 1.6, 503 496 477 caractères

function g(s){return/^([bfmpw]?o|[yjqx]ua?n|[ln]ve?|ei?|y[aio]ng|w?[ae]ng?|w?ai?|wei|y?ao|y?ou|y[ai]n?|yu?e|[^aeiou]+u)$/.test(s)|(((k=6*("ccsszzdflmnprtbghkjqx".indexOf(s[0])+(f=s[1]=='h')))|(r="a.e.ai.ei.ao.ou.an.ang.en.eng.ong.ua.uo.uai.ui.uan.uang.un.i.ia.ie.iao.iu.ian.iang.in.ing.iong.u.ue".split('.').indexOf(s.slice(f+1))))<0?0:k>84?r>17^k<108:parseInt("009m2f00b8jb009m2f00b7r3009m2n00b8jj1dwcfz0000rtfjba4f1xgbnjfj01rz1uyfb1009nn61b37cv1uyfa5".slice(k,k+6),36)>>r&1)}

Fomatté un peu plus de manière lisible (sauf erreur dans la décomposition du code en quelques lignes):

function _g(s)
{
  f = s[1] == 'h'
  k = "ccsszzdfghjklmnpqrtxb".indexOf(s[0]) * 6
  k += 6 * f
  return /^(weng|[bfmp]?o|[yjqx]ua?n|[ln]ve?|[ae]i?|y[aeiu]|y[aio]ng|[ae]ng?|wang?|wai?|we[in]|w[ou]|y?ao|y?ou?|y[ai]n|yue)$/.test(s) | 
         !!(k >= 0 && (1 << "a.e.ai.ei.ao.ou.an.ang.en.eng.ong.u.ua.uo.uai.ui.uan.uang.un.i.ia.ie.iao.iu.ian.iang.in.ing.iong.u.ue".split('.').indexOf(s.slice(f + 1)) & parseInt("00j85300mh2v00j85300mgan00j85b00mh332rsovz0002cp00b8jj00b8jjqmlts000b8jjv2mkfz3uwo3jv203jz3pwvelqmlts000jbaq2m6ewvqmlts03pwvdp".slice(k, k + 6), 36)))
}

Les cas à zéro initial plus quelques cas uniques sont testés avec une expression régulière. Après cela, la table est codée comme une série (concaténée) de 6 chiffres, base 36, un par son initial. La recherche utilise ensuite une paire d' indexOfappels et un décalage pour sélectionner le bon bit.

Testé contre toutes les cellules du tableau des combinaisons (cellules pleines testées pour vrai, cellules vides testées pour faux).

Edit: Remplacement de certains des 36 caractères de la recherche en base 36 par des comparaisons puisque g–, k–, h–, j–, q– et z– ont des blocs denses de vrai / faux.

Edit: réarrangé le test de bits pour éviter un inutile !!et compacté davantage l'expression régulière .

DocMax
la source
Pourquoi en avez-vous besoin !!? Je ne suis pas sûr de comprendre pourquoi vous auriez besoin d'un double pas ...
Peter Olson
Avec lui, le retour est 0 ou 1; sans lui, "true" est retourné comme non nul mais pas nécessairement 1. Mon script de test est en train de valider if (g(s) == (validList.indexOf(s) >= 0)ce qui retourne false on 16 == true; Je l'ai débattu du point de vue «qu'est-ce que« vrai »signifie vraiment» »et laissé la chose en place. Dans les deux cas, j'ai un changement prévu pour plus tard aujourd'hui qui supprimera le !!en remplaçant 1<<r&*parseIntpar (plus ou moins) (parseInt>>r)&1afin que le le retour est 1 et je rase deux caractères.
DocMax
1

PHP, 548 caractères

Certes, ce n'est probablement pas optimal, mais j'ai écrit une expression régulière pour faire correspondre les combinaisons de pinyin valides. Réduction des caractères en remplaçant les sous-chaînes répétitives par des variables.

Code

<?php $a='?|e(i|ng?)';$b='|o(u|ng)|u';$c='|a?n)?|i(a[on]';$d='(a(ng?|o|i)';$e='|ng?)';$f='(i|ng)?';echo(preg_match("/^([bpm](a(i|o$e$a|u|o|i(e|a[on]$e?)|[pm]ou|m(e|iu)|f(a(ng?)?|ou$a|u)|d$d$a?$b(o|i$c?|e|u)?)|[dtnl]$d?|e$f$b(o$c|e)?)|[jqxy](i(a(o$e?|e|u|o?ng|n)|u(e|a?n))|([zcs]h?|r)i|[nl](ve?|i(n|ang?|u))|[dl]ia|[dt](ing|ui)|[dn]en|diu|([gkh]|[zcs]h?)(e(ng?)|a(o|ng?|i)?|ou|u(o|i|a?n)?)|r(e(ng?)?|a(o$e$b(a?n?|o|i)?)|[gkh](ei|ong|u(a$f))|[zcs]hua$f|([zcs]|[zc]h)ong|(z|[zs]h)ei|a(i|o$e?|ou$a?|w(u|a(i$e?|o|e(i$e))$/",$argv[1]))?"true":"false";

Usage

> php pinyin.php bu
> true
> php pinyin.php cei
> false
rintaun
la source
1

F #, 681 caractères

type l=Y|J|Q|X|W|F|B|P|M|N|L|T|D|Z|K|H|Zh|G|Sh|Ch|C|S|R|Iong|Vn|Van|Ia|Iu|In|Iang|Ve|V|Ian|Iao|Ie|Ing|I|Ei|A|Ai|An|Ang|Eng|U|Ao|E|Ou|Uo|Uan|Un|Ui|En|Ong|Ua|Uang|Uai|Ueng|O
let v x=x.GetHashCode()
let n x=J.GetType().GetNestedType("Tags").GetFields().GetValue(v x).ToString().Substring(6).ToLower();
let(^)a b=List.collect(fun x->List.map(fun z-> n x+ n z)b)a
let(-)a b=[v a..v b]
let(&)a b=a@b
let(!)a=[v a]
[<EntryPoint>]
let main a=
 printf"%b"(List.exists(fun x->x=a.[0])(Y-X^Iong-I& !W^Ei-Ui@Ua-O& !F^Ei-A@An-U@ !Ou&(F-N@D-Sh)^ !En&F-M^ !O&B-M^ !In&N-L^Iu-Un& !D^Ia-Iu&B-D^Ian-Ao& !M^E-Ou&Ch-S^A-Ong&T-Sh^Ei-Ui&N-G^ !Ong&K-Ch^Ua-Uai& !R^An-Ua&(Sh-R@ !Z@ !Zh)^ !I&["lia";"pou";"mui"]))
 0

N'obtient pas tout à fait les syllabes sans consonne initiale correcte (Y, W, etc.).

Mark H
la source
1

APL (Dyalog Extended) , 475 octets

s←⊢⊆⍨' '≠⊢
a b c2097144 131064 1957895
f←{(⊂⍵)∊(12v),(s'yi ya ye yao you yan yang yin ying yong yu yue yuan yun wu wa wo wai wei wan wang wen weng nv lv nve lve'),(,⊤(a-8)1966080 393208 1966064 2096720 1966072 1048568a a 2056184a 131048a 7288b 7280 106488b 7280b 0 1958911 73735c c 352263c 24583 1859591c,57)/,('bpmfdtnlgkhzcs',s'zh ch sh r j q x')∘.,v'aoe',s'ai ei ao ou an ang en eng ong u ua uo uai ui uan uang un ueng i ia ie iao iu ian iang in ing iong u ue uan un'}

Essayez-le en ligne!

Golf en cours.

Non golfé

s←{⍵⊆⍨' '≠⍵}
cons'b p m f d t n l g k h z c s zh ch sh r j q x'
vwls'a o e ai ei ao ou an ang en eng ong u ua uo uai ui uan uang un ueng i ia ie iao iu ian iang in ing iong u ue uan un'
tabcon∘.,vwl
bin←,⊤2097136 1966080 393208 1966064 2096720 1966072 1048568 2097144 2097144 2056184 2097144 131048 2097144 7288 131064 7280 106488 131064 7280 131064 0 1958911 73735 1957895 1957895 352263 1957895 24583 1859591 1957895 7 7 7 7 7
all'aoe',(12vwl),(s'yi ya ye yao you yan yang yin ying yong yu yue yuan yun wu wa wo wai wei wan wang wen weng nv lv nve lve'),bin/,tab
f←{(⊂⍵)∊all}

Essayez-le en ligne!

La fonction d'assistance sdécompresse une chaîne délimitée par des espaces:

{⍵⊆⍨' '≠⍵}    monadic function taking a string
    ' '≠⍵       0s at spaces, 1s elsewhere
 ⍵⊆⍨            Partition (split at 0s)

Je stocke d'abord les chaînes initiales et finales possibles dans la syllabe, puis je crée un tableau tab contenant la concaténation de chaque chaîne de la première liste avec chaque chaîne de la deuxième liste.

Ensuite, je stocke des données binaires sous forme de liste d'entiers. Certains des entiers sont répétés et peuvent donc être stockés dans des variables, ce qui permet également d'éliser certains espaces.

Chaque entier est décodé en binaire et représente une ligne du tableau. Chaque bit du nombre représente si une certaine syllabe de cette ligne est une syllabe valide, le MSB représentant la première colonne. Toutes les syllabes invalides sont supprimées du tableau.

Nous aplatissons le tableau dans une liste, ajoutons les formulaires sans consonne initiale comme cas spécial et vérifions enfin si notre entrée est dans la liste.

Autre potentiel de golf possible:

  • Écrire le codage base64 ou base255
  • Réorganisez les colonnes et les lignes pour réduire les nombres.

Générateur de scripts et de cas de test utile Python: essayez-le en ligne!

lirtosiast
la source