Decode Baby-talk!
Perl, 82 bytes
Includes +1 for -a
Give input on STDIN:
perl -M5.010 baby.pl <<< "OOaGOG GoGOOoGoU gAA bLAA GOUGoOUgAIGAI"
baby.pl
:
#!/usr/bin/perl -a
say map{$A=$O=$_=uc;y/AEIOU/@/c;s/(\B.|.\B)/$$1+=$$1<4/eg;(A..I,K..Z)[5*$A+$O]}@F
This assumes a recent enough perl version where -a
implies -n
. If your perl is too old you will need to add an explicit -n
option.
It also assumes babies can't say general ASCII strings that start with digits like 1 this will not work
JavaScript (ES6), 145 bytes
alert(prompt().replace(/\S+ ?/g,x=>(g=r=>(q=(x.match(/[aeiou]{2,}/gi)+"").split(r).length-1)>4?4:q,(g(/a/i)*5+g(/o/i)+10)*20/19|0).toString(36)))
Replaces each word (and the following space) with its corresponding letter.
s.split` `.map().join``
is 3 bytes longer:
alert(prompt().split` `.map(x=>(g=r=>(q=(x.match(/[aeiou]{2,}/gi)+"").split(r).length-1)>4?4:q,(g(/a/i)*5+g(/o/i)+10)*20/19|0).toString(36)).join``)
brainfuck, 656 bytes
+[[>>>,[>++++[<-------->-]]<]<<[>]<-[+[<+>>+<-]----[>>+<<----]>>+[<[-<]<[>]>>-]-<[[-]>+<]>[[-[->]<<+>]<->>>]<<<[>>>+<<<-]<<-]>>>>>[[<+>>+<-]----[>-<----]>--[----<]<[>]>[----<]<[>]>[------<]<[>]>[------<]<[>]><+>[[-]<->]>>]<<<[>->]<[<]>[>[<<<<<+>>>>>>+<-]<<<<]<[-]>>>>[<[>[>+<-]<-]>[-]->[<+>-]>>]<<<[-<----[>-<----]>[>+>+<<-]+>[<->[-]<]<[<]>[[<<<]<+>>>>[>>>]<<<-]>+>--------------[<->[-]]<[-<<<<[<<<]>+>>[>>>]>]<<<<]<[<+<+>>-]>++++[<<[->]>[<]>-]+<<[[-]++++<[-]>>]>[<]<<[>+<-]>>+>->[>+>+<<-]<++++[>>[-<]<[>]<-]>>[[-]++++>[-]]<<<[>]<->>>>[<+>-]<[<<<+>>>-]<<<<[>+++++<-]>[>+>+<<-]<++++++++[>>[-<]<[>]<-]>>[[-]>+<]----[>+<----]>++.[-]+>>>,[<++++[>--------<-]]>]
This was a pretty good way to kill a couple of hours.
Requires a brainfuck interpreter that uses 8-bit wrapping cells, allows you to go left from cell 0 and returns 0 if ,
is used when stdin is empty. In my experience, these are the most common settings.
This program does not consider Y a vowel, but if OP wants it to it's an easy fix.
It seems like writing this would be a daunting task but if you have some familiarity with the language there's nothing surprising or new in the code. Standard brainfuck tactics: Read the input but make sure you leave a couple of empty cells between each byte, use those empty cells to store data about the input, use the data you stored to decide how to transform it and spit something out at the end. In this case it was get the input, set it all to uppercase, figure out which cells are vowels, throw that information away after using it to determine which cells are next to vowels, set everything that isn't next to a vowel to some value that will never be relevant so they're not in the way later, and you're basically done. From there you just have to count your A
s and O
s, multiply A
s by 5 and add the number of O
s, special case anything above 8 to avoid J and output. I did choose to handle this one word at a time, rather than taking the whole input at once, so I had to set up the part of the code that reads stdin to break at 0 or 32, but that's not too big of a problem (just wrap the subtraction by 32 in a conditional so it doesn't happen if the value is already 0, then correct for any <
or >
instructions you missed later).
I don't know how helpful it will be because I wrote it mostly to keep my thoughts straight rather than as a real explanation, but here's the code with my comments and its original indentation:
+[[>>>,[>++++[<-------->-]]<]get an entire word of input
each character lowered by 32
two empty cells between characters
stops when reaching a space or null byte
any lowercase letters have become uppercase; anything with a value below 65 used
to be an uppercase character; fix it
<<[>]<-[+ for each character until hitting 1:
[<+>>+<-] make a backup
subtract 64 from the character but stop if it hits 0
----[>>+<<----]>>+ generate the number 64
[ 64 times:
<[ if the character is not 0:
- subtract 1
< go to a guaranteed 0 cell to break the loop
]
we're either on the character or to the left of it; sync up
<[>]
>>-]
-<[[-]>+<]> logical NOT of character
[ if logical NOT returns true:
[-[->]<<+>]<- add 32 to backup of character
>>>]
<<<[>>>+<<<-] move copy over to make room
<<-]
>>>>>[ for each character:
[<+>>+<-] make copies
----[>-<----]>-- check if it's A
[----<]<[>]> check if it's E
[----<]<[>]> check if it's I
[------<]<[>]> check if it's O
[------<]<[>]> check if it's U
IF YOU NEED TO ADD Y; THIS IS THE PLACE
<+>[[-]<->] logical NOT to complete vowel check
>>]
<<<[ if the last char is a vowel; prevent a side effect
>->
]
<[<]>[ for each character:
>[ if it's a vowel:
<<<<<+>>>>>>+<- leave a flag to the left and right to show that a
] vowel is adjacent
<<<<]
<[-]> clean up a side effect left behind if first char is vowel
>>>[ for each char:
<[ if it's adjacent to a vowel:
>[>+<-]<- move it to the side
]
>[-]- otherwise; destroy it
>[<+>-] move backup over if it exists (subtracting 1)
>>]
all characters without a vowel beside them have been set to 255
all characters with a vowel beside them are set to itself minus 1
notable charaters are: 'A' minus 1 = 64
'O' minus 1 = 78
<<<[ for each character:
-<----[>-<----] subtract 64
>[>+>+<<-] make a copy
+>[<->[-]<]<[<]> logical NOT
[[<<<]<+>>>>[>>>]<<<-] if NOT returns true; record an A
>+>-------------- subtract 14 from backup
[<->[-]]< logical NOT
[-<<<<[<<<]>+>>[>>>]>] if NOT returns true; record an O
<<<<]
<[<+<+>>-] make a backup of A count
>++++[<<[->]>[<]>-] subtract 4 but don't go below 0
+<<[ if the char was greater than 3:
[-]++++<[-]>> put 4 there
]
>[<] resynchronise
<<[>+<-] if there were fewer than 4 As put the number back
same thing but for the O count
>>+>->[>+>+<<-] make a backup of O count
<++++[>>[-<]<[>]<-] subtract 4 but don't go below 0
>>[ if the char was greater than 3:
[-]++++>[-] put 4 there
]
<<<[>] resynchronise
<->>>>[<+>-] if there were fewer than 4 Os put the number back
<[<<<+>>>-]<<<<[>+++++<-] A*5 plus B = index of character to output
>[>+>+<<-] make a backup
<++++++++[>>[-<]<[>]<-] subtract 8 but don't go below 0
>>[[-]>+<] if the result is nonzero it is late enough in the alphabet
that it must be increased by 1 to exclude J as a possible
output
----[>+<----]>++ add 65 to make it a letter
.[-]+>>>, output and get new input
[<++++[>--------<-]]> sub 32 if not 0
]