일본어 로마자는 일본어 텍스트를 라틴 문자로 변환합니다. 이 과제에서는 입력으로 일본어 문자열이 제공되며 올바른 ASCII 문자열로 변환해야합니다.
알아야 할 사항
일본어에는 히라가나 (짧은 단어에 사용되는 매력적인 단어), 가타카나 (소리와 다른 언어에서 빌려온 단어에 사용되는 각도) 및 한자 (원래 중국어에서 나오는 짙은 문자)의 세 가지 쓰기 시스템이 있습니다. 이 도전에서 우리는 히라가나에 대해서만 걱정할 것입니다.
히라가나 음절에는 46 개의 문자가 있습니다. 각 문자는 음절을 나타냅니다. 문자는 첫 번째 소리 (자음)와 두 번째 소리 (모음)로 구성됩니다. 순서대로 열은 aiueo
입니다.
: あいうえお
k: かきくけこ
s: さしすせそ
t: たちつてと
n: なにぬねの
h: はひふへほ
m: まみむめも
y: や ゆ よ
r: らりるれろ
w: わ を
N: ん
(이 표를 복사하여 붙여 넣은 경우 표의 문자 공간 U + 3000을 사용하여 y와 w의 간격을 두었다는 점에 유의하십시오)
예를 들어, あ と め는의 출력을 생성해야합니다 atome
. 첫 번째 문자는 a
이고 두 번째 문자는 이며 세 번째 문자는 to
입니다 me
.
예외
다른 언어와 마찬가지로 일본어에는 규칙에 예외가 있으며 히라가나 테이블에는 몇 가지가 있습니다. 이 문자들은 표에서의 위치와 약간 다르게 발음됩니다.
し : shi
, not si
ち : chi
, not ti
つ : tsu
, not tu
ふ : fu
, 아닙니다hu
다 쿠텐 ゛
‘다 쿠텐’이라는 단어는 ‘진흙 자국’을 의미합니다. 예를 들어, かka
는 か ゛로 바뀝니다 ga
. 변경 사항의 전체 목록 :
k
→ g
s
→ z
t
→ d
h
→b
예외도 변경됩니다. し ゛ : ji
(또는 zhi
), not zi
ち ゛ : ji
, not di
つ ゛ : dzu
, not du
(ふ ゛은 예상대로 작동하지만 예외는 아닙니다)
Handakuten은 행에 적용되는 추가 문자 ゜입니다 h
. 캐릭터 뒤에 배치하면 캐릭터의 소리가 p
아닌로 변경 b
됩니다.
dakuten과 handakuten은 모두 개별 문자로 제공됩니다. 미리 작성된 양식이나 결합 문자를 다룰 필요는 없습니다.
작은 문자
마지막으로 일부 문자의 작은 버전이 있습니다. 그들은 앞뒤에 오는 문자를 수정합니다.
ゃ ゅ ょ
이들의 작은 형태이다 ya
, yu
하고 yo
. 그것들은- i
컬럼 에서 소리 후에 만 배치됩니다 . 그들은를 제거 i
하고 소리를 추가합니다. 그래서 き や는 kiya
; き ゃ가로 변합니다 kya
.
chi
또는 shi
(또는 해당 양식) 뒤에 배치하면 y
역시 제거됩니다. し ゆ는 shiyu
; し ゅ는 shu
입니다.
마지막으로 다루어야 할 것은 작은 것 tsu
입니다. っ 무슨 일이 있어도 뒤에 오는 자음을 두 배로합니다. 다른 것은 없습니다. 예를 들어, き た는 kita
; き っ た는 kitta
입니다.
요약, 입력 및 출력
귀하의 프로그램은 46 가지 기본 히라가나, 언어 및 수기 양식, 작은 문자와의 조합으로 음역 할 수 있어야합니다.
정의되지 않은 동작이 포함됩니다 : 작은 ya
, yu
그리고 yo
이 아니라와 문자 다음에 i
작은 tsu
비에 handakuten 영향을받지 않은 문자에 탁점 문자열의 끝에, p
문자, 아무것도가 다른 위의 사양 / 소개에서 언급되지.
모든 입력이 유효하고 위에서 언급 한 일본어 문자 만 포함한다고 가정 할 수 있습니다.
출력은 문제가되지 않습니다. 당신은 또한 대체 할 수 r
와 함께 l
또는 혼자 n
와 m
. 출력은 모든 음절 사이에 공백이 있거나 공백이 없을 수 있습니다.
이것은 코드 골프입니다 : 바이트 단위의 최단 코드가 이깁니다.
테스트 사례
각 개별 부품에 대한 많은 테스트 사례가 사양에 나와 있습니다. 일부 추가 사례 :
ひ ら か ゛ な → hiragana
か た か な → katakana
た ゛ い き ゛ ゃ く て ん さ い は ゛ ん → daigyakutensaiban
ふ ゜ ろ く ゛ ら み ん く ゛ は ゜ す ゛ る こ う と ゛ こ ゛ る ふ → puroguramingupazurucoudogorufu
か ゛ ん ほ ゛ っ て → ganbatte
노트
-
나는 여기에 쓴 것 외에는 일본어를 잘 모른다. 실수를 한 경우 알려주십시오.
-
나는 원래 카타카나도 포함시킬 계획 이었기 때문에 (영어 음역 테스트 사례가 약간 더 정확할 수 있음 ), 코드 골프 도전에는 너무 클 것입니다.
-
유니 코드 이름에는 각 문자의 음역이 개별적으로 포함되지만 예외는 없습니다. 도움이 될 수도 있고 아닐 수도 있습니다.
-
두 오타 수정에 대한 squeamishossifrage 덕분에!
-
이것이 너무 길면 죄송합니다. 나는 히라가나의 기발한 부분을 도전에 맞추려고 시도했지만 작은 모음 전용 히라가나, 일부 자음 앞에서 n을 m으로 변경하고 반복 마크와 같은 것들을 도전을 관리하기 위해 잘라야했습니다.
-
제목이 미안하지 않습니다. 걸작입니다.
답변
파이썬 2, 638 바이트
import unicodedata
s=input()
k=[0x309B,0x309C,0x3063]
m=[0x3083,0x3085,0x3087]
e={0x3057:'shi',0x3061:'chi',0x3064:'tsu',0x3075:'fu'}
d={0x3057:'ji',0x3061:'ji',0x3064:'dzu'}
D=dict(zip('ksth','gzdb'))
f=lambda c:unicodedata.name(c).split()[-1].lower()if ord(c)not in e else e[ord(c)]
g=lambda c:d[c]if c in d else D[f(c)[0]]+f(c)[1:]
R=[]
r=[]
t=[]
i=0
while i<len(s):
c=ord(s[i])
if c==k[0]:R[-1]=g(s[i-1])
elif c==k[1]:R[-1]='p'+R[-1][1:]
elif c in m:R[-1]=R[-1][:-1];n=f(s[i]);R+=[n[1:]]if r[-1]in[0x3057,0x3061]else[n];r+=[c]
elif c==k[2]:t+=[len(R)]
else:R+=[f(s[i])];r+=[c]
i+=1
for i in t:R[i]=R[i][0]+R[i]
print ''.join(R)
유니 코드 문자열로 입력을받습니다.
Ideone에서 테스트
답변
파이썬 2, 447 바이트
import unicodedata as u
r=str.replace
i=''.join('x'*('SM'in u.name(x)or ord(x)==12444)+u.name(x)[-2:].strip()for x in raw_input().decode('utf-8'))
for a,o in zip('KSTH','GZDB'):
for b in'AEIOU':i=r(r(i,a+b+'xRK','P'+b),a+b+'RK',o+b)
for a,b,c,d in zip('STDZ',('SH','CH','J','J'),'TDHH',('TS','DZ','F','F')):i=r(r(i,a+'I',b+'I'),c+'U',d+'U')
for a in'CH','SH','J':i=r(i,a+'IxY',a)
for a in'BCDFGHJKMNPRSTWYZ':i=r(i,'xTSU'+a,a+a)
print r(i,'Ix','')
이것은 유니 코드 입력을 직접 가져 오기 때문에 몇 바이트를 잃어 버렸지 decode('utf-8')
만 도전의 정신에 더 가깝다고 생각합니다.
퍼즐 노트에서 제안한 것처럼 모든 문자를 유니 코드 이름의 마지막 두 문자로 바 꾸었습니다. 불행히도 이것은 동일한 문자의 대체 버전을 구별하지 않으므로 작은 문자와 handakuten 앞에 ‘x’를 추가하기 위해 추한 해킹을 만들어야했습니다.
나머지 for 루프는 다음과 같은 순서로 예외를 수정합니다.
- 첫 번째 for 루프는 dakutens와 handakutens를 올바른 자음으로 바꿉니다.
- 두 번째 for 루프는 shi, chi, tsu 및 fu의 히라가나 예외를 처리합니다.
- 세 번째 for 루프는 작은 y 문자 (sha, jo와 같은) 앞에있는 예외를 처리합니다.
- 네 번째 for 루프는 작은 tsu 후에 두 배의 자음을 처리합니다.
- 마지막 줄은 작은 y-를 다룹니다.
더 많은 단계를 결합 할 수 있기를 원하지만 경우에 따라 충돌을 피하기 위해 단계를 수행해야합니다.
온라인으로 사용해보십시오! (더 많은 예제가 포함 된 여러 줄 버전은 여기 에서 찾을 수 있습니다 ).
답변
스위프트 3, 67 64 자
s.applyingTransform (.toLatin에서 r = {(s : String)을하자 (뒤 : false)}}
let r={(s:String)in s.applyingTransform(.toLatin,reverse:false)}
답변
파이썬 3 , 259 바이트
import re,unicodedata as u
s=re.sub
n=u.normalize
k,*r=r'NFKC DZU DU TSU TU \1\1 SM.{6}(.) \1 (CH|J|SH)Y \1 ISMALL.(Y.) CHI TI JI [ZD]I SHI SI FU HU'.split()
t=''.join(u.name(c)[16:]for c in n(k,s(' ','',n(k,input()))))
while r:t=s(r.pop(),r.pop(),t)
print(t)
설명
이 입력 형식으로 운이 좋았습니다! NFKC 정규화를 통해 입력을 전달하면 어떻게되는지보십시오 .
>>> nfkc = lambda x: u.normalize('NFKC', x)
>>> [u.name(c) for c in 'は゛']
['HIRAGANA LETTER HA', 'KATAKANA-HIRAGANA VOICED SOUND MARK']
>>> [u.name(c) for c in nfkc('は゛')]
['HIRAGANA LETTER HA', 'SPACE', 'COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK']
dakuten은 공백과 결합 dakuten으로 대체됩니다. 그 공간은 は를 그것의 dakuten과 분리시키는 전부입니다. 그래서 우리는 그것을 제거하고 다시 정상화 합니다 .
>>> [u.name(c) for c in nfkc(nfkc('は゛').replace(' ', ''))]
['HIRAGANA LETTER BA']
빙고. 다섯 번째 줄은 입력을 다음과 같이 바꿉니다.
KONOSUBARASIISEKAINISISMALL YUKUHUKUWO
그런 다음 9 개의 지루한 정규식 대체를 적용하여 r
완료했습니다.
KONOSUBARASHIISEKAINISHUKUFUKUWO
(Jonathan French는 import re,unicodedata as u
대신 4 바이트를 절약했습니다 import re;from unicodedata import*
. 감사합니다!)