Combinazioni di Pinyin


13

Crea una funzione che accetta una stringa di una sillaba pinyin come argomento e restituisce true della combinazione esistente, false in caso contrario.

Utilizzare "v" per "ü".

Ecco un elenco completo di combinazioni. http://www.pinyin.info/rules/initials_finals.html

Esempi

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

Per favore, non fare cose come raschiare pagine Web o leggere file di metodi di input per ridurre il conteggio dei caratteri. (Se lo fai, la lunghezza dei dati verrà conteggiata per il conteggio dei caratteri) Uno degli scopi di questo codice golf è vedere come semplificare le regole. Il codice più corto vince.


Che ne dici di qualcosa del genere nar? : P
JiminP

1
Proprio come una nota, nonostante ciò che dicono gli esempi, non credo nvisia mai una combinazione valida.
rintaun,

Se la pagina collegata dice già »  er è stata omessa da questa tabella« non dovrebbe essere inclusa anche? (Dopo tutto, era un numero, se ricordo bene ;-))
Joey,

Risposte:


4

JavaScript 1.6, 503 496 477 caratteri

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

Fomattato in modo un po 'più leggibile (escludendo eventuali errori nell'interrompere il codice in poche righe):

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

I casi a zero iniziale più alcuni pezzi unici vengono testati con un'espressione regolare. Successivamente, la tabella viene codificata come una serie (concatenata) di numeri a 6 cifre, base 36, uno per suono iniziale. La ricerca utilizza quindi una coppia di indexOfchiamate e uno spostamento per selezionare il bit giusto.

Testato su tutte le celle nella tabella delle combinazioni (celle riempite testate per celle vere e vuote testate per falso).

Modifica: ha sostituito alcuni dei 36 caratteri della ricerca base-36 con confronti poiché g–, k–, h–, j–, q– e z– hanno blocchi densi di vero / falso.

Modifica: Riorganizzato il bit test per evitare un inutile !!e compattato il regex di più.


Perché hai bisogno di un !!? Non sono sicuro di capire perché non avresti mai bisogno di un doppio ...
Peter Olson,

Con esso, il ritorno è 0 o 1; senza di essa "true" viene restituito come diverso da zero ma non necessariamente 1. Il mio script di test viene convalidato con il if (g(s) == (validList.indexOf(s) >= 0)quale restituisce false 16 == true; Ho discusso dal punto di vista di "cosa significa" vero "in realtà" e ho lasciato la cosa dentro. In entrambi i casi, ho programmato un cambiamento per oggi che eliminerà !!sostituendolo 1<<r&*parseIntcon (più o meno) in (parseInt>>r)&1modo che il il ritorno è 1 e mi rado due caratteri.
DocMax

1

PHP, 548 caratteri

Certo, probabilmente non è ottimale, ma ho scritto una regex per abbinare combinazioni di pinyin valide. Caratteri ridotti sostituendo le sottostringhe ripetute con variabili.

Codice

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

uso

> php pinyin.php bu
> true
> php pinyin.php cei
> false

1

F #, 681 caratteri

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

Le sillabe non vengono rilevate correttamente senza la consonante iniziale corretta (Y, W, ecc.).


1

APL (Dyalog Extended) , 475 byte

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

Provalo online!

Giocare a golf in corso.

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}

Provalo online!

La funzione helper sdecomprime una stringa delimitata da spazi:

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

Prima memorizzo le possibili stringhe iniziali e finali nella sillaba, quindi creo una tabella tab contenente la concatenazione di ogni stringa dal primo elenco con ciascuna stringa dal secondo elenco.

Successivamente, memorizzo i dati binari come un elenco di numeri interi. Alcuni numeri interi vengono ripetuti e possono quindi essere memorizzati in variabili, il che consente anche l'eliminazione di alcuni spazi.

Ogni numero intero viene decodificato in binario e rappresenta una riga della tabella. Ogni bit nel numero indica se una determinata sillaba in quella riga è una sillaba valida, con l'MSB che rappresenta la prima colonna. Tutte le sillabe non valide vengono rimosse dalla tabella.

Appiattiamo la tabella in un elenco, aggiungiamo i moduli senza consonante iniziale come caso speciale e infine controlliamo se il nostro input è nell'elenco.

Possibile ulteriore potenziale golfistico:

  • Scrivi la codifica base64 o base255
  • Riordina le colonne e le righe per ridurre i numeri.

Utile script e generatore di test case Python: provalo online!

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.