병음 조합


13

병음 음절 문자열을 인수로 사용하고 조합이 존재하면 true를 반환하고, 그렇지 않으면 false를 반환하는 함수를 만듭니다.

"ü"에 "v"를 사용하십시오.

다음은 전체 조합 목록입니다. http://www.pinyin.info/rules/initials_finals.html

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

문자 수를 줄이기 위해 웹 페이지 스크랩 또는 입력 방법 파일 읽기와 같은 작업을 수행하지 마십시오. (만약 당신이 그렇게한다면, 데이터의 길이는 문자 수에 따라 계산 될 것입니다)이 코드 골프의 목적 중 하나는 규칙이 어떻게 단순화 될 수 있는지 보는 것입니다. 가장 짧은 코드가 승리합니다.


어떻게 같은 약 nar? : P
JiminP 2016 년

1
참고로, 예제의 내용에도 불구하고, 나는 nvi유효한 조합 이라고 생각하지 않습니다 .
rintaun

링크 된 페이지가 이미» er 이 표에서 생략 되었다고 표시되어 있으면  «도 포함되어 있지 않아야합니까? (결국 기억이 나면 숫자 였지만 ;-))
Joey

답변:


4

자바 스크립트 1.6, 503 496 477 자

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

코드를 몇 줄로 나누는 데 오류가 발생하지 않도록 좀 더 읽기 쉽게 정리했습니다.

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

초기 값이 0 인 경우와 일회성 인 경우는 정규식으로 테스트됩니다. 그 후, 테이블은 (사운드 된) 일련의 6 자리, 기본 36 개의 숫자 (초기 사운드 당 하나씩)로 인코딩됩니다. 그런 다음 조회는 한 쌍의 indexOf통화와 시프트를 사용하여 올바른 비트를 선택합니다.

조합 표의 모든 셀에 대해 테스트했습니다 (채워진 셀은 참, 빈 셀은 거짓).

편집 : g–, k–, h–, j–, q– 및 z–의 36 개 문자 중 36 개 문자 중 일부를 비교하여 촘촘한 true / false 블록을 갖기 때문에 대체되었습니다.

편집 : 불필요한 비트를 피하기 위해 비트 테스트를 재정렬 !!하고 정규식을 더 압축했습니다.


왜 필요한 !!가요? 나는 왜 당신이 더블을 필요로하는지 이해하지 못합니다 ...
Peter Olson

그것으로 리턴은 0 또는 1입니다. 그것은 "true"로하지 않고이 아닌 0으로 반환하지만 반드시 1. 내 테스트 스크립트로 유효성 검사가 진행되지 않고 if (g(s) == (validList.indexOf(s) >= 0)있는 것은 거짓 반환 16 == true; 나는 " '진정한 것이 정말로 무엇을 의미 하는가'라는 관점에서 그것을 토론하고 그 일을 맡겼다. 어느 경우 에나, 오늘 어느 날, 나는 (더 많거나 적은) !!으로 대체 하여 return은 1 이고 두 문자를 깎았습니다. 1<<r&*parseInt(parseInt>>r)&1
DocMax

1

PHP, 548 자

물론 최적의 것은 아니지만 유효한 병음 조합과 일치하는 정규식을 작성했습니다. 반복되는 하위 문자열을 변수로 바꾸어 문자를 줄였습니다.

암호

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

용법

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

1

F #, 681 자

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

초기 자음이 정확하지 않은 음절을 얻지 못합니다 (Y, W 등).


1

APL (Dyalog Extended) , 475 바이트

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

온라인으로 사용해보십시오!

골프가 진행 중입니다.

언 골프

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}

온라인으로 사용해보십시오!

도우미 함수 s는 공백으로 구분 된 문자열의 압축을 풉니 다.

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

먼저 가능한 초기 및 최종 문자열을 음절에 저장 한 다음 tab첫 번째 목록의 각 문자열과 두 번째 목록의 각 문자열을 연결 하는 테이블을 만듭니다 .

다음으로 이진 데이터를 정수 목록으로 저장합니다. 일부 정수는 반복되므로 변수에 저장하여 일부 공백을 제거 할 수 있습니다.

각 정수는 이진수로 디코딩되며 테이블의 한 행을 나타냅니다. 숫자의 각 비트는 해당 행의 특정 음절이 유효한 음절인지 여부를 나타내며 MSB는 첫 번째 열을 나타냅니다. 유효하지 않은 모든 음절이 표에서 제거됩니다.

테이블을 목록으로 병합하고 특별한 경우로 초기 자음이없는 양식을 추가 한 다음 입력이 목록에 있는지 확인합니다.

추가 골프 가능성 :

  • base64 또는 base255 인코딩 작성
  • 숫자를 작게하려면 열과 행을 재정렬하십시오.

Python 유용한 스크립트 및 테스트 케이스 생성기 : 온라인으로 사용해보십시오!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.