18
\$\begingroup\$

Briefing

Aliens have settled on earth and strangely enough, their alphabet is the exact same as ours. Their language is also very similar to ours with some very distinct and easy to compute differences.

Challenge

Take a string and output the alien's language equivalent. The translation works as such:

Swap all the vowels in the word with the corresponding:

  Vowel |   With
--------+--------
   a    |   obo
   e    |   unu
   i    |   ini
   o    |   api
   u    |   iki

You may also write another translator to translate Alien->English, this is optional however.

Examples

Input: Shaun
Output: Shoboikin

Input: Java
Output: Jobovobo

Input: Hello, World!
Output: Hunullapi, Wapirld!

If the vowel is capitalized then you capitalize the first letter..

Input: Alan
Output: Obolobon

Input: Australia
Output: Oboikistroboliniobo

Rules

  • Standard loopholes apply
  • Must work for text that contains new lines
  • You can either write a function, lambda, or full program

    Capingrobotikilobotiniapins apin wrinitining thunu runuvunursunu trobonslobotapir!

\$\endgroup\$
7
  • \$\begingroup\$ I'm not sure what You may also write another translator to translate Alien->English is supposed to mean. Can we write the reverse translator instead of the regular one? \$\endgroup\$
    – Dennis
    Sep 16, 2016 at 15:22
  • 4
    \$\begingroup\$ Maybe it's just me, but it's not obvious to me that also carries this meaning here. Anyway, I'm not sure how this is a rule if it's not part of the actual task. \$\endgroup\$
    – Dennis
    Sep 16, 2016 at 15:55
  • \$\begingroup\$ @Dennis You're being a bit punudobontinic, but I've edited it to make it clearer. \$\endgroup\$
    – Shaun Wild
    Sep 16, 2016 at 16:14
  • 2
    \$\begingroup\$ Why the requirement for newlines? In my opinion, this is unnecessary and doesn't add anything to the main point of the challenge. \$\endgroup\$
    – Adnan
    Sep 16, 2016 at 16:53
  • 1
    \$\begingroup\$ Can the input contain any ASCII character or only a subset. E.g., will there ever be numbers in the input? \$\endgroup\$
    – Riley
    Sep 16, 2016 at 19:05

26 Answers 26

14
\$\begingroup\$

Haskell, 100 91 bytes

(>>= \x->last$[x]:[y|(z:y)<-words"aobo eunu iini oapi uiki AObo EUnu IIni OApi UIki",z==x])
\$\endgroup\$
1
  • 5
    \$\begingroup\$ Hoboskunull surely \$\endgroup\$
    – jk.
    Sep 16, 2016 at 14:32
12
\$\begingroup\$

TI-Basic, 173 + 59 + 148 = 380 bytes

Hopefully the aliens use TI-83/84 calculators ;)

Main Program, 173 bytes

BONUS: Keep second or third line depending on whether your want a normal or reverse translator.

"("+Ans+")→Str1
"@a~obo@A~Obo@e~unu@E~Unu@i~ini@I~Ini@o~api@O~Api@u~iki@U~Iki@→Str2    <-- English to Alien
"@obo~a@Obo~A@unu~e@Unu~E@ini~i@Ini~I@api~o@Api~O@iki~u@Iki~U@→Str2    <-- Alien to English
For(I,2,length(Ans
If "@"=sub(Str2,I-1,1
Then
Str1+"~"+sub(Str2,I,inString(Str2,"@",I)-I
prgmQ
Ans→Str1
End
End

Subprogram (prgmQ), 59 bytes:

Ans→Str9
inString(Ans,"~
sub(Str9,Ans,length(Str9)-Ans+1→Str8
Str9
prgmR
Repeat Str9=Ans+Str8
Ans+Str8→Str9
prgmR
End

Subprogram (prgmR), 148 bytes:

Ans→Str0
inString(Ans,"~→Z
inString(Str0,"~",Ans+1→Y
inString(sub(Str0,1,Z-1),sub(Str0,Z+1,Ans-Z-1→X
sub(Str0,1,-1+inString(Str0,"~
If X
sub(Str0,1,X-1)+sub(Str0,Y+1,length(Str0)-Y)+sub(Str0,X+length(sub(Str0,Z+1,Y-Z-1)),Z-X-length(sub(Str0,Z+1,Y-Z-1

P.S. ~ represents token 0x81 and @ represents token 0x7F, learn more here.

P.P.S. Part of why these programs have a high byte count is because sub(, inString(, length(, and all lowercase letters are two bytes each...

\$\endgroup\$
2
  • \$\begingroup\$ I think you mixed up prgmR and prgmQ in your code headlines once? \$\endgroup\$ Sep 17, 2016 at 0:01
  • \$\begingroup\$ Yes, thanks for catching that @ByteCommander :) \$\endgroup\$
    – Timtech
    Sep 17, 2016 at 13:31
8
\$\begingroup\$

Perl, 56 bytes

Includes +1 for -p

Give input on STDIN

alien.pl:

#!/usr/bin/perl -p
s%\w%"`"&$&|("A\x0fboE\x15nuI\x09niO\x01piU\x09ki"=~/\u$&\K.../,$&)%eg

Works as shown, but replace the \xXX escapes by the actual character to get the claimed score

\$\endgroup\$
2
  • 1
    \$\begingroup\$ +1 Upvoted just for the Alien avatar. Just kidding, the solution is nice, also. \$\endgroup\$
    – Chaotic
    Sep 16, 2016 at 22:24
  • 1
    \$\begingroup\$ Jesus christ.. Perl at its best, ladies and gents. \$\endgroup\$ Sep 17, 2016 at 14:05
6
\$\begingroup\$

sed 89

s,a,&b\n,gi
s,i,&n\r,gi
s,o,&p\r,gi
s,u,&k\r,gi
s,e,&n\f,gi
y,aeouAEOU\n\r\f,ouaiOUAIoiu,
\$\endgroup\$
4
  • \$\begingroup\$ Does this work for input that contains newlines? \$\endgroup\$
    – Jordan
    Sep 16, 2016 at 16:12
  • \$\begingroup\$ @Jordan It does. sed reads "one line at a time". So it will process everything up to the first newline, print that, print a newline, then start over if there is more text. \$\endgroup\$
    – Riley
    Sep 16, 2016 at 16:20
  • \$\begingroup\$ Ah, of course. 👍🏻 \$\endgroup\$
    – Jordan
    Sep 16, 2016 at 16:25
  • \$\begingroup\$ @Jordan That wasn't a rule when I wrote this, but it ended up working anyway. \$\endgroup\$
    – Riley
    Sep 16, 2016 at 16:26
6
\$\begingroup\$

Python, 99 95 93 bytes

lambda s:"".join(("ouiaiOUIAI bnnpkbnnpk ouiiiouiii"+c)["aeiouAEIOU".find(c)::11] for c in s)

On ideone.com...

Pretty simple. Just take the index we find each character at in the vowel list and use it to pull the three characters we need. If it's not found, .find() returns -1 so just stick the current character on the end of the string. The spaces are necessary so any letter "a" doesn't include the added c. The translated vowels are grouped by letter order (the first letter of every translation, then the second, then the third).

\$\endgroup\$
2
  • \$\begingroup\$ Wow, nice creative approach. I'm impressed :) \$\endgroup\$ Sep 17, 2016 at 0:03
  • 1
    \$\begingroup\$ You can remove the space in ["aeiouAEIOU".find(c)::11] for \$\endgroup\$
    – acrolith
    Sep 21, 2016 at 22:30
6
\$\begingroup\$

05AB1E, 28 27 20 bytes

žÀ.•₅%~≠#ùÛãú•3ôD™«‡

Try it online!

Unuxplobonobotiniapin

žÀ                    # the string "aeiouAEIOU"
  .•₅%~≠#ùÛãú•        # the string "obounuiniapiiki"
              3ô      # split in pieces of 3
                D™«   # concatenate with a title-case copy
                   ‡  # transliterate
\$\endgroup\$
6
  • 2
    \$\begingroup\$ Ini lapivunu gapilfining! \$\endgroup\$
    – Shaun Wild
    Sep 16, 2016 at 11:57
  • \$\begingroup\$ @BasicallyAlanTuring: Took me way too long to translate that in my head. I think I need a reverse translator :P \$\endgroup\$
    – Emigna
    Sep 16, 2016 at 11:59
  • 2
    \$\begingroup\$ Go for it, shouldn't be too hard :P \$\endgroup\$
    – Shaun Wild
    Sep 16, 2016 at 12:03
  • \$\begingroup\$ Scary, I think it says I love golf. \$\endgroup\$
    – datagod
    Sep 16, 2016 at 14:58
  • \$\begingroup\$ I've changed my question which makes you answer invalid. This must work with new lines \$\endgroup\$
    – Shaun Wild
    Sep 16, 2016 at 15:31
5
\$\begingroup\$

PHP , 91 Bytes

<?=strtr($argv[1],[A=>Obo,E=>Unu,I=>Ini,O=>Api,U=>Iki,a=>obo,e=>unu,i=>ini,o=>api,u=>iki]);
\$\endgroup\$
5
\$\begingroup\$

Python, 129 bytes

lambda s:"".join([str,str.capitalize][ord(l)<91]({"a":"obo","e":"unu","i":"ini","o":"api","u":"iki"}.get(l.lower(),l))for l in s)

See it running on ideone.com

Here's a more nicely formatted version:

lambda s: \
    "".join(
        [str, str.capitalize][ord(l) < 91](
            {"a":"obo", "e":"unu", "i":"ini", "o":"api", "u":"iki"}
            .get(l.lower(), l)
        )
    for l in s)

The most interesting parts are { ... }.get(l.lower(), l) which tries to look up the letter stored in l converted to lower case in the dictionary and either returns the translated version (if found), or else the original letter,
and [str, str.capitalize][ord(l) < 91]( ... ) which checks whether the original letter was a capital letter (ASCII code point lower than 91) and then either calls the str() function with the letter as argument (if it wasn't a capital letter, does nothing) or the str.capitalize() function (converts the first letter of the argument string to upper case).

\$\endgroup\$
4
\$\begingroup\$

Batch, 215 bytes

@echo off
set/pt=
set s=
:l
if "%t%"=="" echo(%s%&exit/b
set c=%t:~0,1%
for %%a in (obo.a unu.e ini.i api.o iki.u Obo.A Unu.E Ini.I Api.O Iki.U)do if .%c%==%%~xa set c=%%~na
set s=%s%%c%
set t=%t:~1%
goto l

Takes input on STDIN. Processing character-by-character has the convenience of being case-sensitive.

\$\endgroup\$
1
  • \$\begingroup\$ Batch is just the worst tool for everything, isn't it? (Well, at least you beat TI-Basic :) Nice seeing a codegolf in Batch, by the way! \$\endgroup\$
    – yyny
    Sep 17, 2016 at 0:30
4
\$\begingroup\$

Pyth, 42 bytes

#sXw"aeiouAEIOU"+Jc"obounuiniapiiki"3mrd3J

A program that takes input on STDIN and prints the output.

Try it online

How it works

#sXw"aeiouAEIOU"+Jc"obounuiniapiiki"3mrd3J  Program.
#                                           Loop until error statement:
   w                                         Get w, the next line of the input
                   "obounuiniapiiki"         Yield string literal "obounuiniapiiki"
                  c                 3        Split that into groups of three characters
                 J                           Assign that to J and yield J
                                     mrd3J   Map title case over J
                +                            Merge the lower and title groups
    "aeiouAEIOU"                             Yield string literal "aeiouAEIOU"
  X                                          Translate w from that to the three-character
                                             groups
 s                                           Concatenate that
                                             Implicitly print
\$\endgroup\$
4
\$\begingroup\$

C, 167 bytes

I really didn't want to break my habit of always doing main functions when coding C, but this is substantially shorter than the version with a main and this way I got another letter to spell what I wanted!

Golfed

a;l;i;e(char*n){for(;i=*n++;l=i>90,i-=32*l,a=!(i-65)+2*!(i-69)+3*!(i-73)+4*!(i-79)+5*!(i-85),printf(a?"%c%c%c":"%c",(a?"HOUIAI"[a]:i)+l*32,"ibnnpk"[a],"!ouiii"[a]));}

Commented

a;l;i;
e(char*n)
{
    for(;
        i = *n++;  /* Get char and advance */
        l = i>90,  /* Is lowercase? */
        i -= 32*l, /* Make uppercase */

        /* Is 1,2,3,4,5 depeding on the vowel and 0 for no vowel */
        a = !(i-65) + 2*!(i-69) + 3*!(i-73) + 4*!(i-79) + 5*!(i-85),

        printf(a?"%c%c%c":"%c",        /* Print 1 or 3 chars? */
               (a?"HOUIAI"[a]:i)+l*32, /* Print appropriate char+case */
                  "ibnnpk"[a],            /* Print appropriate char */
                  "!ouiii"[a]));          /* Print appropriate char */
}

There is something special about C and how horrible you can be with pointers and such.

\$\endgroup\$
2
  • \$\begingroup\$ 151 bytes \$\endgroup\$
    – ceilingcat
    Feb 24, 2019 at 13:41
  • \$\begingroup\$ @ceilingcat I'd say post your answer on its own. It's diverged enough to deserve its own answer. :) \$\endgroup\$
    – algmyr
    Feb 24, 2019 at 13:47
4
\$\begingroup\$

C (gcc), 150 141 136 134 bytes

a;i;e(char*n){for(char*v=" AEIOUIAI",*t;i=*n++;printf(&a))t=index(v,i-i/96*32),a=t?t-v:0,a=a?v[a+3]|L" 潢畮楮楰楫"[a]<<8|i&32:i;}

Try it online!

Based on the answer by @algmyr and -8 thanks to @ASCII-only

Less golfed version

a;i;
e(char*n){
  for(char*v=" AEIOUIAI",*t;i=*n++;printf(&a))
    t=index(v,i-i/96*32),
    a=t?t-v:0,
    a=a?v[a+3]|L" 潢畮楮楰楫"[a]<<8|i&32:i;
}
\$\endgroup\$
3
  • \$\begingroup\$ 149? a;l;i;e(char*n){for(char*v=" AEIOU",*t;i=*n++;printf("%c%c%c"+4*!a,(a?" OUIAI"[a]:i)|i&32," bnnpk"[a]," ouiii"[t=index(v,i-32*l),a=t?t-v:0]))l=i>96;} \$\endgroup\$
    – ASCII-only
    Feb 25, 2019 at 1:58
  • \$\begingroup\$ maybe also 149: a;l;i;e(char*n){for(char*v="AEIOU",*t;i=*n++;printf("%c%c%c"+4*!a,(a?" OUIAI"[a]:i)|i&32," bnnpk"[a]," ouiii"[t=index(v,i&95),a=t&&t-v<5?t-v+1:0]));} \$\endgroup\$
    – ASCII-only
    Feb 25, 2019 at 2:01
  • \$\begingroup\$ 144: a;l;i;e(char*n){for(char*v=" AEIOU",*t;i=*n++;)printf("%c%c%c"+4*!a,a?" OUIAI"[a]|i&32:i," bnnpk"[a]," ouiii"[t=index(v,i-i/96*32),a=t?t-v:0]);} \$\endgroup\$
    – ASCII-only
    Feb 25, 2019 at 2:02
3
\$\begingroup\$

Retina, 60 bytes

Byte count assumes ISO 8859-1 encoding.

[A-Z]
»$&
T`L`l
i
ini
u
iki
e
unu
a
·b·
o
api
·
o
T`»l`_L`».

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Javascript (ES6), 94 93 92 bytes

s=>s.replace(/[aeiou]/gi,c=>"OUIAIouiai"[n="AEIOUaeiou".search(c)]+"bnnpk"[n%=5]+"ouiii"[n])

Saved 1 byte thanks to edc65
Saved 1 byte thanks to Neil

Demo

let f =
s=>s.replace(/[aeiou]/gi,c=>"OUIAIouiai"[n="AEIOUaeiou".search(c)]+"bnnpk"[n%=5]+"ouiii"[n])

function translate() {
  document.getElementById("o").value = f(document.getElementById("i").value);
}
translate();
<input id="i" size=80 oninput="translate()" value="Hello, World!"><br><input id="o" size=80 disabled>

\$\endgroup\$
3
  • 1
    \$\begingroup\$ To check the return value of .indexOf and .search use ~ instead of <0 \$\endgroup\$
    – edc65
    Sep 16, 2016 at 14:33
  • 1
    \$\begingroup\$ I looked to see what would happen if you only replaced vowels, and I originally got s=>s.replace(/[aeiou]/gi,c=>"ouiaiOUIAI"[n="aeiouAEIOU".indexOf(c)]+"bnnpk"[n%=5]+"ouiii"[n]) which is still 93 bytes. But since c is now known to be a vowel you can now use search instead of indexOf to save a byte! \$\endgroup\$
    – Neil
    Sep 17, 2016 at 10:13
  • \$\begingroup\$ @Neil - Nice! I tried both, actually, but didn't think about combining them. \$\endgroup\$
    – Arnauld
    Sep 17, 2016 at 10:33
2
\$\begingroup\$

Java 8, 172 bytes

String f(String s){String v="AEIOUaeiou",r="OboUnuIniApiIkiobounuiniapiiki",o="";for(char c:s.toCharArray()){int n=v.indexOf(c);o+=n>-1?r.substring(n*3,n*3+3):c;}return o;}

ungolfed:

String f(String s){
    String v="AEIOUaeiou",r="OboUnuIniApiIkiobounuiniapiiki",o="";
    for(char c:s.toCharArray()){
        int n=v.indexOf(c);
        o+=n>-1?r.substring(n*3,n*3+3):c;
    }
    return o;
}

And Alien back to English (171 bytes):

String g(String s){String[] v="AEIOUaeiou".split(""),r="Obo Unu Ini Api Iki obo unu ini api iki".split(" ");for(int i=0;i<v.length;i++)s=s.replaceAll(r[i],v[i]);return s;}

Ungolfed:

String g(String s){
    String[] v="AEIOUaeiou".split(""),r="Obo Unu Ini Api Iki obo unu ini api iki".split(" ");
    for(int i=0;i<v.length;i++)s=s.replaceAll(r[i],v[i]);
    return s;
}
\$\endgroup\$
2
\$\begingroup\$

Tcl, 75 bytes

String to be translated is in the variable s.

string map {A Obo a obo E Unu e unu I Ini i ini O Api o api U Iki u iki} $s
\$\endgroup\$
2
\$\begingroup\$

Mathematica, 128 bytes

#~StringReplace~{"a"->"obo","A"->"Obo","e"->"unu","E"->"Unu","i"->"ini","I"->"Ini","o"->"api","O"->"Api","u"->"iki","U"->"Iki"}&

Not sure whether a shorter program can be obtained by using IgnoreCase->True together with a case check.

\$\endgroup\$
2
\$\begingroup\$

C 178 bytes

char*p[256],*a="obo\0unu\0ini\0api\0iki\0Obo\0Unu\0Ini\0Api\0Iki",*b="aeiouAEIOU";main(c){for(c=0;b[c];++c)p[b[c]]=a+4*c;for(;(c=getchar())>0;)p[c]?printf("%s",p[c]):putchar(c);}
\$\endgroup\$
2
  • 1
    \$\begingroup\$ 153 bytes \$\endgroup\$
    – ceilingcat
    May 3, 2019 at 17:34
  • \$\begingroup\$ @ceilingcat &c can be ok if it save number as byte1 byte2 byte3... For example 255 in memory as ff 00 00 00 but if there is the other endian for 255 we have 00 00 00 ff and print the void string ... \$\endgroup\$
    – user58988
    May 11, 2019 at 18:33
2
\$\begingroup\$

C, 163 162 159 bytes

char*t="aeiou";n,k;q(char*x){for(;*x;n<0||(*x=t[n>1?n%2?0:2:n+3])&&k>90||(*x-=32),printf("%c%.2s",*x++,n<0?"":&"bonunipiki"[2*n]))n=strchr(t,tolower(k=*x))-t;}
\$\endgroup\$
2
  • \$\begingroup\$ putting char*t="aeiou"; into for loop saves 1 byte \$\endgroup\$ May 3, 2019 at 2:21
  • \$\begingroup\$ 144 bytes \$\endgroup\$
    – ceilingcat
    May 3, 2019 at 18:16
2
\$\begingroup\$

C#, 133 121 bytes

s=>{int i;return string.Concat(s.Select(c=>(i ="AIUEOaiueo".IndexOf(c))>-1?"OboIniIkiUnuApioboiniikiunuapi".Substring(i*3,3):c+""));}

Edit (thanks to milk)

thank you :) I actually know this overload but somehow completely forgot it when writing this..

s=>string.Concat(s.Select((c,i)=>(i="AIUEOaiueo".IndexOf(c))>-1?"OboIniIkiUnuApioboiniikiunuapi".Substring(i*3,3):c+""));
\$\endgroup\$
1
  • \$\begingroup\$ You can use the Select(char, int) overload so you don't need to declare i and can put it all in one line. s=>string.Concat(s.Select((c,i)=>(i="AIUEOaiueo".IndexOf(c))>-1?"OboIniIkiUnuApioboiniikiunuapi".Substring(i*3,3):c+"")); \$\endgroup\$
    – milk
    Sep 16, 2016 at 23:52
2
\$\begingroup\$

C, 207 202 bytes (thanks to Cyoce)

#include <stdio.h>
#define r(c,t) case c:printf(t);continue;
int main(){int c;while(~(c=getchar())){switch(c){r('a',"obo")r('e',"unu")r('i',"ini")r('o',"api")r('u',"iki")default:putchar(c);}}return 0;}

1) I hate to omit type before any kind of declarations

2) I don't really like to put unusable code (without main() function)

Usage:

c89 cg.c -o cg; echo "Testing" | ./cg
\$\endgroup\$
4
  • \$\begingroup\$ Welcome to PPCG! \$\endgroup\$ Sep 18, 2016 at 14:12
  • \$\begingroup\$ @MartinEnder, that's unexpected... but thank you :) \$\endgroup\$
    – Xdevelnet
    Sep 18, 2016 at 17:51
  • \$\begingroup\$ (c=getchar())!= EOF can become ~(c=getchar()) \$\endgroup\$
    – Cyoce
    Sep 20, 2016 at 1:00
  • \$\begingroup\$ 143 bytes \$\endgroup\$
    – ceilingcat
    May 6, 2019 at 23:25
1
\$\begingroup\$

Swift 2.2 196 bytes

¯\_(ツ)_/¯

Golfed

var r = ["a":"obo","e":"unu","i":"ini","o":"api","u":"iki"];var q={(s:String) in var o = "";for var i in s.lowercaseString.characters{o += r[String(i)] != nil ? r[String(i)]!:String(i)};print(o);}

unGolfed

var r = ["a":"obo","e":"unu","i":"ini","o":"api","u":"iki"]
var q={(s:String) in
    var o = ""
    for var i in s.lowercaseString.characters {
        o += r[String(i)] != nil ? r[String(i)]!:String(i)
    }
    print(o)
}
\$\endgroup\$
4
  • \$\begingroup\$ Are the spaces in var r = [ necessary? \$\endgroup\$
    – Cyoce
    Sep 20, 2016 at 1:05
  • \$\begingroup\$ Yeah in the playgrounds app if you don't put a space in between an assignment it give you an error and tells you to add spaces. Swift is probably one of the worst languages to golf with but I thought it would be fun to try. \$\endgroup\$
    – Danwakeem
    Sep 20, 2016 at 1:40
  • \$\begingroup\$ And it was interesting it didn't give me that error when I was assigning a variable to a closure. Hence the shrugging man \$\endgroup\$
    – Danwakeem
    Sep 20, 2016 at 1:42
  • \$\begingroup\$ yeah I noticed that too. That's why I was confused. \$\endgroup\$
    – Cyoce
    Sep 20, 2016 at 5:05
0
\$\begingroup\$

Perl 6,  84  82 bytes

{my%o=<a obo e unu i ini o api u iki>;S:i:g[<{%o.keys}>]=%o{$/.lc}.samecase($/~'a')}
{my%o=<a obo e unu i ini o api u iki>;S:i:g[<[aeiou]>]=%o{$/.lc}.samecase($/~'a')}

Expanded:

# bare block lambda with implicit parameter 「$_」
{
  # create the mapping
  my %v = <a obo e unu i ini o api u iki>;

  # replace vowels in 「$_」
  S
    :ignorecase
    :global
  [
    <[aeiou]>
  ]

  = # replace them with:

  %v{ $/.lc }
  # change it to be the same case as what was matched, and a lowercase letter
  .samecase( $/ ~ 'a' )
}

Usage:

my &english-to-alien = {my%o=<a obo e unu i ini o api u iki>;S:i:g[<[aeiou]>]=%o{$/.lc}.samecase($/~'a')}

say english-to-alien 'Australia'; # Oboikistroboliniobo
\$\endgroup\$
0
\$\begingroup\$

C - 192 bytes

(newlines added for clarity)

int c,j,b;main(){
char*f[]={"bo","nu","ni","pi","ki",""},
s[]={14,16,0,-14,-12};
while(c=getchar()){for(b=j=0;j<10;++j)
{if(c=="aeiouAEIOU"[j]){c+=s[j%=5];b=1;break;}}
printf("%c%s",c,f[b?j:5]);}}

Just lookup tables and a boolean switch.

Lookup each letter in table (string) of vowels; if found, then modify it according to the rule in table s. Print each character followed by a string: if a vowel was found, print the character modified by the value in s followed by the rest of the syllable stored in table f; if a vowel was not found, print the original character and an empty string.

\$\endgroup\$
1
0
\$\begingroup\$

Ruby, 102 93 91 88 78 bytes

gsub(/[#{b='aeiouAEIOU'}]/){'obounuiniapiikiOboUnuIniApiIki'[b.index($&)*3,3]}

Explanation:

Execute the line like ruby -pe "gsub(/[#{b='aeiouAEIOU'}]/){'obounuiniapiikiOboUnuIniApiIki'[b.index($&)*3,3]}", next up type, for example, Australia it should output: Oboikistroboliniobo.

It's pretty straightforward, replace all vowels with a substring based on the index of the to-be replaced vowel in (b), times 3 and the next 3 characters in the translation string.

\$\endgroup\$
8
  • 1
    \$\begingroup\$ I suspect the leading and trailing quotation marks (and internal escapes if the input has quotation marks) in the output might disqualify this. Anyway, you can save two bytes by moving the assignment of b into the Regexp (/[#{b=...}/). \$\endgroup\$
    – Jordan
    Sep 20, 2016 at 4:03
  • 1
    \$\begingroup\$ I think the space p $* is unnecessary \$\endgroup\$
    – Cyoce
    Sep 20, 2016 at 5:09
  • 1
    \$\begingroup\$ Use the -p flag to save additional bytes. ruby -pe 'gsub(/[#{b="aeiouAEIOU"}]/){"obounuiniapiikiOboUnuIniApiIki"[b.index($&)*3,3]}' \$\endgroup\$
    – Value Ink
    Sep 20, 2016 at 7:30
  • \$\begingroup\$ I count 78 + 2 (-pe). How do you get 71? \$\endgroup\$ Sep 21, 2016 at 19:36
  • \$\begingroup\$ @NotthatCharles do the characters needed for execution really matter in this case? I just didn't count them. \$\endgroup\$
    – Biketire
    Sep 27, 2016 at 10:02
0
\$\begingroup\$

TI-BASIC, 201 197 195 bytes

Ans+" →Str1:"AEIOUaeiou→Str2:"OUIAIouiai→Str3:"bonunipiki→Str4:1→X:While X<length(Str1:inString(Str2,sub(Str1,X,1→A:5fPart(.2A→B:If A:sub(Str1,1,X-1)+sub(Str3,A,1)+sub(Str4,2B-1,2)+sub(Str1,X+1,length(Str1)-X→Str1:X+1+2(A>0→X:End:sub(Str1,1,length(Str1)-1

To think that I'd find another TI-BASIC answer here!

Anyway, the input is an English string in Ans.
The output is the translated string.

Examples:

"HE
HE
prgmCDGF1A
HUnu
"Hello
Hello
prgmCDGF1A
Hunullapi

Explanation:
(Newlines added for readability. Multiple lines from the same line will be denoted with a : in the following code block.)

Ans+" →Str1                     ;append a space to the input string and store the result
                                ; in "Str1"
"AEIOUaeiou→Str2                ;store the upper- and lowercase vowels in "Str2"
"OUIAIouiai→Str3                ;store the beginning letter of each corresponding translated
                                ; vowel in "Str3"
"bonunipiki→Str4                ;store the remaining letters of each translated vowel
                                ; in "Str4"
1→X                             ;store 1 in "X"
While X<length(Str1             ;loop until all English letters have been checked
inString(Str2,sub(Str1,X,1→A    ;get the current letter and store its index in "Str2"
                                ; into "A"
5fPart(.2A→B                    ;get which translated vowel end should be used
                                ; B ranges from 1 to 5
If A                            ;if the current letter is a vowel
sub(Str1,1,X-1)                 ;extract the substring of the input before the
                                ; current letter
: +sub(Str3,A,1)                ;append the translated vowel start
: +sub(Str4,2B-1,2)             ;append the translated vowel end
: +sub(Str1,X+1,length(Str1)-X  ;append the remaining substring of the input
: →Str1                         ;store the result of these concatenations into "Str1"
X+1+2(A>0→X                     ;check if A>0 (if the current letter was a vowel)
                                ; if true, increment "X" by three
                                ; if false, increment "X" by one
End
sub(Str1,1,length(Str1)-1       ;remove the trailing space and store the result in "Ans"
                                ;implicit print of "Ans"

Notes:

  • TI-BASIC is a tokenized language. Character count does not equal byte count.

  • Lowercase letters in TI-BASIC are two bytes each.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.