10
\$\begingroup\$

Text may be translated to a written version of TUT language by replacing each letter by the corresponding "TUT word", as given in the following table (adapted from the linked article)*:

a  e        h  hash     o  o        u  yu
b  bub      i  ay       p  pup      v  vuv
c  kut      j  jag      q  kwak     w  waks
d  dud      k  kak      r  rut      x  eks
e  i        l  lul      s  sus      y  yak
f  fuf      m  mum      t  tut      z  zuz
g  jug      n  nun            

* Exceptions: 
(1) Upper case letters have corresponding TUT words in upper case.
(2) A doubled letter becomes 'skwer' ('SKWER') followed by the TUT word for that letter.
    - An n-fold letter is treated as a number of doubles, followed by a single if needed.
    - To be considered a double or n-fold letter, the letters must be in the same case.
(3) 'rut' ('RUT') is replaced by 'rud' ('RUD') if immediately followed by 'dud' ('DUD'). 

Write a program with the following i/o behavior:

Input (from stdin): A binary (0/1) indicator i and an ASCII string s.

  • If i = 0 then s may contain any ASCII text.
  • If i = 1 then s must be the TUT Language output for some valid input.

Output (to stdout): A binary (0/1) indicator j and an ASCII string t.

  • If i = 0 then j = 1 and t is the translation of s to TUT Language.
  • If i = 1 then j = 0 and t is the translation of s from TUT Language.
  • For any valid input, applying the program to its own output must exactly reproduce the original input; i.e., program (program (i, s)) = (i, s). Input and output must have exactly the same format.

Scoring: The score is the number of characters in the program -- lowest score wins.

Examples

(a)

(0, 'Look for the birds.')
(1, 'LULskwerokak fuforut tuthashi bubayruddudsus.')

(b)

(0, '"Mrs. Hogwallop up and R-U-N-N-O-F-T."')
(1, '"MUMrutsus. HASHojugwakseskwerlulopup yupup enundud RUT-YU-NUN-NUN-O-FUF-TUT."')

(c)

(0, 'QWX WWW Rrrrd deeeeep')
(1, 'KWAKWAKSEKS SKWERWAKSWAKS RUTskwerrutruddud dudskweriskweriipup')

(d)

(0, 'aa AA aA Aa rd RD rD Rd')
(1, 'skwere SKWERE eE Ee ruddud RUDDUD rutDUD RUTdud)

(((Aside about pronunciation: The TUT words for the vowels (e, i, ay, o, yu) are supposed to represent the usual sounds of (a, e, i, o, u) when reciting the alphabet -- i.e., rhyming with (may, me, my, mow, mew). In the three-or-more-letter TUT words, the symbols (u,a,e) are supposed to sound as in (but, bat, bet) respectively -- these are ASCII replacements for (ʌ æ ɛ) in the linked article.)))

\$\endgroup\$
  • 1
    \$\begingroup\$ do we have to support doubled uppercase? What's the tut translation of AA, SKWERE or skwerE? What about tripled letters? is it wakswakswaks, skwerwakswaks, waksskwerwaks, or even kyubwaks, or we may choose? \$\endgroup\$ – John Dvorak Nov 17 '13 at 17:23
  • 1
    \$\begingroup\$ rrd should translate to skwerruddud; are we allowed to leave it at skwerrutdud? \$\endgroup\$ – John Dvorak Nov 17 '13 at 17:41
  • \$\begingroup\$ @JanDvorak - Yes, it should handle doubled letters, regardless of case. Input (0,'AA SKWERE skwerE') should have output(1,'ee SUSKAKWAKSIRUTI suskakwaksirutI'). Inputs (1,'AA') and (1,'skwerE') are not valid because 'AA' and 'skwerE' do not occur as outputs of any valid input. Input (1, 'SKWERE') should have output (0,'EE'). A string of three or more letters should be regarded as some number of doubles, possibly followed by a single. Input (0,'rrd') should have output (1,'skwerruddud'). \$\endgroup\$ – r.e.s. Nov 17 '13 at 18:28
  • \$\begingroup\$ uh... how does 0,"AA" translate to 1,"ee"? As for 1,"SKWERE", I assume you meant 0,"AA", not 0,"EE". \$\endgroup\$ – John Dvorak Nov 17 '13 at 18:31
  • 1
    \$\begingroup\$ @psxls - I intended (0,rd_RD_rD_Rd) -> (1,ruddud_RUDDUD_rutDUD_RUTdud) and (0,aa_AA_aA_Aa) -> (1,skwere_SKWERE_eE_Ee). Rule (3) applies to the TUT words 'skwere' and "SKWERE'. \$\endgroup\$ – r.e.s. Nov 19 '13 at 0:51
6
\$\begingroup\$

Ruby, 310 311 characters

h=Hash[(?a..?z).zip %w{e bub kut dud i fuf jug hash ay jag kak lul mum nun o pup kwak rut sus tut yu vuv waks eks yak zuz}]
h["rd"]="ruddud"
h.keys.each{|k|h[k[0]+k]="skwer"+h[k]}
h.keys.each{|k|h[k.upcase]=h[k].upcase}
h=h.invert if b=getc==?1
i=gets
print b ?0:1;(k=i;k=k.chop until h[k]||!k[1];$><<(h[k]||k);i[k]="")until i==""

Correctly handles:

  • squared uppercase (unfix by merging iterations gains 18 characters)
    • if AA should turn into skwerE, swap lines #3 and #4
    • I also assume aA and Aa should turn into eE and Ee respectively
  • rrd translates to `skwerruddud (unfix gains 3 characters)
  • in cubes the first pair is reported as a square. rrrd turns into skwerrutruddud. rrrrd becomes skwerrutskwerruddud
  • the output is now a valid input. It is, indeed, required by the spec
  • uses newline as input terminator

Input requires there be no newline between the indicator and the string, output puts it there (fix: 1 character). Console output suppressed at this point to prevent mixing with STDIN. Unfix free, it's just a little bit uglier.

Example input:

0Hello

Output:

1
HASHiskwerlulo
\$\endgroup\$
  • \$\begingroup\$ I was vacillating about whether to require input & output to have identical formats, but it wasn't clear in the question, so ... this answer looks fine to me (so far -- I'll run some tests on the answers soon). \$\endgroup\$ – r.e.s. Nov 17 '13 at 19:00
  • \$\begingroup\$ I don't know why, but your program runs for me -- both online and off -- only if getc is prefixed with STDIN. (six more characters). \$\endgroup\$ – r.e.s. Nov 17 '13 at 22:37
  • \$\begingroup\$ I'm using jRuby IRB 1.7.5 (2.0.0) and it shows me only a warning. What verion are you using? \$\endgroup\$ – John Dvorak Nov 18 '13 at 5:18
  • \$\begingroup\$ I like the shorthand to create the map. I just included it fully. Which makes it unlikely that I will beat that. \$\endgroup\$ – Johannes Kuhn Nov 18 '13 at 7:26
  • 1
    \$\begingroup\$ @r.e.s. I believe that the input/output requirement was clear: For any valid input, applying the program to its own output must exactly reproduce the original input; i.e., program (program (i, s)) = (i, s). But it would only cost 1 character to fix that. \$\endgroup\$ – Johannes Kuhn Nov 18 '13 at 7:28
3
\$\begingroup\$

Perl, 453 443 309 307 303 299

($x,$_)=split//,<>,2;@x{a..z,rd}=(e,bub,kut,dud,i,fuf,jug,hash,ay,jag,kak,lul,mum,nun,o,pup,kwak,rut,sus,tut,yu,vuv,waks,eks,yak,zuz,ruddud);$x{$_ x2}=skwer.$x{$_}for a..z;$x{uc$_}=uc$x{$_}for keys%x;%x=reverse%x if$x;$z=join"|",sort{length$b<=>length$a}keys%x;s/\G(.*?)($z)/$1$x{$2}/g;print!$x+0,$_

Test cases:

I have tested successfully the (a),(b),(c) and (d) test cases provided in the OP.

A *somewhat* more readable version:

($x,$_)=split//,<>,2;
@x{a..z,rd}=(e,bub,kut,dud,i,fuf,jug,hash,ay,jag,kak,lul,mum,nun,o,pup,kwak,rut,sus,tut,yu,vuv,waks,eks,yak,zuz,ruddud);
$x{$_ x2}=skwer.$x{$_}for a..z;
$x{uc$_}=uc$x{$_}for keys%x;
%x=reverse%x if$x;
$z=join"|",sort{length$b<=>length$a}keys%x;
s/\G(.*?)($z)/$1$x{$2}/g;
print!$x+0,$_
\$\endgroup\$
  • 1
    \$\begingroup\$ Nice! Some good test cases to check, it appears I have a lot of work to do! I've had a quick look at yours and I think you can knock a few bytes off using barewords instead of qw (change qw(bub kut ... yak zuz) to (bub,kut ... yak,zuz)), also you can replace keys%x with @b (since you know what the keys are because of $x). A small change to save another three is $1eq uc($1) to uc$1eq$1. You could also drop the + before the ! of the print for that extra byte to take you to 443. Hope that's all valid, I've tested limited test cases! \$\endgroup\$ – Dom Hastings Nov 18 '13 at 22:16
  • \$\begingroup\$ Hmmm, uc$1eq$1 might have to be uc$1 eq$1, but I'm not certain... Sorry if that's wrong! \$\endgroup\$ – Dom Hastings Nov 18 '13 at 22:34
  • \$\begingroup\$ Thanks Dom for the tips! You saved me 10 chars. Still there's room for improvement, I'll get back to work.. :) \$\endgroup\$ – psxls Nov 19 '13 at 2:00
2
\$\begingroup\$

APL (Dyalog) (372)

You can really tell APL doesn't have built-in string handling functions (except for the generic array ones). I had to write my own tolower (it's L). As always with multiline Dyalog APL, to test it, paste it in an edit window and then call it (T).

T
Q←⎕UCS
L←{Q(Q⍵)+32×⍵∊⎕A}
Z←{⎕←⊃z,.⍺⍺1⌽z←⍵,' '}
w←L¨W←1↓¨W⊂⍨' '=W←' E BUB KUT DUD I FUF JUG HASH AY JAG KAK LUL MUM NUN O PUP KWAK RUT SUS TUT YU VUV WAKS EKS YAK ZUZ RUD SKWER'
⍞{⎕←~⍵:{U←L⍣(l←⍺∊L⎕A)
~l∨⍺∊⎕A:⍺
⍺=⍵:U⊃⌽W
'rd'≡L¨⍺⍵:U'RUD'
U⊃W[96-⍨Q+L⍺]}Z⍺
{'rR'∊⍨v←⊃⍺:v
(⊃⌽w)≡m←L⍺:⍵∇⍬
~w∊⍨⊂m:⍺
L⍣(⍺≡L⍺)⍨⎕A/⍨26↑≡∘m¨w}Z{~×⍴⍵:''
∨/H←⊃¨⍷∘(L⍵)¨w:(⊂l↑⍵),∇⍵↓⍨l←⍴⊃H/W
(⊂⊃⍵),∇1↓⍵}⍺}⎕

Usage:

      T
⎕:
0
"Mrs. Hogwallop up and R-U-N-N-O-F-T."     
1
"MUMrutsus. HASHojugwakseskwerlulopup yupup enundud RUT-YU-NUN-NUN-O-FUF-TUT."      
      T
⎕:
1
"MUMrutsus. HASHojugwakseskwerlulopup yupup enundud RUT-YU-NUN-NUN-O-FUF-TUT."      
0
"Mrs. Hogwallop up and R-U-N-N-O-F-T."       
\$\endgroup\$
2
\$\begingroup\$

Tcl, 395 394 392

set m { rd ruddud a e h hash o o u yu b bub i ay p pup v vuv c kut j jag q kwak w waks d dud k kak r rut x eks e i l lul s sus y yak f fuf m mum t tut z zuz g jug n nun ঙ skwer}
set m $m[string tou $m]
if [read stdin 1] {puts 0[regsub -all ঙ(.) [string map [lreverse $m] [gets stdin]] {\1\1}]} {puts 1[string map $m [regsub -all (.)\\1 [gets stdin] ঙ\\1]]}

Notes:

  • Uses skwerruddud for rrd.
  • skwereskweree for aaaaa.

Example input:

0Hello

Output:

1HASHiskwerlulo

How it works:

  • m is at the beginning a string.
  • I concatiate it with the uppercase map.
  • [string map] does most of the stuff for me (uses a list, so anything that is a valid list...)
  • regexp for for the double characters. Use a special replacement character ().
\$\endgroup\$
  • \$\begingroup\$ The Bengali Abugida, how did you choose that character? \$\endgroup\$ – Kaya Nov 18 '13 at 1:13
  • \$\begingroup\$ \ufff iirc. Doesn't really matter. Any non-ascii character would do. \$\endgroup\$ – Johannes Kuhn Nov 18 '13 at 7:06
  • \$\begingroup\$ It was \u999. As I said, the only important thing was: not an ascii character. \$\endgroup\$ – Johannes Kuhn Nov 18 '13 at 7:49
  • \$\begingroup\$ @JohannesKuhn it fails at example (c), returns 1KWAKWAKSEKS skwerWAKSWAKS RUTskwerrutruddud dudskweriskweriipup. \$\endgroup\$ – psxls Nov 18 '13 at 19:27
  • \$\begingroup\$ @psxls Which is correct: A doubled letter is replaced by `skwer` followed by the TUT word for that letter. No mention of SKWER. \$\endgroup\$ – Johannes Kuhn Nov 18 '13 at 20:28
2
\$\begingroup\$

Perl 385

$t=e0bub0kut0dud0i0fuf0jug0hash0ay0jag0kak0lul0mum0nun0o0pup0kwak0rut0sus0tut0yu0vuv0waks0eks0yak0zuz;@t=split 0,$t."0\U$t";@s=(a..z,A..Z);while(<>){($-,$_)=split/ /,$_,2;@l{$-?@t:@s}=$-?@s:@t;if($-){for$@(@t){s/skwer$@/$@$@/gi}for$@(@t){s/$@/$l{$@}/g}s/(r)ud/$1/gi}else{s/(.)/$l{$1}||$1/ge;for$@(@t){$r=lc$@eq$@?"skwer":"SKWER";s/$@$@/$r$@/g}s/(ru)t(d)/$1$2$2/gi}$-=!$-;print"$- $_"}

Syntax highlighter hates this one...

Expects input on STDIN, format is 0 (or 1) String to convert here.:

0 Hello! # input
1 HASHiskwerlulo! # output

1 HASHiskwerlulo!
0 Hello!

0 Look for the birds.
1 LULskwerokak fuforut tuthashi bubayruddudsus.

1 LULskwerokak fuforut tuthashi bubayruddudsus.
0 Look for the birds.

0 "Mrs. Hogwallop up and R-U-N-N-O-F-T."
1 "MUMrutsus. HASHojugwaksaskwerlulopup yupup anundud RUT-YU-NUN-NUN-O-FUF-TUT."

1 "MUMrutsus. HASHojugwaksaskwerlulopup yupup anundud RUT-YU-NUN-NUN-O-FUF-TUT."
0 "Mrs. Hogwallop up and R-U-N-N-O-F-T."

Edit: I've noticed an issue with the translation of X (it becomes 'aks' in the reversion, I'll look into this later. Might need to re-order the hash :(.

\$\endgroup\$
  • 1
    \$\begingroup\$ apart of X, it fails also in OP's examples (b), (c) and check also in my answer the test cases (e) & (g). \$\endgroup\$ – psxls Nov 18 '13 at 19:20
  • \$\begingroup\$ This is very true, back to the drawing board! \$\endgroup\$ – Dom Hastings Nov 18 '13 at 22:17
2
\$\begingroup\$

GNU Sed, 514

s/$/\n@a!e@b!bub@c!kut@d!dud@e!i@f!fuf@g!jug@h!hash@i!ay@k!kak@l!lul@m!mum@n!nun@o!o@p!pup@q!kwak@r!rud@r!rut@s!sus@t!tut@u!yu@v!vuv@w!waks@x!eks@y!yak@z!zuz/
s/.*\n\(.*\)/&\U\1@/
ta
:a
s/^1/0\v/
td
s/^0/1\v/
:t
/\v\n/bf
s/\v\([^a-z]\)/\1\v/i
tt
s/\v\([a-z]\)\1/skwer\v\1/
s/\v\([A-Z]\)\1/SKWER\v\1/
s/\v\(.*\)\(.*\n.*@\1!\(\w\+\)@\)/\3\v\2/
s/rut\vd/rud\vd/
s/RUT\vD/RUD\vD/
bt
:d
/\v\n/bf
s/\v\([^a-z]\)/\1\v/i
td
s/\v\(skwer\)/\1\v/i
s/\v\(.*\)\(.*\n.*@\(.\)!\1@\)/\3\v\2/
s/skwer\(.\)\v/\1\1\v/
bd
:f
s/\v.*//

Could probably be shortened, though I'm done for now.

Uses a lookup table to handle conversions in both directions, should handle all exceptions including skwer case and ruddud/RUDDUD correctly.

input taken on each line as 0/1 followed by the string. Uses \v (vertical tab) as a cursor.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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