Pinyin-Kombinationen

13

Erstellen Sie eine Funktion, die eine Zeichenfolge aus einer Pinyin-Silbe als Argument verwendet und true für die vorhandene Kombination zurückgibt, andernfalls false.

Verwenden Sie "v" für "ü".

Hier ist eine vollständige Liste der Kombinationen. http://www.pinyin.info/rules/initials_finals.html

Beispiele

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

Bitte tun Sie nichts wie das Scrappen von Webseiten oder das Lesen von Eingabemethodendateien, um die Anzahl der Zeichen zu verringern. (Wenn Sie dies tun, wird die Länge der Daten zur Anzahl der Zeichen hinzugerechnet.) In diesem Codegolf wird unter anderem untersucht, wie Regeln vereinfacht werden können. Kürzester Code gewinnt.

Ming-Tang
quelle
Was ist mit so etwas nar? : P
JiminP
1
Nur als Anmerkung, trotz der Aussagen in den Beispielen, glaube ich nicht, dass nvies jemals eine gültige Kombination gibt.
Rintaun
Wenn auf der verlinkten Seite bereits steht, dass »  er in dieser Tabelle weggelassen wurde«, sollte dies nicht auch berücksichtigt werden? (Immerhin war es eine Zahl, wenn ich mich richtig erinnere ;-))
Joey

Antworten:

4

JavaScript 1.6, 503 496 477 Zeichen

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)}

Etwas leserlicher formatiert (abgesehen von Fehlern beim Aufteilen des Codes in einige Zeilen):

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)))
}

Die Null-Anfangsfälle plus einige Einmalfälle werden mit einem regulären Ausdruck getestet. Danach wird die Tabelle als (verkettete) Reihe von 6-stelligen Basis-36-Zahlen codiert, eine pro Anfangston. Die Suche verwendet dann ein Paar von indexOfAufrufen und eine Verschiebung, um das richtige Bit auszuwählen.

Getestet gegen alle Zellen in der Kombinationstabelle (gefüllte Zellen auf wahr getestet, leere Zellen auf falsch getestet).

Bearbeiten: Ersetzt einige der 36 Zeichen der Base-36-Suche durch Vergleiche, da g–, k–, h–, j–, q– und z– dichte Blöcke von wahr / falsch haben.

Bearbeiten: Der Bittest wurde neu angeordnet, um unnötiges !!und mehr komprimiertes Regex zu vermeiden .

DocMax
quelle
Warum brauchst du eine !!? Ich bin nicht sicher, ob ich verstehe, warum Sie jemals ein Doppel brauchen würden, nicht ...
Peter Olson
Damit ist die Rückgabe 0 oder 1; ohne sie wird "true" als nicht null, aber nicht unbedingt 1 zurückgegeben. Mein Testskript überprüft, if (g(s) == (validList.indexOf(s) >= 0)womit false on zurückgegeben wird 16 == true. Ich diskutierte es aus der Perspektive "Was bedeutet", "wirklich bedeutet" und beließ die Sache dabei. In beiden Fällen habe ich eine geplante Änderung für den späteren Tag vor, mit der das !!Problem beseitigt wird, indem 1<<r&*parseInt(mehr oder weniger) (parseInt>>r)&1durch das ersetzt wird return ist 1 und ich rasiere zwei Zeichen ab.
DocMax
1

PHP, 548 Zeichen

Zugegeben, es ist wahrscheinlich nicht optimal, aber ich habe einen regulären Ausdruck geschrieben, der mit gültigen Pinyin-Kombinationen übereinstimmt. Reduzierte Zeichen durch Ersetzen von sich wiederholenden Teilzeichenfolgen durch Variablen.

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";

Verwendung

> php pinyin.php bu
> true
> php pinyin.php cei
> false
Rintaun
quelle
1

F #, 681 Zeichen

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

Verstehen die Silben ohne Anfangskonsonanten nicht ganz richtig (Y, W usw.).

Mark H
quelle
1

APL (Dyalog Extended) , 475 Bytes

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'}

Probieren Sie es online!

Golfen im Gange.

Ungolfed

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}

Probieren Sie es online!

Die sHilfsfunktion entpackt einen durch Leerzeichen getrennten String:

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

Ich speichere zuerst die möglichen Anfangs- und Endzeichenfolgen in der Silbe und erstelle dann eine Tabelle, tabdie die Verkettung jeder Zeichenfolge aus der ersten Liste mit jeder Zeichenfolge aus der zweiten Liste enthält.

Als nächstes speichere ich Binärdaten als Liste von ganzen Zahlen. Einige der ganzen Zahlen wiederholen sich und können daher in Variablen gespeichert werden, was auch die Elution einiger Leerzeichen ermöglicht.

Jede Ganzzahl wird binär decodiert und repräsentiert eine Zeile der Tabelle. Jedes Bit in der Zahl gibt an, ob eine bestimmte Silbe in dieser Zeile eine gültige Silbe ist, wobei das MSB die erste Spalte darstellt. Alle ungültigen Silben werden aus der Tabelle entfernt.

Wir reduzieren die Tabelle zu einer Liste, fügen die Formulare ohne Anfangskonsonanten als Sonderfall hinzu und prüfen schließlich, ob unsere Eingabe in der Liste enthalten ist.

Mögliches weiteres Golfpotential:

  • Schreiben Sie die Base64- oder Base255-Codierung
  • Ordnen Sie die Spalten und Zeilen neu an, um die Zahlen zu verkleinern.

Python-hilfreiches Skript und Testfallgenerator: Probieren Sie es online aus!

Lirtosiast
quelle