Let's golf a BIBABOBU decoder

52

2

While I was traveling in the future, I noticed a funny game among kids circa 2275. When they don't want their great-great-great-great-grand parents to understand what they're saying, they use the BIBABOBU speak. Obviously, I couldn't understand anything either with my pre-cyborg era brain and I felt (or technically: I will feel) really silly. So, I'd need a decoder for my next visit.

BIBABOBU?

While it's been deprecated for a long time, ASCII is still commonly used in the pop culture of 2275 and this language is based upon it.

A string is BIBABOBU-encoded that way:

  • Convert all characters to their ASCII codes.
  • Take the 2-digit hexadecimal representation of each code and convert them using the following table:

    0: BI  4: BIDI  8: BADI  C: BODI
    1: BA  5: BIDA  9: BADA  D: BODA
    2: BO  6: BIDO  A: BADO  E: BODO
    3: BU  7: BIDU  B: BADU  F: BODU
    

Example

"Hello!" → 48 65 6C 6C 6F 21 → "BIDIBADI BIDOBIDA BIDOBODI BIDOBODI BIDOBODU BOBA"

However, the corresponding input would be given without any space to mimic the monotonous intonation that kids are using to make this even harder to understand without implants:

"BIDIBADIBIDOBIDABIDOBODIBIDOBODIBIDOBODUBOBA"

Clarifications and rules

  • Remember that I need a decoder, not an encoder.
  • Decoded characters are guaranteed to be in the range [ 32...126 ].
  • The input is guaranteed to contain en even number of BIBABOBU-encoded hexadecimal digits.
  • You may take input in either full lowercase or full uppercase. Mixed cases are not allowed.
  • Because bit flips are quite common during a time travel, this is in order to minimize the risks.

Test cases

NB: Linefeeds are used below for formatting purposes only. You are not supposed to handle them.

Input:
BIDABIDIBIDOBIDABIDUBUBIDUBIDI

Output:
Test

Input:
BIDABIDUBIDOBIDABIDOBODIBIDOBUBIDOBODUBIDOBODABIDOBIDABOBIBIDUBIDIBIDOBODUBOBIBUBOBUBOBUBI
DUBUBIDABOBA

Output:
Welcome to 2275!

Input:
BIDIBADIBIDOBIDABIDOBODIBIDOBODIBIDOBODUBOBODIBOBIBIDABIDIBIDOBADABIDOBODABIDOBIDABOBIBIDA
BIDIBIDUBOBIDOBABIDUBIDOBIDOBIDABIDOBODIBIDOBIDABIDUBOBOBABOBIBIDABADABIDOBODUBIDUBIDABOBI
BIDOBODIBIDOBODUBIDOBODUBIDOBADUBOBIBIDUBUBIDOBODUBOBIBIDOBIDOBIDUBIDABIDOBODOBIDOBODOBIDU
BADABOBA

Output:
Hello, Time Traveler! You look so funny!

Input:
BIDIBABIDOBODOBIDOBIDIBOBIBIDUBADABIDOBODUBIDUBIDABOBIBIDOBIDIBIDOBODUBIDOBODOBOBIDUBIDUBI
DIBOBIBIDUBIDABIDOBODOBIDOBIDIBIDOBIDABIDUBOBIDUBUBIDUBIDIBIDOBABIDOBODOBIDOBIDIBOBIBIDUBI
DUBIDOBADIBIDOBABIDUBIDIBOBIBIDIBADABOBIDUBIDOBODABOBIBIDUBUBIDOBABIDUBADABIDOBADABIDOBODO
BIDOBIDUBOBODIBOBIBIDOBIDIBIDOBODUBOBIBIDUBADABIDOBODUBIDUBIDABUBODUBOBIBIDIBADIBIDOBABOBI
BIDOBADIBIDOBABOBIBIDOBADIBIDOBABOBA

Output:
And you don't understand what I'm saying, do you? Ha ha ha!

Arnauld

Posted 2018-08-29T08:50:28.210

Reputation: 111 334

I like the challenge, but I would have liked it slightly better if the encoding was lexicographically sorted. – Stewie Griffin – 2018-08-29T08:57:44.160

4@StewieGriffin These damn kids are mischievous... :-/ – Arnauld – 2018-08-29T09:04:04.447

12By the way, I find the story really really unlikely! I wouldn't be surprised if it was just a dream you had... might you have a CO leak in your house? – Stewie Griffin – 2018-08-29T09:09:47.387

12Ah... That would also explain the ponies riding rainbows in my living room! – Arnauld – 2018-08-29T09:13:10.523

2"Because bit flips are quite common during a time travel" - err shouldn't it be radiation-hardened then? – Jonathan Allan – 2018-08-29T10:07:22.367

1Do you need a decoder for the actual BIBABOBU speak, or just for the written down version? – Mr Lister – 2018-08-29T10:30:06.980

1@MrLister The written down version is fine. :) – Arnauld – 2018-08-29T10:34:44.520

1... but not nearly as great a challenge. – Mr Lister – 2018-08-29T10:36:42.133

@MrLister That would be another kettle of fish indeed. Here is the only voice decoding challenge I've been able to find.

– Arnauld – 2018-08-29T10:47:20.570

9One could argue that golfed code increases the severity of a bit-flip (less redundancy within the code) even if it decreases the frequency of a bit-flip... but whatever :) - Nice challenge! – JayCe – 2018-08-29T12:53:01.157

4@JayCe True. I was more thinking along the lines: the smaller the code, the more redundancy you can get by storing multiple copies. – Arnauld – 2018-08-29T13:01:53.227

^ Of course... this makes sense. – JayCe – 2018-08-29T13:05:17.127

Of course, this implies that immortality will be invented circa or before 2125. – Erik the Outgolfer – 2018-08-29T14:17:44.250

@JonathanAllan If that solves the problem, then those bit flips would be pretty weird, since they would always restrict themselves to one byte. – Erik the Outgolfer – 2018-08-29T14:25:37.350

4Sorry, I want to like this challenge, but the premise of the question is clearly ridiculous. ASCII will never be deprecated. – scatter – 2018-08-30T13:44:43.370

It is bugging me that the encoding table is not a Huffman tree (properly organized to use the shortest phonemes for the most common symbols, of course). – zwol – 2018-08-30T20:38:36.677

1I’m pretty sure that technically you willan on-when presooning on-feelenta silly in this situation; the correct tense to use here is surely the Future Subinverted Plagal Retropast. – Janus Bahs Jacquet – 2018-09-02T08:38:22.163

Answers

15

05AB1E, 36 35 33 bytes

Saved 1 byte thanks to Mr.Xcoder
Saved 2 bytes thanks to KevinCruijssen

ć©¡®ì®D…IAO©â'D«‚˜®'U«âJskh2ôJHçJ

Try it online! or as a Test Suite

Explanation

ć©¡                                 # extract the head ("B") and split input on it
   ®ì                              # prepend "B" to each
     ®D                            # push 2 copies of "B"
       …IAO©â                      # cartesian product with "IAO"
             'D«                   # append "D" to each
                ‚˜                 # add the leftover "B" to the list
                  ®'U«â            # cartesian product with "IAOU"
                       J           # join each to string
                        sk         # get the index of each word of the input in this list
                          h        # convert each to hex
                           2ôJ     # format as pairs of chars
                              H    # convert to int
                               çJ  # convert from ascii-codes to string

Emigna

Posted 2018-08-29T08:50:28.210

Reputation: 50 798

I believe 'B©¡¦®ì®D…IAO©â'D«‚˜®'U«âJskh2ôJHçJ works for 35 bytes. – Mr. Xcoder – 2018-08-29T10:39:37.033

@Mr.Xcoder: Ah, of course. Nice reuse of ©. Thanks :) – Emigna – 2018-08-29T10:45:30.050

-2 bytes changing the leading 'B to ć and removing the ¦, since the input will always start with a 'B'. – Kevin Cruijssen – 2018-08-29T20:25:08.743

@KevinCruijssen: Ooh, good idea. I hadn't considered ć. Thanks! – Emigna – 2018-08-30T06:21:54.813

9Now let's get back at those kids and see if they understand that ! – Aaron – 2018-08-30T08:28:53.590

Grrr... you beat me by 2. Oh, and I did the challenge wrong, so, in reality, by 7. I never stood a chance xD. – Magic Octopus Urn – 2018-08-30T18:30:50.743

So we now have a partial traduction of THE magical song.. What does Bibbidi-bobbidi, bibbidi-bobbidi, bibbidi-bobbidi-boo. really mean?

– Drag and Drop – 2018-08-31T06:53:56.307

14

Jelly, 26 24 23 22 20 17 15 bytes

ṣḢO^1%9%4Ḅḅ⁴b⁹Ọ

Try it online!

How it works

ṣḢO^1%9%4Ḅḅ⁴b⁹Ọ  Main link. Argument: s (string)

 Ḣ               Head; remove and yield the first character of s.
ṣ                Split s at occurrences of the result ('B').
  O              Ordinal; map "IAOUD" to A1 := [73, 65, 79, 85, 68].
   ^1            Bitwise XOR 1; map A1 to A2 := [72, 64, 78, 84, 69].
     %9          Modulo 9; map A2 to A3 := [0, 1, 6, 3, 6].
       %4        Modulo 4; map A3 to A4 := [0, 1, 2, 3, 2].
                 So far, we've mapped "BX" to [x] and "BXDY" to [x, 2, y],
                 where x/y = 0, 1, 2, 3 when X/Y = I, A, O, U.
         Ḅ       Unbinary; map [x] to x and [x, 2, y] to 4x + 2×2 + y = 4(x + 1) + y.
          ḅ⁴     Convert the resulting array from base 16 to integer.
            b⁹   Convert the resulting integer to base 256.
              Ọ  Unordinal; replace code points with their characters.

Dennis

Posted 2018-08-29T08:50:28.210

Reputation: 196 637

13

Perl 6, 58 bytes

{S:g{(B.[D.]?)**2}=chr :16[$0».&{:2[.ords»³X%87 X%4]}]}

Try it online!

Heavily inspired by Dennis' Jelly solution. Uses a different magic function x³ % 87 % 4 which also maps the ASCII codes of IAOUBD to 012302.

Alternative 75 74 bytes version

-1 byte thanks to Jo King

{pack('H',.trans((<B BID BAD BOD>X~ <I A O U>)=>(^16)».base(16))).decode}

Try it online!

Alternative 85 bytes version

{S:g[....]=chr :4(~$/)*2+|221+^:4(~$/)+^238}o{TR:d/UIAOBD/0123/}o{S:g[B.<![D]>]=0~$/}

Try it online!

nwellnhof

Posted 2018-08-29T08:50:28.210

Reputation: 10 037

How about (^16)>>.base(16) for -1 byte

– Jo King – 2018-08-29T13:41:27.947

8

Python 2, 100 97 96 95 bytes

-1 byte thanks to ovs
-1 byte thanks to G B

lambda w:''.join(' 1023546798abdcef'[int(c,35)/7%77%18]for c in w.split('B')[1:]).decode("hex")

Try it online!

Rod

Posted 2018-08-29T08:50:28.210

Reputation: 17 588

6

05AB1E (legacy), 68 65 60 59 bytes

.•5Ç¿ÆΓ•2ô.•1ÒKá ¸ΓìŸÆt`ô_zTºγ„KRI‰ι놽òι•4ô«I¬©¡®ìkh2ôJHçJ

Input is in lowercase.

-3 bytes implicitly thanks to @Emigna changing 'b¡εg>}s£ to 'b©¡®ì.

Try it online or verify all test cases.

Also, can definitely be golfed with something smarter than the huge compressed strings. Will take another look later on. Shorter answer already provided by @Emigna, so make sure to upvote him!

Explanation:

.•5Ç¿ÆΓ•      # Compressed string "bibabobu"
        2ô    # Split in parts of 2
              #  → ["bi","ba","bo","bu"]
.•1ÒKá ¸ΓìŸÆt`ô_zTºγ„KRI‰ι놽òι•
              # Compressed string "bidibidabidobidubadibadabadobadubodibodabodobodu"
        4ô    # Split in parts of 4
              #  → ["bidi","bida","bido","bidu","badi","bada","bado","badu","bodi","boda","bodo","bodu"]
«             # Merge both lists together
              #  → ["bi","ba","bo","bu","bidi","bida","bido","bidu","badi","bada","bado","badu","bodi","boda","bodo","bodu"]
I¬©¡          # Take the input and split on the head (always 'b')
              #  i.e. "bidibadibidobidabidobodibidobodibidoboduboba"
              #   → ["idi","adi","ido","ida","ido","odi","ido","odi","ido","odu","o","a"]
    ®ì        # And prepend a 'b' to each item again
              #  i.e. ["idi","adi","ido","ida","ido","odi","ido","odi","ido","odu","o","a"] 
              #   → ["bidi","badi","bido","bida","bido","bodi","bido","bodi","bido","bodu","bo","ba"]
k             # Map each item to the index of the first list
              #   i.e. ["bidi","badi","bido","bida","bido","bodi","bido","bodi","bido","bodu","bo","ba"]
              #    → [4,8,6,5,6,12,6,12,6,15,2,1]
 h            # Convert everything to hexadecimal
              #  i.e. [4,8,6,5,6,12,6,12,6,15,2,1]
              #   → ["4","8","6","5","6","C","6","C","6","F","2","1"]
  2ôJ         # Split it in parts of 2 and join them together
              #  i.e. ["4","8","6","5","6","C","6","C","6","F","2","1"]
              #   → ["48","65","6C","6C","6F","21"]
     H        # Convert that from hexadecimal to an integer
              #  i.e. ["48","65","6C","6C","6F","21"] → [72,101,108,108,111,33]
      ç       # And take its ASCII value
              #  i.e. [72,101,108,108,111,33] → ["H","e","l","l","o","!"]
       J      # Then join everything together (and output implicitly)
              #  i.e. ["H","e","l","l","o","!"] → "Hello!"

Kevin Cruijssen

Posted 2018-08-29T08:50:28.210

Reputation: 67 575

6

Perl 6, 88 86 84 bytes

{S:g{B(.*?)B(.D.|.)}=chr :16[$/.map:{first :k,~$_,("",|<ID AD OD UD>X~ <I A O U>)}]}

Try it online!

Jo King

Posted 2018-08-29T08:50:28.210

Reputation: 38 234

6

Perl 5 -p, 67 bytes

for$p(<{B,0D,1D,2D}{I,A,O,U}>){s/$p/chr$i+48/ge;$i++}$_=pack'H*',$_

Try it online!

nwellnhof

Posted 2018-08-29T08:50:28.210

Reputation: 10 037

5

Japt, 43 29 28 bytes

Unsurprisingly, a port of Dennis' Jelly solution works out much shorter.

Outputs an array of characters.

Åqbu)®¬®c ^1 %9%4Ãì2Ãò ®ìG d

Try it


Original, 42 bytes

Åqb £`bbidbad¾d`ò3n)ï`ia`q)m¬bXibÃò ®ìG d

Try it

Explanation

Åqb £`bbidbad¾d`ò3n)ï`ia`q)m¬bXibÃò ®ìG d
Å                                              :Slice off the first character
 qb                                            :Split on "b"
    £                                          :Map
     `bbidbad¾d`                               :  Compressed string "bbidbadbod"
                ò3n)                           :  Partition at every 3rd character from the end (["b","bid","bad","bod"])
                    ï                          :  Cartesian product
                     `ia`                      :   Compressed string "iaou"
                          q                    :   Split
                           )                   :  End Cartesian product
                            m                  :  Map
                             ¬                 :   Join
                              b                :  Index of
                               X               :   Current element
                                ib             :   Prepend "b"
                                  Ã            :End map
                                   ò           :Partition at every second element
                                     ®         :Map
                                      ìG       :  Convert from base-16 digit array to base-10 integer
                                         d     :  Get the character at that codepoint

Shaggy

Posted 2018-08-29T08:50:28.210

Reputation: 24 623

5

R, 141 135 bytes

function(x,y="I":"A":"O")intToUtf8(matrix(match(el(strsplit(gsub("D","",x),"B"))[-1],paste0(rep("":y,e=4),y:"U"))-1,,2,T)%*%16:1)
":"=c

Try it online!

Thanks to JayCe for saving 6 bytes!

Using some modular magic is likely to be shorter, but I'm pretty happy with this as a naive first pass.

Giuseppe

Posted 2018-08-29T08:50:28.210

Reputation: 21 077

1

Nice ! My favorite trick saves 6 bytes - inspired by your comment to an answer of mine the other day.

– JayCe – 2018-08-29T19:45:16.100

@JayCe very nice and neat! Even using it with the precedence over %*% I see. :-) You can also put \:`` as a function argument in case you wanted to use this in tandem with something else! – Giuseppe – 2018-08-29T19:57:13.457

That's right - I always tend to forget about the backquotes. – JayCe – 2018-08-29T20:15:28.417

5

C (gcc), 181 138 136 bytes

Hopefully there will be a C compiler in the future to compile this! :-)

Thanks to Max Yekhlakov and ceilingcat for the suggestions.

v,t,c,d;f(char*s){for(v=t=c=0;d=*s++;)t+=d==66?v=v*16+t,++c>2?v=!putchar(v),c=1:0,-t:d-65?d-79?d-68?d-85?0:3:4+t*3:2:1;putchar(v*16+t);}

Try it online!


In case the C compiler of the future only understands BIBABOBU-ified ASCII :-)

BIDUBIDOBOBODIBIDUBIDIBOBODIBIDOBUBUBADUBIDOBIDOBOBADIBIDOBUBIDOBADIBIDOBABIDUBOBOBADOBIDUBUBOBADABIDUBADUBIDOBIDOBIDOBODUBIDUBOBOBADIBIDUBIDOBUBODABIDUBIDIBUBODABIDOBUBUBODABUBIBUBADUBOBADOBIDUBUBUBADUBIDUBUBOBADUBOBADUBOBADABIDUBIDIBOBADUBUBODABOBADOBIDUBUBUBODABUBODABUBIDOBUBIDOBUBODUBIDUBIDOBUBODABIDUBIDOBOBADOBUBABUBIDOBOBADUBIDUBIDIBOBODIBOBADUBOBADUBIDOBUBUBODOBUBOBUBODUBIDUBIDOBUBODABOBABIDUBIBIDUBIDABIDUBIDIBIDOBUBIDOBADIBIDOBABIDUBOBOBADIBIDUBIDOBOBADABOBODIBIDOBUBUBODABUBABUBADOBUBIBOBODIBOBODABIDUBIDIBUBADOBOBADOBIDUBUBOBODABUBIDOBUBIDABUBODUBOBADOBIDUBUBOBODABUBIDUBUBADABUBODUBOBADOBIDUBUBOBODABUBIDOBUBADIBUBODUBOBADOBIDUBUBOBODABUBADIBUBIDABUBODUBUBIBUBADOBUBUBUBADOBUBIDIBOBADUBIDUBIDIBOBADOBUBUBUBADOBUBOBUBADOBUBABUBADUBIDUBIBIDUBIDABIDUBIDIBIDOBUBIDOBADIBIDOBABIDUBOBOBADIBIDUBIDOBOBADOBUBABUBIDOBOBADUBIDUBIDIBOBADABUBADUBIDUBODA

(Encoder Try it online!)

ErikF

Posted 2018-08-29T08:50:28.210

Reputation: 2 149

179 bytes - Try it online!

– Max Yekhlakov – 2018-08-30T10:34:15.110

Suggest c=printf(&v),v=0 instead of v=!putchar(v),c=1 – ceilingcat – 2018-10-19T06:44:56.047

4

JavaScript (Node.js), 131 128 bytes

s=>unescape(s.replace(/B.(D.)?/g,(f,s)=>(-~g(f[1])*4*!!s+g((s||f)[1])).toString(16),g=c=>'IAOU'.search(c)).replace(/../g,'%$&'))

Try it online! Link includes test cases. Alternative version, also 131 bytes:

s=>unescape(s.replace(/B.(D.)?/g,s=>(-~g(s[1])*4*!!s[3]+g(s[3]||s[1])).toString(16),g=c=>'IAOU'.search(c)).replace(/../g,'%$&'))

Try it online! Link includes test cases. Edit: Saves 3 bytes thanks to @Shaggy.

Neil

Posted 2018-08-29T08:50:28.210

Reputation: 95 035

1Using unescape() is a nice idea. – Arnauld – 2018-08-29T09:43:02.823

indexOf -> search to save a byte. – Shaggy – 2018-08-29T12:14:35.433

Also, it doesn't look like you need to assign the RegEx to r. – Shaggy – 2018-08-29T12:23:12.913

@Shaggy Whoops, that's a left-over from a previous iteration. Thanks! – Neil – 2018-08-29T12:28:30.430

4

Scala, 305 bytes

Well, I'm pretty sure this can be golfed out. But still, it exists. Takes input lowercase. f prints out the result in stdout.

EDIT: -8 chars thanks to me not being dumb anymore (spaces); -13 chars thanks to crater2150

var k=Seq("bi","ba","bo","bu")
k++=k.init.flatMap(a=>Seq("di","da","do","du").map(a+_))//Putting "bu" here instead of at line 1, and in place of using init, would be interesting... if it did not cause a typing problem
var m=Seq[String]()
def g(a:Seq[String],b:Int)=k.indexOf(a(b)).toHexString
def f(a:String){a.split('b').drop(1).foreach(x=>m:+="b"+x)
var i=0
while(i<m.length){print(Integer.parseInt(g(m,i)+g(m,i+1),16).toChar)
i+=2}}

Try it online!

V. Courtois

Posted 2018-08-29T08:50:28.210

Reputation: 868

You can replace dropRight(1) with init, Seq("").drop(1) with Seq[String](), and map(b=>a+b) with map(a+_) – crater2150 – 2018-09-02T09:31:10.053

@crater2150 thanks! my compiler did not want map(a+_) to work but I knew I could do that. thanks for other tips! – V. Courtois – 2018-09-02T09:44:56.910

4

Bash + common Linux utilities, 75 bytes

sed $(printf `printf %s s/{B{O,A,I}D,B}{U,O,A,I}/%x/g\;` {15..0})|xxd -r -p

Try it online!

Digital Trauma

Posted 2018-08-29T08:50:28.210

Reputation: 64 644

3

Python 2, 142 139 127 118 bytes

lambda s:''.join(chr(16*a+b)for a,b in zip(*[iter(4*F(l[:-2])+F(l[-1])-1for l in s.split('B')[1:])]*2));F=' IAOU'.find

Try it online!

TFeld

Posted 2018-08-29T08:50:28.210

Reputation: 19 246

3

Python 2, 93 bytes

lambda w:''.join('c60238e4d1_b7f95a'[hash(x)%3046%17]for x in w.split('B')[1:]).decode('hex')

Try it online!

ovs

Posted 2018-08-29T08:50:28.210

Reputation: 21 408

I love answers that abuse the hash value of sufficiently small lists – Lyndon White – 2018-08-30T05:55:29.217

3

Ruby, 86 75 bytes

->s{[s.gsub(/B[^B]+/){|x|"546798ABDCEF1023"[x.to_i(31)/7%38%20]}].pack'H*'}

Try it online!

G B

Posted 2018-08-29T08:50:28.210

Reputation: 11 099

3

Dyalog APL, 74 72 bytes

Beginner level solution in Dyalog APL (just started learning this a couple of days ago!). Defines a dfn that takes one right argument (the input). 72 characters, 72 bytes when using the dyalog encoding. Based on Emigna's solution in 05AB1E .

{⎕UCS 16⊥¨(1 0⍴⍨≢t)⊂1-⍨(,('B',('B'∘.,'IAO'),¨'D')∘.,'IAOU')⍳t←('B'⍷⍵)⊂⍵}

vancan1ty

Posted 2018-08-29T08:50:28.210

Reputation: 131

Welcome to PPCG and to the world of APL golfing. This is amazing after only a couple of days of learning APL. You may enjoy the APL golfing tips. Feel free to participate in The APL Orchard too!

– Adám – 2018-09-03T18:14:35.753

2

Jelly, 39 bytes

®+“IAO”+”D®;p“IAOU”Ẏ€
=”B©œṗµḊ¢iⱮ’s2ḅ⁴Ọ

Try it online!

The technique used is very similar to Emigna's. I will golf this further soon, hopefully.

Mr. Xcoder

Posted 2018-08-29T08:50:28.210

Reputation: 39 774

2

05AB1E, 30 bytes

ć¡Ç1^9%4%εDg≠i421øP]€OžvβžzвçJ

Port of @Dennis' insane Jelly answer (just with less convenient builtins). So make sure to upvote him!

Try it online or verify all test cases.

Explanation:

ć¡             # Split the input-string on its first character ('B')
               #  i.e. "BIDABIDIBIDOBIDABIDUBUBIDUBIDI"
               #   → ["IDA","IDI","IDO","IDA","IDU","U","IDU","IDI"]
  Ç            # Convert each character to it's ordinal value
               #  → [[73,68,65],[73,68,73],[73,68,79],[73,68,65],[73,68,85],85,[73,68,85],[73,68,73]]
   1^          # XOR it by 1
               #  → [[72,69,64],[72,69,72],[72,69,78],[72,69,64],[72,69,84],84,[72,69,84],[72,69,72]]
     9%        # Take modulo-9
               #  → [[0,6,1],[0,6,0],[0,6,6],[0,6,1],[0,6,3],3,[0,6,3],[0,6,0]]
       4%      # Take Modulo-4
               #  → [[0,2,1],[0,2,0],[0,2,2],[0,2,1],[0,2,3],3,[0,2,3],[0,2,0]]
ε         ]    # Now map it to:
 Dg≠i          # If the length is not 1:
               #  i.e. [0,2,1] → 3 → 1 (truthy)
               #  i.e. 3 → 1 → 0 (falsey)
     421øP     # Multiply the first number by 4, second by 2, and third by 1
               #  i.e. [0,2,1] and [4,2,1] → [[0,4],[2,2],[1,1]] → [0,4,1]
           €O  # Then sum every inner list
               #  [[0,4,1],[0,4,0],[0,4,2],[0,4,1],[0,4,3],3,[0,4,3],[0,4,0]]
               #   → [5,4,6,5,7,3,7,4]
žvβ            # Convert this list from base-16 to base-10
               #  → 1415934836
   žzв         # Convert this integer from base-10 to base-256
               #  → [84,101,115,116]
      ç        # Convert this number to ASCII characters
               #  → ["T","e","s","t"]
       J       # Join the characters together (and output implicitly)
               #  → "Test"

Kevin Cruijssen

Posted 2018-08-29T08:50:28.210

Reputation: 67 575

Wondered how you snipped 3 off emignas score. Jeebus this is complex +1 for the effort on the port-- never used XOR or that base conversion before! Will keep in mind from now on! – Magic Octopus Urn – 2018-09-04T23:22:49.533

@MagicOctopusUrn Yeah, Dennis' answer is something I would have never came up with myself.. And in Jelly this is done way more efficient, since his answer is 15 bytes and mine is 30. Just figured it was worth posting as well however, even though it's a port. I've only used XOR once myself, and Base conversion pretty often. – Kevin Cruijssen – 2018-09-05T09:29:07.487

2

Brain-Flak, 178 bytes

{(([((((()()()()){}){}){}()){}]{}){{}<>(({}){}){}(<>)}{}<({}(<>))(<>)((()()()())({})()){{(({})){({}[()])<>}{}}<>({}<>)<>{}}{}><>{}{})<>}<>([]){{}({}(((({}){}){}){}){}<>)<>([])}<>

Try it online!

Explanation

# Step 1: convert to hex.
# For each pair of letters in the input:
{

  (

    # Compare first letter to B
    ([((((()()()()){}){}){}()){}]{})

    # If not B, pop previous output, multiply by 4, and put on third stack.
    # 4 is added automatically from pushing/popping the difference
    # between the letters B and D.
    {{}<>(({}){}){}(<>)}{}

    <

      # Push second letter in pair to other stack
      ({}(<>))

      # Push 4 and 9
      (<>)((()()()())({})())

      # Compute 3-((8-(n mod 9)) mod 4)
      # (same as (n-1) mod 9 mod 4)
      {{(({})){({}[()])<>}{}}<>({}<>)<>{}}{}

    >

    # Add result to third stack (either 0 or 4*previous+4)
    <>{}{}

  # Push onto second stack
  )

<>}

# Step 2: Pair up hex digits.
# While digits remain on right stack:
<>([]){{}

  # Push top of stack + 16*second on stack to left stack
  ({}(((({}){}){}){}){}<>)<>

([])}

# Switch to left stack for output.
<>

Nitrodon

Posted 2018-08-29T08:50:28.210

Reputation: 9 181

2

Java (JDK 10), 199 bytes

s->{var z="";for(var x:s.substring(1).split("B")){int d=-1;for(var y:x.split("D"))d=-~d*4+"IAOU".indexOf(y);z+=(char)(d>9?d+55:d+48);}return new String(new java.math.BigInteger(z,16).toByteArray());}

Try it online!

Credits

Olivier Grégoire

Posted 2018-08-29T08:50:28.210

Reputation: 10 647

1Could you use -~d instead of (d+1)? – Arnauld – 2018-09-01T12:45:15.833

Yep, thanks! I had those in my first version, then I toyed with the idea of using chars instead and when I came back to my first version, I totally forgot it again. ;) – Olivier Grégoire – 2018-09-01T13:27:16.517

2

VBA (Excel), with an amazing 322 244 bytes

Yeah, and I LOVE hexadecimal. (There's no sarcasm font yet, so I'm using italics for now) I'll add comments if someone wants, but I think it's self explanatory. Golfing happened.

Sub b(s)
For Each c In Split(Replace(s,"D",""),"B")
c=Application.Match(c,Array("I","A","O","U","II","IA","IO","IU","AI","AA","AO","AU","IO","OA","OO","OU"),0)
If Not IsError(c)Then d=d &c-1:If Len(d)=2Then e=e &Chr("&h"&d):d=""
Next
Debug.?e
End Sub

With Comments:

Sub b(s)
  'For each string between B's (Remove the D's first)
  For Each c In Split(Replace(s,"D",""),"B")
    'Get the index of the element in the array (Can cause error if empty)
    c = Application.Match (c,Array("I","A","O","U","II","IA","IO","IU","AI","AA","AO","AU","IO","OA","OO","OU"),0)
    'If c isn't an error
    If Not IsError(c) Then
      'Subtract 1 from c and add to d  --> Array index is 1 based
      d = d & (c-1)
      'If d is 2 characters
      If Len(d)=2 Then
        'Add the char from the hex value of d   --> &h forces Hex
        e = e & Chr("&h" & d)
        'Reset d
        d = ""
      End if
    End if
  Next
  'Print the output
  Debug.Print e
End Sub

I really tried to get this into the VB Immediate Window, but it doesn't seem to work there... that would cut 11 characters I think. I also wanted to put the Match statement into brackets, but that causes a silent error everytime. Help is appreciated :D

seadoggie01

Posted 2018-08-29T08:50:28.210

Reputation: 181

Welcome to PPCG! – Arnauld – 2018-09-03T14:35:20.147

Thanks! I've been here for a while, just never been able to post anything :) – seadoggie01 – 2018-09-03T15:22:46.883

Array("I","A","O","U","II","IA","IO","IU","AI","AA","AO","AU","IO","OA","OO","OU") -> Split("I A O U II IA IO IU AI AA AO AU IO OA OO OU") and Not IsError(c) -> IsError(c)=0 – Taylor Scott – 2019-02-15T19:14:03.793

1

Haxe, 228 bytes

s->{var l=(u,i)->((i=u.charCodeAt(i))&8==8?0:1)|((i>>1)&2),p=s.split("B"),i=-1,q,o;[while((i+=2)<p.length)String.fromCharCode(l(q=p[i+1],o=q.length-1)+((o>1?l(q,0)+1:0)+((l(q=p[i],o=q.length-1)+o*(l(q,0)+1)*2)*4))*4)].join("");}

Not the best, standard library function names are too large :(

Try it online!

Aurel Bílý

Posted 2018-08-29T08:50:28.210

Reputation: 1 083

1

Pyth, 35 bytes

mCid16cm+4imx"IAOU"k.[N2d4tc-Q\D\B2

Outputs as a list of characters.
Try it here

Explanation

mCid16cm+4imx"IAOU"k.[N2d4tc-Q\D\B2
                          tc-Q\D\B   Get the vowels associated with each digit.
       m            .[N2d            Pad with a quote.
           mx"IAOU"k                 Find each character's position.
        +4i              4           Convert to base 4 and add 4.
      c                           2  Split the result into pairs.
mCid16                               Get the associated ASCII characters.

user48543

Posted 2018-08-29T08:50:28.210

Reputation:

1

Charcoal, 36 bytes

FS≡ιB⊞υ⁰D⊞υ×⁴⊕⊟υ⊞υ⁺⊟υ⊕⌕AOUι⭆⪪υ²℅↨ι¹⁶

Try it online! Link is to verbose version of code. Explanation:

FS≡ι

Loop over each input character and switch.

B⊞υ⁰

If it's a B then push 0 to the predefined empty list.

D⊞υ×⁴⊕⊟υ

If it's a D then pop the last value, increment it, multiply by 4, and push it again.

⊞υ⁺⊟υ⊕⌕AOUι

Otherwise, find the index in the string AOU, increment it, and add to the last value.

⭆⪪υ²℅↨ι¹⁶

Split the list into pairs of values, decode as base 16, convert to ASCII, and implicitly print.

Neil

Posted 2018-08-29T08:50:28.210

Reputation: 95 035

1

Clean, 145 134 bytes

import StdEnv                   // import things like addition and comparison
?c=(743rem(toInt c))/16         // magical formula that maps ['IAOU'] to [0,1,2,3]
@[_,b,'D',d:t]=[?d+ ?b*4+4: @t] // convert B#D#
@[_,b:t]=[?b: @t]               // convert "B#"
@_=[]                           // handle base case
$[u,v:t]=[u<<4+v: $t]           // turn the digits into 2-digit numbers
$e=e                            // handle base case

toString o$o@                   // convert to string (make numbers (make digits))

Try it online!

Explained:

Οurous

Posted 2018-08-29T08:50:28.210

Reputation: 7 916

1

PHP, 119 bytes

foreach(explode(B,$argn)as$i=>$m)($v=$v*16+4*strpos(XIAO,$m[-3]?:B)+strpos(IAOU,$m[-1]?:B))?$i&1||print chr($v&=255):0;

assumes uppercase input. Run as pipe with -nR or try it online.

requires PHP 7.1
for older PHP, use substr($m,-3,1) and substr($m,-1) instead of $m[-<x>] (+16 bytes);
for younger PHP, put B, XIAO and IAOU in quotes to avoid warning messages (+10 bytes).

Titus

Posted 2018-08-29T08:50:28.210

Reputation: 13 814

0

05AB1E, 40 bytes

'B"IAOU"©âÐUs'D®ââJ)˜sXíDεSðý}:#khJ2ôHçJ

Try it online!

Magic Octopus Urn

Posted 2018-08-29T08:50:28.210

Reputation: 19 422

0

PHP, 163 bytes

function f($s){$t=[I=>0,A=>1,O=>2,U=>3];for($q=explode(B,$s);$a=&$q[++$i];){$a=($a[1]?($t[$a[0]]+1)*4:0)+$t[$a[2*($a[1]==D)]];$i%2?:print(chr(($q[$i-1]<<4)+$a));}}

Call f(string $s) with the appropriate string of bibabobu-encoded characters, and it will print the decoded string.

Élektra

Posted 2018-08-29T08:50:28.210

Reputation: 284

0

Python 3, 199 bytes

import re
lambda s:''.join(eval(re.sub(r'(\d+), (\d+)',r'chr(16*\1+\2)',str(eval(s.replace('I','1').replace('A','2').replace('O','3').replace('U','4').replace('B',',-1+').replace('D','*4+')[1:])))))

Not the shortest but without loops.

user0815

Posted 2018-08-29T08:50:28.210

Reputation: 121