Sen bir Romancısın, bebeğim


38

Japonca'nın romanlaştırılması, Japonca metni Latin karakterlerine dönüştürüyor. Bu mücadelede, giriş olarak Japonca karakterlerden oluşan bir dizge verilecek ve bunları doğru ASCII dizgisine dönüştürmeniz bekleniyor.

Bilmeniz Gerekenler

Japonca dilinin üç yazı sistemi vardır: hiragana (kısa kelimeler için kullanılan kıvrımlı dil), katakana (diğer dillerden ödünç alınan sesler ve kelimeler için kullanılan açı açısı) ve kanji (aslen Çinli olan yoğun karakterler). Bu mücadelede sadece hiragana için endişeleneceğiz.

Hiragana hecesinde 46 karakter vardır. Her karakter bir heceyi temsil eder. Karakterler ilk ses (ünsüz) ve ikinci ses (ünlü) tarafından düzenlenir. Sıradaki sütunlar aiueo.

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

(bu tabloyu kopyalayıp yapıştırırsanız, U + 3000 ideografik boşluklarını y ve w boşluklarını kullandığımı unutmayın.)

Bu nedenle, örneğin, あ と め bir çıktı üretmelidir atome. İlk karakter, aikincisi tove üçüncüsü me.

İstisnalar

Herhangi bir güzel dilde olduğu gibi, Japonca da kendi kurallarında istisnalar vardır ve hiragana masası da birkaç tane vardır. Bu karakterler, tablodaki konumlarından biraz farklı olarak telaffuz edilir:

し: shi, değil si
ち: chi, değil ti
つ: tsu, değil tu
ふ: fu, değilhu

Dakuten ゛

'Daututen' kelimesi 'çamurlu işaret' anlamına gelir: dakuten sesleri kendi eşdeğerlerine dönüştürür (genellikle); örneğin, かkaか ゛ olur ga. Değişikliklerin tam listesi:

kg
sz
td
hb

İstisnalar da değişiyor: し ゛: ji(veya zhi), zi
ち ゛: jideğil, di
つ ゛: dzudeğil, du
(ふ ゛ beklediğin gibi davranıyor; istisna değil)

Handakuten, sıraya uygulanan character ek bir karakterdir h. Bir karakterden sonra yerleştirilirse, karakterin sesini pyerine değiştirir b.

Hem dalkuten hem de handakuten bireysel karakter olarak verilecek. Önceden oluşturulmuş formlarla veya birleştirme karakterleriyle uğraşmanıza gerek kalmayacak.

Küçük Karakterler

Son olarak, bazı karakterlerin küçük versiyonları vardır. Onlardan önce veya sonra gelen karakterleri değiştirir.

ゃ ゅ ょ

Bunlar küçük şekilleridir ya, yuve yo. Yalnızca i-column içindeki seslerden sonra yerleştirilirler ; kaldırırlar ive seslerini eklerler. Böylece, き や dönüşür kiya; き ゃ dönüşür kya.

Sonra chiveya shi(veya dakuten-ed formları) yerleştirilirse, o yda kaldırılır. し ゆshiyu; し ゅshu.

Başa çıkmanız gereken son şey küçük tsu. What ne olursa olsun peşinden gelen ünsüzü iki katına çıkarır; başka bir şey yapmaz. Örneğin, き たkita; き っ たkitta.

Özet, Giriş ve Çıkış

Programınız harfleri çevirebilmelidir: 46 temel hiragana, dakuten ve handakuten formları ve küçük karakterli kombinasyonlar.

Tanımsız davranış şunları içerir: küçük ya, yuve yobir karakterin sonunda, bir karakterin sonunda iküçük tsu, etkilenmemiş bir karakterde daututen, pkarakter olmayan bir karakterde handakuten ve yukarıdaki açıklamada / açıklamada belirtilmeyen herhangi bir şey.

Tüm girdilerin geçerli olduğunu ve yalnızca yukarıda belirtilen Japonca karakterleri içerdiğini varsayabilirsiniz.

Vaka çıktıda önemli değil; Ayrıca değiştirebilir rile lveya yalnız nolan m. Çıktı, her hecenin arasında bir boşluk bırakabilir veya hiç boşluk bırakılmayabilir.

Bu : bayt cinsinden en kısa kod kazanır.

Test Kılıfları

Her bir bölüm için birçok test durumu şartnamede verilmiştir. Bazı ek durumlar:

ひ ら か ゛ な → hiragana

か た か な → katakana

た ゛ い き ゃ く て ん ん い は ゛ ん → daigyakutensaiban

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

か ゛ ん ほ ゛ て → ganbatte

notlar

  • Burada yazdıklarım dışında fazla Japonca bilmiyorum. Herhangi bir hata yaptıysam lütfen bana bildirin.

  • Aslında ben de katakana eklemeyi düşünüyordum (bu yüzden ingilizce çevirisi test durumum biraz daha doğru olabilirdi), ancak bu kod golf mücadelesi için çok fazla olurdu.

  • Unicode adları, her karakterin ayrı ayrı, ancak istisnalar olmadan çevrilmesini içerir. Bu size yardımcı olabilir veya olmayabilir.

  • İki yazım hatasını düzeltmek için squeamishossifrage'a teşekkürler!

  • Bu çok uzunsa özür dilerim; Hiragana'nın tuhaflıklarının çoğunu bu zorluğa sığdırmaya çalıştım, ancak bazı şeylerin (sadece küçük ünlü hiraganalar gibi, bazı ünsüzlerin önünde n'den m'ye değişiyor ve tekrarlama işareti gibi) mücadeleyi yönetilebilir kılmak zorunda kaldım.

  • Başlık için hiç üzgünüm. Bu bir şaheser.


1
Çıktı ne için olmalı きっった?
lirtosiast 29:15

@ Tomo: Bu geçersiz bir girdi. Çıktı istediğiniz ne olabilir.
Deusovi

1
gerektiğini っしolmak sshiya shshi?
lirtosiast

2
I'm not at all sorry for the title. It's a masterpiece.Aşağı oy verildi
8'de ölümüne neden

3
@Fatalize Buraya anti-Britney yanlılığınızı getirmenize gerek yok. Şahsen daha çok J-Lo hayranı olmama rağmen, bunun için mükemmel bir bilmece kullanmayacağım.
yarı ekstrinsik

Yanıtlar:


7

Python 2, 638 bayt

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)

Girdiyi unicode dizgesi olarak alır.

İdeone üzerinde test et


1
Sen değiştirerek cimri güle kaydedebilirsiniz print ''.join(R)içinprint''.join(R)
Zachary

6

Python 2,447 bayt

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

Bu doğrudan Unicode girdisini alır, bu da beni bir kaç bayt kaybetti, çünkü decode('utf-8')bence daha çok meydan okuma ruhu içinde.

Bulmacanın notlarında önerildiği gibi, her karakteri unicode adının son iki karakteriyle değiştirerek başladım. Ne yazık ki, bu aynı karakterin alternatif versiyonları arasında ayrım yapmıyor, bu yüzden küçük karakterlerden ve handakutenden önce 'x' eklemek için çirkin bir kesmek zorunda kaldım.

For döngülerinin geri kalanı sırayla sadece istisnaları düzeltiyor:

  1. ilk for döngüsü dakutens ve handakutens'i doğru ünsüzlere dönüştürür;
  2. döngü için ikincisi shi, chi, tsu ve fu'nun hiragana istisnaları ile ilgilidir;
  3. Döngü için üçüncü, küçük bir y karakterinden önceki istisnalar ile ilgilidir (sha, jo gibi);
  4. döngü için dördüncü küçük bir tsu sonra iki katına ünsüz ile ilgilidir.
  5. son satır küçük y- ile ilgilidir.

Keşke daha fazla adım birleştirebilseydim, ancak bazı durumlarda çatışmaları önlemek için adımların gerçekleştirilmesi gerekiyor.

Çevrimiçi deneyin! (Daha fazla örnek içeren çok hatlı bir sürüm burada bulunabilir ).



PPCG'ye Hoşgeldiniz. Çok güzel ilk çözüm :)
Shaggy

Dört baytınızı for b in'AEIOU'bir sekme veya 3 bayttan tasarruf etmek için tek bir alana çevirin . from unicodedata import*Bazı baytları kaydetmek için de kullanabilirsiniz - emin değilsiniz.
Stephen, 15:

4

Swift 3, 67 64 karakter

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

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

3
Bir yerleşik, gerçekten, Swift BU BUTİN İÇİN BİR BİNA var?
Zacharý

Hiç Swift Bilmiyorum ama sonra gelen boşluklara doğrayın s:String)ve .toLatin,?
Yytsi,

@TuukkaX, iyi tespit edildi!
idrougge

@ Zacharý, iyi Foundation.
idrougge

3

Python 3 , 259 bayt

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)

Çevrimiçi deneyin!

açıklama

Bu giriş formatı ile şanslıyız! Bakın girişi NFKC normalizasyonundan geçersem ne olur :

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

Dartuten yerine bir boşluk ve birleştiren dakuten alır. Şimdi bu alan は'yı dakutundan ayıran tek şey. Böylece ondan kurtulup tekrar normalleşelim :

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

Bingo. Beşinci satır, girişi şöyle bir şeye dönüştürür:

KONOSUBARASIISEKAINISISMALL YUKUHUKUWO

Sonra sıkışmış 9 sıkıcı regex ikamesi uyguluyoruz rve işimiz bitti:

KONOSUBARASHIISEKAINISHUKUFUKUWO

(Jonathan Fransız import re,unicodedata as uyerine 4 bayt kaydetti import re;from unicodedata import*. Teşekkürler!)


Eğlence ve kar için normalleşmeyi kötüye kullanmak. Bu çok güzel.
Tim Pederick

2
import re,unicodedata as uKirill L.'deki gibi ilgili bir soruna cevap 4 bayt kazandırır .
Jonathan Frech
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.