Output the next kana

21

2

Japanese kana characters correspond to a single sound in the Japanese language. With the exception of ん (n), every other kana consists of a consonant part and a vowel part. There is a natural ordering to Japanese kana, a sort of "alphabetical order", which is typically arranged in a 10 by 5 table:

   |   a    i    u    e    o
-----------------------------
*  |   a    i    u    e    o
k  |  ka   ki   ku   ke   ko
s  |  sa   si   su   se   so
t  |  ta   ti   tu   te   to
n  |  na   ni   nu   ne   no
h  |  ha   hi   hu   he   ho
m  |  ma   mi   mu   me   mo
y  |  ya        yu        yo
r  |  ra   ri   ru   re   ro
w  |  wa                  wo

This ordering is called gojuuon, or "fifty sounds", even though some of the fifty cells in the table are in fact empty.

The challenge

Input will be any of the listed kana above, with the exception for wo. Your program or function should output the next kana along in left-to-right, top-to-bottom reading order, e.g:

Input       Output
------------------
a     ->    i
i     ->    u
o     ->    ka
ke    ->    ko
so    ->    ta
ni    ->    nu
ya    ->    yu
yu    ->    yo
wa    ->    wo
wo    ->    (undefined behaviour)

With the exception of an optional single trailing newline, there should be no leading or trailing whitespace in the output.

This is , so the goal is to minimise program size, in bytes.

Additional notes

  • In order to keep things simple, this challenge uses Nihon-shiki romanisation. Hepburn romanisation is more common, but has a few kinks which make things more annoying for golf (e.g. si becomes shi, hu becomes fu).

  • Kana do exist for the empty spots (see Japanese SE), but they were either non-standard or are now obsolete.

Sp3000

Posted 2016-01-06T21:53:01.000

Reputation: 58 729

3I think it would be much more fun to use the Hepburn exceptions and make wo transform to n which loops to a. – Jan – 2016-01-07T13:22:35.980

Answers

16

Retina, 54 53 bytes

T`au`ie`y.
wa
we
T`\oeuia`ao
T`ko`stn\hmyr\w`.a
^a
ka

Try it online.

Explanation

Wooo, showing off even more features from today's 0.7.2 release. :) (The release predates this challenge by about 7 hours.)

T`au`ie`y.

This is a transliteration which replaces a with i and u with e, but only in matches of y.. The purpose of that is to treat ya and yu like yi and ye, respectively, in order to skip the gaps.

wa
we

Replace wa with we to skip that gap as well.

T`\oeuia`ao

Here is the new feature. When rotating sets of characters, the "from" and "to" set in a transliteration are usually almost identical. So now we've got o (without a backslash) to refer to the other set, which allows us to get rid of some duplication. The \o just stands for a literal o in that case. So the two sets expand to:

oeuia
aoeuia

The extraneous a in the second set is ignored and the vowels are replaced cyclically as expected.

T`ko`stn\hmyr\w`.a

This does the same thing for the consonants, but using o in the first set (just because we can...). h and w need escaping because they are character classes. The expanded sets are:

kstnhmyrw
stnhmyrw

The .a restricts this operation to syllables that end in a, i.e. those that wrap to the next line of the table.

^a
ka

Finally, we replace a single a with ka, because that case cannot be handled by the previous transliteration.

Martin Ender

Posted 2016-01-06T21:53:01.000

Reputation: 184 808

Doesn't using a version of your language released after the challenge was posted disqualify your entry from competing? (Guess why I asked about this in that other place? ;)

– Alex – 2016-01-08T13:27:58.357

@Alex I released that version before this challenge was posted. – Martin Ender – 2016-01-08T13:29:57.407

Okay. My apologies. Your edit made it appear otherwise. I just verified your list of releases (probably should've done that before throwing accusations around). – Alex – 2016-01-08T13:32:02.360

5

Pyth, 42 40 38 bytes

s.r]z.DrR6*" kstnhmyrw""aiueo"CM"$&./0

This takes the outer product between vowels and consonants, and removes elements at the ords of each number in $&./0. Then it outputs the element after the input.

@J.DrR6*" kstnhmyrw""aiueo"CM"$&./0"hxJz    Implicit: z=input()
       *" kstnhmyrw""aiueo"                 Outer product: [' a',...,' o','ka',...]
    rR6                                     Strip each string—'a'~'o' now single letters
                           CM"$&./0"        Map ord onto the string: [36,38,46,47,48]
  .D                                        Remove elements at those indices.
 J                                          That's the list of kana; assign it to J
                                     xJz    Find the index (x) of z in J,
                                    h       add one,
@J                                          and access J at that index.

Try it here.

lirtosiast

Posted 2016-01-06T21:53:01.000

Reputation: 20 331

Wow, this language is crazy! – Just a learner – 2018-09-11T10:50:11.803

5

Ruby, 105

->n{a=['wo','wa']
'rymhntsk '.chars{|c|a+='*o *e *u *i *a'.tr(?*,c).split}
a[8..10]='yu'
a[a.index(n)-1]}

Commented in test program

f=->n{a=['wo','wa']                     #initialize array to last line of table, begin to build table backwards                                
  'rymhntsk '.chars{|c|                 #for each consonant, 
    a+='*o *e *u *i *a'.tr(?*,c).split  #perform a sustitution to get that line of table in string form,  
  }                                     #then split into array at spaces and append to a
  a[8..10]='yu'                         #substitute 3 elements ye yu yi with 1 element yu
  a[a.index(n)-1]                       #return element before argument (array is backwards.)
}

puts f[gets.chop]

Level River St

Posted 2016-01-06T21:53:01.000

Reputation: 22 049

You can save a few bytes with a=%w{wo wa}. – Jordan – 2016-09-15T22:45:53.530

Also: "rymhntsk ".chars{|c|"oeuia".chars{|d|a<<c+d}}, although I have a sneaking suspicion it could be golfed further. – Jordan – 2016-09-15T23:02:23.787

5

GNU sed, 65

Comments not included in score:

:                        # Define unnamed label
y/aiueo/iueoa/           # Rotate vowels
/a/y/kstnhmyr/stnhmyrw/  # If at end of row, rotate consonants
s/^a/ka/                 # If at end of 1st row, prefix a "k"
/[yw][ie]\|wu/b          # If one of the invalid values, jump back to label and redo

Oy, this is beginning to look a lot like @Martin's Retina answer (but longer, of course).

Digital Trauma

Posted 2016-01-06T21:53:01.000

Reputation: 64 644

3

TXR Lisp, 135 127 124 91 bytes

(ret[(memqual @1(diff(maprod(op trim-str`@1@2`)" kstnhmyrw""aiueo")'#"yi ye wi wu we"))1])

Run:

1> (ret[(memqual @1(diff(maprod(op trim-str`@1@2`)" kstnhmyrw""aiueo")'#"yi ye wi wu we"))1])
#<interpreted fun: lambda (#:arg-1-0208 . #:arg-rest-0207)>
2> [*1 "a"]
"i"
3> [*1 "o"]
"ka"
4> [*1 "ki"]
"ku"
5> [*1 "mu"]
"me"
6> [*1 "ya"]
"yu"
7> [*1 "yo"]
"ra"
8> [*1 "wa"]
"wo"

Kaz

Posted 2016-01-06T21:53:01.000

Reputation: 372

1

JavaScript, 145 162 131 118 bytes

x=>(d=" kstnhmyrw".replace(/./g,"$&a$&i$&u$&e$&o").replace(/ |yi|ye|wiwuwe/g,"").match(/[^aiueo]?./g))[d.indexOf(x)+1]

Admit it, you couldn't imagine a more ridiculous solution to solve this problem ;) ok, done this in a more interesting way.

Demo:

function p(x) {
  return (d=" kstnhmyrw".replace(/./g,"$&a$&i$&u$&e$&o") //build the sequence of kana, regex rulez!
        .replace(/ |yi|ye|wiwuwe/g,"")                   //remove the spaces and excess kana
        .match(/[^aiueo]?./g))[d.indexOf(x)+1]           //split it into array using regex and get the index of input in it
}

alert(p(prompt()))

nicael

Posted 2016-01-06T21:53:01.000

Reputation: 4 585

@Sp3000 Oh, that's a pity, you should then mention that these excess (trailing/leading) spaces ain't allowed. – nicael – 2016-01-06T22:43:48.610

@nicael I don't see anything in the spec implying that they are currently allowed. – Martin Ender – 2016-01-06T22:49:34.630

@Sp3000 fixed spacing. – nicael – 2016-01-06T22:53:57.333

1

Bash + sed, 83

echo {,k,s,t,n,h,m,y,r,w}{a,i,u,e,o}|sed -E "s/[yw][ie]|wu//g;s/.*\b$1 +//;s/ .*//"
  • Brace expansion to create full table on one line
  • sed to:
    • remove yi, ye, wi, wu and we
    • remove everything up to and including the input entry (but not the next entry)
    • remove everything after the next entry

Digital Trauma

Posted 2016-01-06T21:53:01.000

Reputation: 64 644

1

Haskell, 114 96 bytes

f"ya"="yu"
f"yu"="yo"
f"wa"="wo"
f x=snd(span(/=x)[words[a,b]!!0|a<-" kstnhmyrw",b<-"aiueo"])!!1

[words[a,b]!!0|a<-" kstnhmyrw",b<-"aiueo"] is a list of all kanas, including the "holes". I break up the list into the part before the input kana and from the input kana up to the end. From the 2nd part I pick the second element. The exceptions around the "holes" a caught before by separate cases.

Edit: @xnor came up with the idea of using spanwhich saved 18 bytes.

nimi

Posted 2016-01-06T21:53:01.000

Reputation: 34 639

Would something like (snd$span(/=x)k)!!1 not work for the lookup? – xnor – 2016-01-07T06:43:07.833

@xnor: now that I see it, it's obvious. Thanks so much! – nimi – 2016-01-07T18:53:36.690

1

Japt, 75 70 68 bytes

X=" kstnhmyrw"£"aiueo"®+X w} r" |yi|ye|wiwuwe"P f"[^aiueo]?.")g1+XbU

Try it online!

nicael

Posted 2016-01-06T21:53:01.000

Reputation: 4 585

Pretty nice! I tried to golf this down more, but I could only chop off 3 bytes: X=" kstnhmyrw"£"aiueo"mZ{X+Z} } r" |yi|ye|wiwuwe"P f"[^aiueo]?.")g1+XbU – ETHproductions – 2016-01-07T18:21:30.250

@Eth yeah, and also you've got an excess space in } } :) – nicael – 2016-01-07T18:38:29.390

Ohhhh right, I forgot that was automatically added :) – ETHproductions – 2016-01-07T18:44:56.267

@Eth look, we can get it two bytes shorter with your magic shortcuts :D – nicael – 2016-01-07T18:50:15.827

Wait, that actually works? Nice, you've outgolfed me ;) – ETHproductions – 2016-01-07T18:51:23.253

@Eth note, w, otherwise obviously doesn't ;) – nicael – 2016-01-07T18:52:54.597

0

Perl 6, 105 bytes

.[.first(@*ARGS[0],:k)+1].say with (" kstnhmyrw".comb X~ <a e i o u>).grep(* !~~/[y|w][i|e]|wu/)».trim

This is as short as I can get it on my first go, I might have another crack at it later but I feel pretty good about this.

Hotkeys

Posted 2016-01-06T21:53:01.000

Reputation: 1 015

0

JavaScript (ES6), 127 bytes

s=>s>"yt"?"yo":s=="ya"?"yu":s=="wa"?"wo":(m=[].concat(...["",..."kstnhmyrw"].map(c=>[..."aiueo"].map(v=>c+v))),m[m.indexOf(s)+1])

Explanation

s=>

  // Hardcode "yu", "ya" and "wa"
  s>"yt"?"yo":
  s=="ya"?"yu":
  s=="wa"?"wo":

  // Generate table
  (m=[].concat(...                                   // flatten the array of arrays
    ["",                                             // first consonant is blank
    ..."kstnhmyrw"].map(c=>[..."aiueo"].map(v=>c+v)) // combine each consonant and vowel
  ))[m.indexOf(s)+1]                                 // return the next sound

Test

var solution = s=>s>"yt"?"yo":s=="ya"?"yu":s=="wa"?"wo":(m=[].concat(...["",..."kstnhmyrw"].map(c=>[..."aiueo"].map(v=>c+v))),m[m.indexOf(s)+1])
<input type="text" id="input" value="mo" />
<button onclick="result.textContent=solution(input.value)">Go</button>
<pre id="result"></pre>

user81655

Posted 2016-01-06T21:53:01.000

Reputation: 10 181

0

Perl 6, 96 bytes

{my @a=(" kstnhmyrw".comb X~ <a i u e o>).grep({!/[y|w][e|i]|wu/})>>.trim;@a[1+@a.first($_,:k)]}

bb94

Posted 2016-01-06T21:53:01.000

Reputation: 1 831

0

C, 138 135 bytes

char*s="aiueokstnhmyrw";i,j;k(*v){j=strchr(s,*v>>8)-s;i=strchr(s,*v)-s;j=i<4?i++:j<4?j-~(2520%i&3):!++i;printf("%c%c",s[i],i<5?:s[j]);}

Wandbox

o79y

Posted 2016-01-06T21:53:01.000

Reputation: 509

0

Python 2, 107 bytes

L=[(x+y).lstrip()for x in' kstnhmyrw'for y in'aiueo'if x+y not in'yiyewiwuwe']
print L[L.index(input())+1]

Expects input enclosed in quotes, 'he' for example

Karl Napf

Posted 2016-01-06T21:53:01.000

Reputation: 4 131

0

Racket 151 bytes

(second(member s '(a i u e o ka ki ku ke ko sa si su se so ta ti tu te to na
ni nu ne no ha hi hu he ho ma mi mu me mo ya yu yo ra ri ru re ro wa wo)))

Ungolfed:

(define (f s)
  (second
   (member s
           '(a i u e o ka ki ku ke ko sa si su se so ta ti tu te to na ni nu ne
               no ha hi hu he ho ma mi mu me mo ya yu yo ra ri ru re ro wa wo))))

Testing:

(f 'a)
(f 'i)
(f 'o)
(f 'ke)
(f 'so)
(f 'ni)
(f 'ya)
(f 'yu)
(f 'wa)

Output:

'i
'u
'ka
'ko
'ta
'nu
'yu
'yo
'wo

There is an error message if 'wo is sent.

rnso

Posted 2016-01-06T21:53:01.000

Reputation: 1 635