Du bist ein Romanizer, Baby

38

Bei der Umschrift auf Japanisch wird japanischer Text in lateinische Zeichen umgewandelt. In dieser Herausforderung erhalten Sie eine Zeichenfolge mit japanischen Zeichen als Eingabe und müssen diese in die richtige ASCII-Zeichenfolge konvertieren.

Was Sie wissen müssen

Die japanische Sprache hat drei Schriftsysteme: Hiragana (das kurvige für kurze Wörter), Katakana (das Winkel-Y-Schriftsystem für Laute und Wörter, die aus anderen Sprachen entlehnt wurden) und Kanji (die dichten Schriftzeichen, die ursprünglich aus dem Chinesischen stammen). Bei dieser Herausforderung werden wir uns nur um Hiragana kümmern.

Die Hiragana-Silbenschrift enthält 46 Zeichen. Jedes Zeichen steht für eine Silbe. Die Zeichen sind nach erstem Ton (Konsonant) und zweitem Ton (Vokal) organisiert. Die Spalten in der Reihenfolge sind aiueo.

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

(Wenn Sie diese Tabelle kopieren und einfügen, beachten Sie, dass ich ideografische Leerzeichen U + 3000 verwendet habe, um y und w zu löschen.)

So sollte beispielsweise あ あ と eine Ausgabe von erzeugen atome. Das erste Zeichen ist a, das zweite ist tound das dritte ist me.

Ausnahmen

Wie jede gute Sprache hat Japanisch Ausnahmen von seinen Regeln und die Hiragana-Tabelle hat mehrere. Diese Zeichen werden geringfügig anders ausgesprochen als es die Position in der Tabelle implizieren würde:

し: shi, nicht si
ち: chi, nicht ti
つ: tsu, nicht tu
ふ: fu, nichthu

Dakuten ゛

Das Wort "Dakuten" bedeutet "Schlammfleck": Das Dakuten verwandelt Töne (normalerweise) in ihre stimmhaften Entsprechungen. Zum Beispiel wird かkazu か かga. Eine vollständige Liste der Änderungen:

kg
sz
td
hb

Auch die Ausnahmen ändern sich: し し: ji(oder zhi), nicht zi
ち ち: ji, nicht di
つ つ: dzu, nicht du
(ふ ふ verhält sich wie erwartet; es ist keine Ausnahme)

Das handakuten ist ein zusätzliches Zeichen ゜, das für die hZeile gilt. Wenn es nach einem Zeichen platziert wird, ändert es den Klang des Zeichens in panstatt b.

Sowohl das Dakuten als auch das Handakuten werden als einzelne Zeichen angegeben. Sie müssen sich nicht mit vorkompositionierten Formularen oder kombinierten Zeichen befassen.

Kleine Charaktere

Schließlich gibt es kleine Versionen einiger Charaktere. Sie ändern Zeichen, die vor oder nach ihnen stehen.

ゃ ゃ ゅ

Dies sind die kleinen Formen ya, yuund yo. Sie werden nur nach Tönen in der i-Säule platziert. sie entfernen das iund fügen ihren Ton hinzu. Also verwandelt sich き き in kiya; き き verwandelt sich in kya.

Wenn sie nach chioder shi(oder ihren dakutenhaltigen Formen) platziert werden, werden sie ebenfalls yentfernt. し し ist shiyu; し し ist shu.

Das Letzte, womit Sie sich befassen müssen, ist das Kleine tsu. っ verdoppelt den Konsonanten, der danach kommt, egal was passiert; es macht nichts anderes. Zum Beispiel ist き きkita; き き っ ist kitta.

Zusammenfassung, Eingabe und Ausgabe

Ihr Programm muss in der Lage sein, die 46 Hiragana-Grundformen, ihre Dakuten- und Handakutenformen und ihre Kombinationen mit kleinen Buchstaben zu transkribieren.

Undefiniertes Verhalten beinhaltet: klein ya, yuund yonicht nach einem Charakter mit ikleinen tsuam Ende eines Strings, dakuten auf einem nicht betroffenen Charakter, auf einem nicht handakuten pCharakter, und alles , was nicht in der oben spec / Einleitung erwähnt.

Sie können davon ausgehen, dass alle Eingaben gültig sind und nur die oben genannten japanischen Zeichen enthalten.

Groß- / Kleinschreibung spielt bei der Ausgabe keine Rolle. Sie können auch rmit loder einsam nmit ersetzen m. Die Ausgabe kann entweder ein Leerzeichen zwischen jeder Silbe oder gar kein Leerzeichen enthalten.

Das ist : Der kürzeste Code in Bytes gewinnt.

Testfälle

Viele Testfälle für jedes einzelne Teil sind in der Spezifikation angegeben. Einige zusätzliche Fälle:

ひ ひ ら ゛ ゛ → hiragana

か か か か → katakana

. た ゛ い き ゛ く て ん さ い は ん → daigyakutensaiban

. ふ ゜ ろ く ゛ ら.. ゛ は ゜ ふ ふ → puroguramingupazurucoudogorufu

か か ゛ ん ほ ゛ っ → ganbatte

Anmerkungen

  • Ich kann nicht viel Japanisch außer dem, was ich hier geschrieben habe. Bitte lassen Sie mich wissen, wenn ich Fehler gemacht habe.

  • Ursprünglich plante ich, auch Katakana einzubeziehen (mein Testfall für die englische Transliteration könnte also etwas genauer sein), aber das wäre zu viel für eine Code-Golf-Herausforderung.

  • Die Unicode-Namen enthalten die Transliteration jedes Zeichens einzeln, jedoch ohne Ausnahmen. Dies kann für Sie hilfreich sein oder auch nicht.

  • Danke an squeamishossifrage für die Korrektur von zwei Tippfehlern!

  • Es tut mir leid, wenn das zu lang ist. Ich habe versucht, die meisten Macken von Hiragana in die Herausforderung einzubauen, aber einige Dinge (wie Hiragana nur mit kleinem Vokal, Änderung von n zu m vor einigen Konsonanten und das Wiederholungszeichen) mussten abgeschnitten werden, um die Herausforderung zu bewältigen.

  • Der Titel tut mir überhaupt nicht leid. Es ist ein Meisterwerk.

Deusovi
quelle
1
Wofür soll die Ausgabe sein きっった?
Lirtosiast
@Thomas: Das ist eine ungültige Eingabe. Die Ausgabe kann beliebig sein.
Deusovi
1
sollte っしsein sshioder shshi?
Lirtosiast
2
I'm not at all sorry for the title. It's a masterpiece.Downvoted
Fatalize
3
@Fatalize Keine Notwendigkeit, Ihre Anti-Britney-Tendenz hierher zu bringen. Auch wenn ich persönlich eher ein J-Lo-Fan bin, werde ich darüber kein ausgezeichnetes Rätsel ablehnen.
Semi-Extrinsic

Antworten:

7

Python 2, 638 Bytes

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)

Übernimmt die Eingabe als Unicode-Zeichenfolge.

Teste es auf Ideone

TFeld
quelle
1
Sie können ein dürftiges Wiedersehen retten, indem Sie print ''.join(R)zuprint''.join(R)
Zacharý
6

Python 2, 447 Bytes

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

Dies nimmt die Unicode-Eingabe direkt auf, wodurch ich ein paar Bytes verloren habe, decode('utf-8')aber ich denke, das liegt eher im Geiste der Herausforderung.

Ich begann damit, jedes Zeichen durch die letzten beiden Zeichen seines Unicode-Namens zu ersetzen, wie in den Notizen des Puzzles vorgeschlagen. Leider unterscheidet dies nicht zwischen alternativen Versionen desselben Zeichens, so dass ich einen hässlichen Hack ausführen musste, um ein 'x' vor den kleinen Zeichen und dem handakuten hinzuzufügen.

Die restlichen for-Schleifen beheben nur Ausnahmen, in der Reihenfolge:

  1. die erste for-Schleife verwandelt Dakutens und Handakutens in die richtigen Konsonanten;
  2. Die zweite for-Schleife behandelt die Hiragana-Ausnahmen von Shi, Chi, Tsu und Fu.
  3. Die dritte for-Schleife behandelt die Ausnahmen vor einem kleinen y-Zeichen (wie sha, jo).
  4. Die vierte for-Schleife behandelt das Verdoppeln von Konsonanten nach einem kleinen tsu.
  5. letzte Zeile befasst sich mit kleinen y-.

Ich wünschte, ich hätte mehr Schritte kombinieren können, aber in einigen Fällen müssen die Schritte ausgeführt werden, um Konflikte zu vermeiden.

Probieren Sie es online! (Eine mehrzeilige Version mit weiteren Beispielen finden Sie hier ).

ffao
quelle
1
TIO Link
Boboquack
Willkommen bei PPCG. Sehr schöne erste Lösung :)
Shaggy
Verwandeln Sie Ihre vier Leerzeichen vor for b in'AEIOU'in einen Tabulator oder ein einzelnes Leerzeichen, um 3 Bytes zu sparen. Sie können möglicherweise auch verwenden from unicodedata import*, um einige Bytes zu speichern - nicht sicher.
Stephen
4

Swift 3, 67 64 Zeichen

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

let r={(s:String)in s.applyingTransform(.toLatin,reverse:false)}
idrougge
quelle
3
Ein Builtin, wirklich, Swift hat ein BUILTIN FÜR DIESES?
Zacharý
Ich kenne Swift überhaupt nicht, aber kannst du die Leerzeichen nach s:String)und hacken .toLatin,?
Yytsi
@ TuukkaX, gut gesehen!
Idrougge
@ Zacharý, gut Foundationhat.
Idrougge
3

Python 3 , 259 Bytes

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)

Probieren Sie es online!

Erläuterung

Wir haben Glück mit diesem Eingabeformat! Schauen Sie, was passiert, wenn ich die Eingabe durch die NFKC-Normalisierung leite :

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

Das Dakuten wird durch ein Leerzeichen und ein kombinierendes Dakuten ersetzt. Jetzt ist dieser Raum alles, was das は von seinem Dakuten trennt. Also werden wir es los und normalisieren wieder :

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

Bingo. Die fünfte Zeile verwandelt die Eingabe in so etwas wie

KONOSUBARASIISEKAINISISMALL YUKUHUKUWO

Dann wenden wir 9 langweilige Regex-Substitutionen an r, und wir sind fertig:

KONOSUBARASHIISEKAINISHUKUFUKUWO

(Jonathan French sparte 4 Bytes und schrieb import re,unicodedata as ustattdessen import re;from unicodedata import*. Danke!)

Lynn
quelle
Missbrauch der Normalisierung für Spaß und Gewinn. Das ist schön.
Tim Pederick
2
import re,unicodedata as uWie bei Kirill L. spart die Antwort auf eine damit verbundene Herausforderung 4 Bytes .
Jonathan Frech