Bạn là người La Mã, Baby


38

La Mã hóa tiếng Nhật đang chuyển đổi văn bản tiếng Nhật thành các ký tự Latinh. Trong thử thách này, bạn sẽ được cung cấp một chuỗi các ký tự tiếng Nhật làm đầu vào và dự kiến ​​sẽ chuyển đổi chúng thành chuỗi ASCII chính xác.

Những gì bạn sẽ cần biết

Ngôn ngữ Nhật Bản có ba hệ thống chữ viết: hiragana (một đường cong được sử dụng cho các từ ngắn), katakana (một góc được sử dụng cho các âm thanh và các từ mượn từ các ngôn ngữ khác) và kanji (các ký tự dày đặc có nguồn gốc từ tiếng Trung Quốc). Trong thử thách này, chúng tôi sẽ chỉ lo lắng về hiragana.

Có 46 ký tự trong giáo trình hiragana. Mỗi nhân vật đại diện cho một âm tiết. Các ký tự được tổ chức bởi âm đầu tiên (phụ âm) và âm thứ hai (nguyên âm). Các cột theo thứ tự là aiueo.

 : あいうえお
k: かきくけこ
s: さしすせそ
t: たちつてと
n: なにぬねの
h: はひふへほ
m: まみむめも
y: や ゆ よ
r: らりるれろ
w: わ   を
N: ん

(nếu bạn sao chép và dán bảng này lưu ý rằng tôi đã sử dụng các khoảng trắng ý thức hệ U + 3000 để xóa khoảng trống y và w)

Vì vậy, ví dụ, と sẽ tạo ra một đầu ra của atome. Ký tự đầu tiên là a, thứ hai là tovà thứ ba là me.

Ngoại lệ

Giống như bất kỳ ngôn ngữ tốt nào, tiếng Nhật cũng có ngoại lệ đối với các quy tắc của nó và bảng hiragana có một số ngôn ngữ. Các ký tự này được phát âm hơi khác so với vị trí của chúng trong bảng sẽ ngụ ý:

: shi, Không phải si
ち : chi, không ti
つ : tsu, không tu
ふ : fu, khônghu

Đam mê

Từ 'dakuten' có nghĩa là 'dấu bùn': dakuten biến âm thanh thành âm tương đương của chúng (thông thường); ví dụ, kabiến thành か ゛ga. Danh sách đầy đủ các thay đổi:

kg
sz
td
hb

Các ngoại lệ cũng thay đổi: し ゛: ji(hoặc zhi), không phải zi
ち ゛ : ji, không di
つ ゛ : dzu, không du
(ふ hoạt động như bạn mong đợi; đó không phải là ngoại lệ)

Handakuten là một ký tự bổ sung áp dụng cho hhàng. Nếu được đặt sau một ký tự, nó sẽ thay đổi âm thanh của ký tự thành pchứ không phải b.

Cả dakuten và handakuten sẽ được cung cấp dưới dạng các ký tự riêng lẻ. Bạn sẽ không cần phải xử lý các biểu mẫu được sắp xếp sẵn hoặc các ký tự kết hợp.

Nhân vật nhỏ

Cuối cùng, có phiên bản nhỏ của một số nhân vật. Họ sửa đổi các nhân vật đến trước hoặc sau họ.

ゅ ょ

Đây là những hình thức nhỏ ya, yuyo. Chúng chỉ được đặt sau âm thanh trong i-column; họ loại bỏ ivà thêm âm thanh của họ. Vì vậy, や biến thành kiya; ゃ biến thành kya.

Nếu được đặt sau chihoặc shi(hoặc các hình thức dakuten-ed của họ), thì ycũng bị loại bỏ. し ゆ là shiyu; し là shu.

Điều cuối cùng bạn sẽ phải đối phó là nhỏ tsu. Nhân đôi phụ âm đi sau nó, bất kể là gì; nó không làm gì khác Chẳng hạn, た là kita; き っ là kitta.

Tóm tắt, đầu vào và đầu ra

Chương trình của bạn phải có khả năng phiên âm: 46 hiragana cơ bản, hình thức dakuten và handakuten của họ và sự kết hợp của họ với các ký tự nhỏ.

Hành vi không xác định bao gồm: nhỏ ya, yuyokhông theo sau một ký tự i, nhỏ tsuở cuối chuỗi, dakuten trên một ký tự không bị ảnh hưởng, handakuten trên một pký tự không và bất kỳ thứ gì khác không được đề cập trong thông số / giới thiệu ở trên.

Bạn có thể cho rằng tất cả các đầu vào là hợp lệ và chỉ chứa các ký tự tiếng Nhật được đề cập ở trên.

Trường hợp không quan trọng trong đầu ra; bạn cũng có thể thay thế rbằng lhoặc một mình nvới m. Đầu ra có thể có một khoảng trống giữa mỗi âm tiết hoặc không có khoảng trắng nào cả.

Đây là : mã ngắn nhất tính theo byte thắng.

Các trường hợp thử nghiệm

Nhiều trường hợp thử nghiệm cho từng phần riêng lẻ được đưa ra trong thông số kỹ thuật. Một số trường hợp bổ sung:

ひ ら か → hiragana

か た か な → katakana

゛ い て さ い は ゛ ん → daigyakutensaiban

゜ ろ く ゛ ら み ん く ゛ は ゜ す ゛ る こ う と ゛ こ ゛ る ふ → puroguramingupazurucoudogorufu

゛ ん → ganbatte

Ghi chú

  • Tôi không biết nhiều tiếng Nhật ngoài những gì tôi đã viết ở đây. Xin vui lòng cho tôi biết nếu tôi đã thực hiện bất kỳ sai lầm.

  • Ban đầu tôi cũng dự định bao gồm katakana (vì vậy trường hợp kiểm tra phiên âm tiếng Anh của tôi có thể chính xác hơn một chút ), nhưng điều đó sẽ là quá nhiều cho một thử thách golf mã.

  • Tên Unicode bao gồm phiên âm của từng ký tự riêng lẻ, nhưng không có ngoại lệ. Điều này có thể hoặc có thể không hữu ích cho bạn.

  • Cảm ơn squeamishossifrage đã sửa hai lỗi chính tả!

  • Tôi xin lỗi nếu điều này quá dài; Tôi đã cố gắng phù hợp với hầu hết các quirks của hiragana vào thử thách nhưng một số thứ (như hiragana chỉ nguyên âm nhỏ, thay đổi n thành m trước một số phụ âm và dấu lặp lại) phải được cắt để giữ cho thử thách có thể kiểm soát được.

  • Tôi hoàn toàn không xin lỗi vì danh hiệu này. Nó là một kiệt tác.


1
Đầu ra để làm きっったgì?
lirtosiast

@Thomas: Đó là một đầu vào không hợp lệ. Đầu ra có thể là bất cứ điều gì bạn muốn.
Deusovi

1
nên っしsshihay shshi?
lirtosiast

2
I'm not at all sorry for the title. It's a masterpiece.Downvote
Fatalize

3
@Firthize Không cần phải mang thành kiến ​​chống Britney của bạn ở đây. Mặc dù cá nhân tôi có thể là một người hâm mộ J-Lo nhiều hơn, tôi sẽ không đánh giá thấp một câu đố xuất sắc về điều đó.
bán ngoài

Câu trả lời:


7

Python 2, 638 byte

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)

Lấy đầu vào là chuỗi unicode.

Kiểm tra nó trên Ideone


1
Bạn có thể lưu tạm biệt print ''.join(R)print''.join(R)
bệnh sởi

6

Python 2, 447 byte

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','')

Điều này lấy đầu vào Unicode trực tiếp, khiến tôi mất một vài byte vì decode('utf-8')nhưng tôi nghĩ là nhiều hơn trong tinh thần của thách thức.

Tôi bắt đầu bằng cách thay thế mọi ký tự bằng hai ký tự cuối cùng của tên unicode của nó, như được đề xuất trong ghi chú của câu đố. Thật không may, điều này không phân biệt giữa các phiên bản thay thế của cùng một nhân vật, vì vậy tôi đã phải thực hiện một bản hack xấu xí để thêm 'x' trước các ký tự nhỏ và handakuten.

Phần còn lại của các vòng lặp chỉ là sửa các ngoại lệ, theo thứ tự:

  1. vòng lặp đầu tiên biến dakutens và handakutens thành phụ âm chính xác;
  2. thứ hai cho các giao dịch vòng lặp với các ngoại lệ hiragana của shi, chi, tsu và fu;
  3. thứ ba cho các vòng lặp xử lý các ngoại lệ trước một ký tự y nhỏ (như sha, jo);
  4. thứ tư cho các giao dịch vòng lặp với các phụ âm tăng gấp đôi sau một tsu nhỏ.
  5. thỏa thuận dòng cuối cùng với y- nhỏ.

Tôi ước tôi có thể kết hợp nhiều bước hơn, nhưng trong một số trường hợp, các bước phải được thực hiện để tránh xung đột.

Hãy thử trực tuyến! (một phiên bản nhiều dòng với nhiều ví dụ có thể được tìm thấy ở đây ).



Chào mừng đến với PPCG. Giải pháp đầu tiên rất hay :)
Shaggy

Biến bốn khoảng trắng của bạn ở phía trước for b in'AEIOU'thành một tab hoặc một khoảng trắng để lưu 3 byte. Bạn cũng có thể sử dụng from unicodedata import*để lưu một số byte - không chắc chắn.
Stephen

4

Swift 3, 67 64 ký tự

let r = {(s: String) trong s.appellingTransform (.toLatin, Reverse: false)}

let r={(s:String)in s.applyingTransform(.toLatin,reverse:false)}

3
Một dựng sẵn, thực sự, Swift có BUILTIN CHO NÀY?
Zacharý

Không biết Swift chút nào, nhưng bạn có thể cắt các khoảng trắng sau s:String).toLatin,không?
Yytsi

@TuukkaX, phát hiện tốt!
idrougge

@ Zacharý, cũng Foundationcó.
idrougge

3

Python 3 , 259 byte

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)

Hãy thử trực tuyến!

Giải trình

Chúng tôi rất may mắn với định dạng đầu vào này! Hãy xem điều gì xảy ra nếu tôi chuyển đầu vào thông qua chuẩn hóa 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']

Các dakuten được thay thế bởi một không gian và một dakuten kết hợp. Bây giờ không gian đó là tất cả những gì ngăn cách は với dakuten của nó. Vì vậy, chúng tôi thoát khỏi nó và bình thường hóa một lần nữa :

>>> [u.name(c) for c in nfkc(nfkc('は゛').replace(' ', ''))]
['HIRAGANA LETTER BA']

Chơi lô tô. Dòng thứ năm biến đầu vào thành một cái gì đó như

KONOSUBARASIISEKAINISISMALL YUKUHUKUWO

Sau đó, chúng tôi áp dụng 9 thay thế regex nhàm chán được nhồi nhét rvà chúng tôi đã hoàn thành:

KONOSUBARASHIISEKAINISHUKUFUKUWO

(Jonathan French đã lưu 4 byte, viết import re,unicodedata as uthay vì import re;from unicodedata import*. Cảm ơn!)


Lạm dụng bình thường hóa cho vui và lợi nhuận. Thật là đẹp.
Tim Pederick

2
import re,unicodedata as unhư trong Kirill L. trả lời cho một thách thức liên quan tiết kiệm 4 byte .
Jonathan Frech
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.