title: My Word can beat up your Word

text:
# Question
Title: My Word can beat up your Word
## PROBLEM

Given two words, find the winner in a **digital root** battle.

Define the **digital root** of a word this way:

1. Each letter of the alphabet is assigned a number: *A = 1, B = 2, C = 3, ..., Z = 26*
2. Add the values for each letter to total the word. Take "CAT", for example. *C+A+T = 3+1+20 = 24*
3. Add all the single digits that make up that result: *24 =\> 2 + 4 = 6*
4. Repeat step #3 until you reach a single digit. That single digit is the **digital root** of the word.

**Rules:**

1. A winner is declared if its **digital root** is larger than the other.
2. If the **digital root** values are equal, shorten the words by removing every instance of the highest value letter from both words and recalculating.
3. Repeat steps #1 and #2 until there is a winner **or** one of the words has only a single letter (or no letters) remaining.
4. If the **digital root** values are equal after going through the shortening process, the longer word is declared the winner.
5. If the words are of equal length and no winner is found after going through the shortening process, no winner is declared.

**Special rules:**

1. No use of modulus is allowed in the calculation of the **digital root** itself. It can be used anywhere else.
2. Assume words will consist only of uppercase letters - no punctuation, no spaces, etc.

## INPUT

Pull the words in through stdin (comma-separated). method parameters, or however you want. Make it clear in your solution or the code how the words are parsed or prepared.

## OUTPUT

Display the winning word. If there is no winner, display "STALEMATE".

**Examples:**

intput: CAN,BAT

```
CAN = 18 = 9
BAT = 23 = 5

```

output: CAN

intput: ZOO,NO

```
ZOO = 56 = 11 = 2
NO = 29 = 11 = 2

OO = 30 = 3
N = 14 = 5

```

output: NO

***UPDATE**: Input must be read using stdin with the words as a comma-separated string.*

***UPDATE**: Added a couple examples to test against.*

***UPDATE**: clarified the removal of the highest valued letter in the case of a tie - this also alters slightly the stop condition as well - if a word is one letter or zero letters long, the shortening process is stopped*

# Answer
## J, 100

```
z=:"."0@":@(+/)^:9@(64-~a.i.])@(#~' '&i.)"1
f=:*@-/"2@(z@((]#~]i.~{.@\:~)"1^:([:=/z))){'STALEMATE'&,

```

runs like this:

```
f 'NO',:'ZOO'
NO
f 'CAN',:'BAT'
CAN
f 'FAT',:'BANANA'
FAT
f 'ONE',:'ONE'
STALEMATE

```

it doesn't *yet* accept input exactly as asked.
> 9 votes

# Answer
## APL (Dyalog) (~~91~~ 86)

```
⎕ML←3⋄{Z≡∪Z←{2>⍴⍕⍵:⍵⋄∇+/⍎¨⍕⍵}¨+/¨⎕A∘⍳¨⍵:G[↑⍒Z]⋄1∊↑¨⍴¨⍵:'STALEMATE'⋄∇1∘↓¨⍵}G←Z⊂⍨','≠Z←⍞

```

Explanation (in order of execution):

* `⎕ML←3`: set ML to 3 (this makes  mean partition, among other things).
* `G←Z⊂⍨','≠Z←⍞`: read input, separate by commas, store in G and pass to the function.
* `+/¨⎕A∘⍳¨⍵`: calculate the score for each word. (`⎕A` is a list containing the alphabet.)
* `Z←{2>⍴⍕⍵:⍵⋄∇+/⍎¨⍕⍵}¨`: calculate the digital root for each score (by summing all digits as long as there is still more than one digit) and store them in Z.
* `Z≡∪Z`: if all scores are unique...
* `:G[↑⍒Z]`: ...then output the word with the highest score (from the original list).
* `⋄1∊↑¨⍴¨⍵:'STALEMATE'`: otherwise (if there's a tie), if one of the words is of length 1, output STALEMATE.
* `⋄∇1∘↓¨⍵`: otherwise, take the first letter off each word and run the function again.
> 9 votes

# Answer
# Ruby - 210

```
d,e=(a,b=$<.read.chop.split(/,/)).map{|w|w.bytes.sort}
r=->w,o=65{n=0;w.map{|c|n+=c-o};n>9?r[n.to_s.bytes,48]:n}
d.pop&e.pop while r[d]==r[e]&&d[1]&&e[1]
$><<[[:STALEMATE,a,b][a.size<=>b.size],a,b][r[d]<=>r[e]]

```

Tests:

```
$ ruby1.9 1128.rb <<< CAN,BAT
CAN

$ ruby1.9 1128.rb <<< ZOO,NO
NO

$ ruby1.9 1128.rb <<< ZOO,ZOO
STALEMATE

```
> 5 votes

# Answer
## Haskell, 205 characters

```
import List
s b=d.sum.map((-b+).fromEnum)
d q|q<10=q|1<3=s 48$show q
f=map(s 64.concat).tails.group.reverse.sort
w(a,_:b)=f a#f b where x#y|x<y=b|x>y=a|1<3="STALEMATE"
main=getLine>>=putStrLn.w.span(/=',')

```

Sample runs:

```
> ghc --make WordVsWord.hs
[1 of 1] Compiling Main             ( WordVsWord.hs, WordVsWord.o )
Linking WordVsWord ...

> ./WordVsWord <<< CAN,BAT
CAN

> ./WordVsWord <<< ZOO,NO
NO

> ./WordVsWord <<< FAT,BANANA
FAT

> ./WordVsWord <<< ONE,ONE
STALEMATE

```

---

* Edit: (227 -\> 219) better picking of winner, shortened pattern match in `w`, imported older, shorter module
* Edit: (219 -\> 208) Incorporate JB's suggestions
* Edit: (208 -\> 205) handle negative numbers, exploiting odd rules in Haskell about hyphen
> 5 votes

# Answer
## Perl, 224 ~~225~~ ~~229~~

Basic golfing (nothing smart yet):

```
split",",<>;$_=[sort map-64+ord,/./g]for@a=@_;{for(@b=@a
){while($#$_){$s=0;$s+=$_ for@$_;$_=[$s=~/./g]}}($a,$b)=
map$$_[0],@b;if($a==$b){pop@$_ for@a;@{$a[1]}*@{$a[0]}&&
redo}}say+("STALEMATE",@_)[$a<=>$b||@{$a[0]}<=>@{$a[1]}]

```

Perl 5.10 and above, run with `perl -M5.010 <file>` or `perl -E '<code here>'`

```
$ perl -M5.010 word.pl <<<CAN,BAT
CAN
$ perl -M5.010 word.pl <<<ZOO,NO
NO

$ perl -M5.010 word.pl <<<NO,ON
STALEMATE

```
> 3 votes

# Answer
## VBA (242 462)

```
Function s(q,Optional l=0)
s=-1:t=Split(q,","):r=t:m=t
For j=0 To 1
m(j)=0:w=t(j)
While Len(w)>1 Or Not IsNumeric(w)
b=0
For i=1 To Len(w)
a=Mid(w,i,1):a=IIf(IsNumeric(a),a,Asc(a)-64):b=b+a
If m(j)+0<a+0 Then m(j)=a
Next
w=b
Wend
r(j)=b
Next
s=IIf(r(0)>r(1),0,IIf(r(0)<r(1),1,s))
For j=0 To 1
r(j)=Replace(t(j),Chr(m(j)+64),"",,1)
Next
If s<0 And Len(t(0))+Len(t(1))>2 Then s=s(r(0) & "," & r(1),1)
If l=0 Then If s>=0 Then s=t(s) Else s="STALEMATE"
End Function

```

Turns out the below code didn't match the spec, so I had to re-work, adding much length (see above). :-/ This may be able to be golfed further, but it's already pretty compact and I doubt I'll be able to bring it back down to a competitive score.

The original (below) did not remove the highest-valued letter from the words when there was a tie.

```
Sub s(q)
t=Split(q,",")
r=t
For j=0 To 1
w=t(j):b=0
For i=1 To Len(w)
b=b+Asc(Mid(w,i,1))-64
Next
While Len(b)>1
d=0
For i=1 To Len(b)
d=d+Mid(b,i,1)
Next
b=d
Wend
r(j)=b
Next
MsgBox IIf(r(0)>r(1),t(0),IIf(r(0)<r(1),t(1),"STALEMATE"))
End Sub

```
> 2 votes

# Answer
# K, 106

```
{a::x;@[{$[(>). m:{+/"I"$'$+/@[;x].Q.A!1+!26}'x;a 0;(<). m;a 1;.z.s 1_'x@'>:'x]};x;"STALEMATE"]}[","\:0:0]

```

Uses exception handling to catch stack errors, which result in cases of stalemate.
> 2 votes

# Answer
This really took my fancy and is my first post. Although it is old I noticed no one had done a php version so here is mine.

```
<?php $f='CAN,CBN';$w=explode(',',$f);$a=$ao=$w[0];$b=$bo=$w[1];$c='';
function splice($a,$t){$s=$h=0;$y=array();$x=str_split($a);
foreach($x as $k=>$v){$s=$s+ord($v)-64;if($v>$h){$h=$k;}}
$y[0]=$s;if($t==1){unset($x[$h1]);$y[1]=$x;}return $y;}
while($c==''){$y1=splice($a,0);$y2=splice($b,0);$y3=splice($y1[0],1);
$y4=splice($y2[0],1);if($y3[0]>$y4[0]){$c=$ao;}else if($y3[0]<$y4[0]){$c=$bo;
}else if((strlen($a)<1)OR(strlen($b)<1)){if(strlen($a)<strlen($b)){$c=$ao;}
else if(strlen($b)<strlen($a)){$c=$bo;}else{$c='STALEMATE';}}}
echo $c;
?>

```

534 Characters.

Now I am unsure as to the rules for starting off so I started with $f='CAN,CBN' as my input. I hope that was right. I have run all the tests and it passes all of them although it is not particularly elegant. I really must get some sleep now but I had great fun working this out - thank you for a great puzzle.

Coded on http://codepad.org/ZSDuCdin
> 2 votes

# Answer
# D: 326 Characters

```
import std.algorithm,std.array,std.conv,std.stdio;void main(string[]a){alias reduce r;auto b=array(splitter(a[1],","));auto s=map!((a){int n=r!"a+b"(map!"cast(int)(a-'A')+1"(a));while(n>9)n=r!"a+b"(map!"cast(int)(a-'0')"(to!string(n)));return n;})(b);int v=r!"a>b?a:b"(s);writeln(count(s,v)>1?"STALEMATE":b[countUntil(s,v)]);}

```

More Legibly:

```
import std.algorithm, std.array, std.conv, std.stdio;

void main(string[] a)
{
    alias reduce r;

    auto b = array(splitter(a[1], ","));
    auto s = map!((a){int n = r!"a + b"(map!"cast(int)(a - 'A') + 1"(a));

                      while(n > 9)
                          n = r!"a+b"(map!"cast(int)(a - '0')"(to!string(n)));

                      return n;
                     })(b);
    int v = r!"a > b ? a : b"(s);

    writeln(count(s, v) > 1 ? "STALEMATE" : b[countUntil(s, v)]);
}

```
> 1 votes

# Answer
## Mathematica

Some details still missing

```
a = {"ZOO"}; b = {"NO"}
f = FixedPoint[IntegerDigits@Total@# &, #] &

If[(s = f /@
        NestWhile[(# /. Max@# -> 0 &) /@ # &, (ToCharacterCode @@ # - 64) & /@ #,
        f[#[[1]]] == f[#[[2]]] &, 1, 5] &@{a, b})[[1, 1]] > s[[2, 1]],
   a, b, "STALMATE"]

{"NO"}

```
> 1 votes

# Answer
# Mathematica 220 207

After writing this, I noticed that this follows the same reasoning that Belisarius used,

```
h@u_ := ToCharacterCode@u - 64;
m@w_ := FromCharacterCode[Most@Sort@h@w + 64];
f@v_ := FixedPoint[Tr@IntegerDigits@# &, Tr@h@v];
x_~g~y_ := If[f@x == f@y, g[m@x, m@y], If[f@x > f@y, 1, 2]];
x_~z~x_ := "STALEMATE";
x_~z~y_ := {x, y}[[x~g~y]]

```

**Usage**

```
z["ZOO", "NO"]
z["CAN", "BAT"]
z["FAT", "BANANA"]
z["ONE", "ONE"]

```

Because the response is not competitive (being so long-winded), I decided to use an input format more congenial to Mathematica.
> 1 votes

# Answer
# CoffeeScript - 335

```
z=(a,b,g=a,h=b)->c=y a;d=y b;e=a.length;f=b.length;return g if(c>d);return h if(d>c);return g if(e<2&&f>1);return h if(f<2&&e>1);return "STALEMATE" if(f==e&&f<2);z(x(a),x(b),a,b)
y=(a)->t=0;t+=c.charCodeAt(0)-1 for c in a;t-=9 while 9<t;t
x=(a)->for i in[90..65]
 b=new RegExp(String.fromCharCode(i));return a.replace b, "" if b.test a

```

Not as happy with this one as I might have been, but I'll put it up anyway. The actual scoring is very concise (`y` function), but the `if`s to compare results (in `z`) get pretty long.

To use it call `z` with your two words (e.g. `z 'FOO','BAR'`). It will score both words and return the higher scoring word. If it's a tie, it will recurse with the modified words (keeping the originals to return eventually, hence the extra two parameters) which it gets from the `x` function.

The equivalent (expanded) javascript for those interested:

```
var x, y, z;

z = function(a, b, g, h) {
  var c, d, e, f;
  if (g == null) {
    g = a;
  }
  if (h == null) {
    h = b;
  }
  c = y(a);
  d = y(b);
  e = a.length;
  f = b.length;
  if (c > d) {
    return g;
  }
  if (d > c) {
    return h;
  }
  if (e < 2 && f > 1) {
    return g;
  }
  if (f < 2 && e > 1) {
    return h;
  }
  if (f === e && f < 2) {
    return "STALEMATE";
  }
  return z(x(a), x(b), a, b);
};

y = function(a) {
  var c, t, _i, _len;
  t = 0;
  for (_i = 0, _len = a.length; _i < _len; _i++) {
    c = a[_i];
    t += c.charCodeAt(0) - 1;
  }
  while (9 < t) {
    t -= 9;
  }
  return t;
};

x = function(a) {
  var b, i, _i;
  for (i = _i = 90; _i >= 65; i = --_i) {
    b = new RegExp(String.fromCharCode(i));
    if (b.test(a)) {
      return a.replace(b, "");
    }
  }
};

```
> 1 votes

# Answer
## Racket 479 bytes

```
(define(dl n)(let p((ol '())(n n))(let-values(((q r)(quotient/remainder n 10)))(if(= q 0)(cons r ol)(p(cons r ol)q)))))
(define(dr N)(let p2((n N))(define s(apply +(dl n)))(if(< s 10)s(p2 s))))
(let p3((l(for/list((i(string->list s)))(-(char->integer i)64)))(k(for/list((i(string->list t)))(-(char->integer i)64))))
(let((a(dr(apply + l)))(b(dr(apply + k))))(cond[(> a b)s][(< a b)t][(equal? l k)"STALEMATE"][else(p3(remove*(list(apply max l))l)(remove*(list(apply max k))k))])))

```

Ungolfed:

```
(define (f s t)

  (define (getDigitList n)                     ; sub-fn  to get digit list
    (let loop ((ol '())
               (n n))
      (let-values (((q r) (quotient/remainder n 10)))
        (if (= q 0) (cons r ol)
            (loop (cons r ol) q)))))

  (define (digit_root N)                       ; sub-fn to get digital root of a number
    (let loop2 ((n N))
      (define s (apply + (getDigitList n)))
      (if (< s 10)
          s
          (loop2 s))))

  (let loop3 ((l (for/list ((i (string->list s)))  ; actual fn to compare 2 strings
                   (- (char->integer i) 64)))
              (k (for/list ((i (string->list t)))
                   (- (char->integer i) 64))))
    (let ((a (digit_root (apply + l)))
          (b (digit_root (apply + k))))
      (cond
        [(> a b) s]
        [(< a b) t]
        [(equal? l k) "STALEMATE"]
        [else (loop3 (remove* (list (apply max l)) l)
                     (remove* (list (apply max k)) k)
                     )]
        ))))

```

Testing:

```
(f "CAN" "BAT")
(f "ZOO" "NO")

```

Output:

```
"CAN"
"NO"

```
> 1 votes

# Answer
**JAVA**

```
    public static void main(String args[]) throws Exception{
        String input=(new BufferedReader(new InputStreamReader(System.in)).readLine());
        StringTokenizer st = new StringTokenizer(input, ",");
        String w1 = st.nextToken();String w2 = st.nextToken();int s1=0;int s2=0;
        String flag="";
        do{ Integer sum1=0;Integer sum2=0;
        for (int i=0;i<w1.length();i++)
            sum1+=((int)w1.charAt(i) - 64);
        for (int i=0;i<w2.length();i++)
            sum2+=((int)w2.charAt(i) - 64);
        while (sum1.toString().length()>1){
            s1=0;
            for (int i=0;i<sum1.toString().length();i++)
                s1+=((int)sum1.toString().charAt(i)-48);
            sum1=s1;
        }
        while (sum2.toString().length()>1){
            s2=0;
            for (int i=0;i<sum2.toString().length();i++)
                s2+=((int)sum2.toString().charAt(i)-48);
            sum2 =s2;
        }
        flag=(s1>s2)?w1:(s1!=s2)?w2:"";
        if (flag!="")
            {st = new StringTokenizer(input,",");
                if (s1>s2)
                    System.out.println(st.nextToken());
                else{
                    st.nextToken();
                    System.out.println(st.nextToken());
                }
            }
        int max=0;
        for (int i=0;i<w1.length();i++){
            max=((int)w1.charAt(i)>max)?(int)w1.charAt(i):max;
        }
        w1 = w1.replace((char)max, (char)64);
        max=0;
        for (int i=0;i<w2.length();i++){
            max=((int)w2.charAt(i)>max)?(int)w2.charAt(i):max;
        }
        w2 = w2.replace((char)max, (char)64);
            }while(flag=="" && !w1.equals(w2));
    if (flag.length()<1)
        System.out.println("STALEMATE");
        }

```
> 0 votes

# Answer
C++, 473 (I'm borrowing a course iron)

```
#include<iostream>
#define $ string
#define _ return
using namespace std;$ S($&s){int i=-1,m=i,x=0;while(++i<s.length())if(s[i]-'@'>x)m=i,x=s[i];s.erase(m,1);_ s;}int M($ w){int i,v=0;for(i=0;i<w.length();++i)v+=w[i]-'@';while(v>9){i=0;while(v)i+=v-v/10*10,v/=10;v=i;}_ v;}$ B($ x, $ y){while(!(M(x)-M(y)))S(x),S(y);if(M(x)>M(y))_ x;if(M(x)<M(y))_ y;_"STALEMATE";}int main(int c,char**v){$ s;cin>>s;$ x=s.substr(0,s.find(',')),y=s.substr(s.find(',')+1);cout<<B(x,y)<<endl;_ 0;}

```

I'm sure I could shorten it up somehow, but I'm tired.

Edit: originally took command line argument, modified to use cin. It's probably a few characters longer now but I'm too tired to recount it.
> 0 votes

# Answer
**Python :383 chars**

run the function `c('CAN','BAT')`:

```
def k(j):
 l=list(j);l.remove(max(j));return''.join(l)
def f(x):
 x=str(x)
 if len(x)==1 and x.isdigit():return int(x)
 return f(sum('ABCDEFGHIJKLMNOPQRSTUVWXYZ'.index(y)+1 for y in x)) if x.isalpha() else f(sum(map(int,x)))
def c(a,b):
 v=f(a);u=f(b);
 if v>u:return a
 if v<u:return b
 return'STALEMATE' if v==u and (len(a)==1 or len(b)==1)else c(k(a),k(b))

```
> 0 votes

# Answer
# F#, ~~559~~ ~~533~~ 530 bytes

Not competitive as of yet. I'm sure *c* can be made shorter as well as the last few lines. Not having easier access to command line args is also hurting here.

```
open System
let m=Seq.map
let a s=s="";s.ToUpper()|>m(fun c->int c-64)
let rec c i=if i>9 then string i|>m(int>>(-))|>m(fun x->x 48)|>Seq.sum|>c else i
let b i=Seq.fold(fun(r,a)j->(Seq.sum i-a)::r,a+j)([],0)(Seq.sortBy(~-)i)|>fst|>m c
[<EntryPoint>]
let x z=
 let y=z.[0].Split(',')
 let u,v=y.[0].Length,y.[1].Length
 printf"%s"(Seq.fold2(fun s l r->if l=r then 3::s else if l>r then 0::s else 1::s)[](b<|a y.[0])(b<|a y.[1])|>Seq.tryFind((>)3)|>function|None when u>v->y.[0]|None when u<v->y.[1]|Some x->y.[x]|_->"STALEMATE")
 0

```

Try it online!

* Saved 3 bytes by constraining s to string by comparing it with string

# Ungolfed version

```
open System
let m=Seq.map // this is just to save some characters and I'll use Seq.map for this version

let toIntList s =
    s = "" // constrain s to type string
    s.ToUpper()
    |>Seq.map (fun c -> int c - 64) // converts char value to int and offsets it so that A=1

let rec digitSumUntilSingle i =
    if i > 9 then
        string i                // convert number to string
        |>Seq.map ( int>>(-) )  // convert individual char to int and partially apply substraction
                                // this returns a function
        |>Seq.map (fun x -> x 48) // provide last parameter for substraction, this is equivalent to
                                  // charValue - 48
        |>Seq.sum                 // sum over all digits
        |>digitSumUntilSingle     // recursively call this function again in case we are >9
    else
        i

let calculateDigitalRoot input =
    Seq.fold(fun (result, acc) current ->       // calculate digital root for all possible iterations
                (Seq.sum input - acc)::result,  // basically, this calculates Rule 3 until the end for a given word
                acc + current
            ) ([], 0) (Seq.sortBy (~-) input) // sort input by value descending
    |>fst   // only interested in the lits, not the final accumulator
    |>Seq.map digitSumUntilSingle

[<EntryPoint>]
let main (args) =
    let y = args.[0].Split(',')
    let leftLength = y.[0].Length
    let rightLength = y.[1].Length

    Seq.fold2 (fun state left right ->
                if left = right then
                    3::state
                else if left > right then
                    0::state                // 0 is chosen because this represents y[0] index
                else
                    1::state
               ) [] (calculateDigitalRoot (toIntList y.[0])) (calculateDigitalRoot (toIntList y.[1]))
    |> Seq.tryFind ((>) 3)                  // try to find first variation where left and right digital root isn't equal
    |> function
        | None when leftLength > rightLength -> y.[0]
        | None when leftLength < rightLength -> y.[1]
        | Some x -> y.[x]
        | _ ->"STALEMATE"
    |>printf "%s"
    0

```
> 0 votes

# Answer
# PHP, 339 (not to spec), 410 382 359 339 337 Bytes

```
$b=$w=fgetcsv(STDIN);function a($c){for(;a&$g=$c[$p++];)$f+=ord($g)-64;$f=trim($f);for(;$f[1]&a;$f=$h)for($h=0;a&$r=$f[$q++];$h=bcadd($h,$r));return$f;}function d($f){return strtr($f,[max(str_split($f))=>'']);}for(;$c==$d;$b=[$e,$f]){$x=$z++?d:trim;$e=$x($b[0]);$f=$x($b[1]);$c=a($e);$d=a($f);$e||die(STALEMATE);$c!=$d&&die($w[$c<=$d]);}

```

**EDIT 1**: +71 bytes. Using `STDIN` instead of `fopen('php://stdin','r');` and short tags. Also, full conformance to the spec.

**EDIT 2**: -28 bytes. Using `fgetcsv(STDIN)` instead of `explode(',',trim(fgets(STDIN)))`, and used `for` loop instead of `while` loop.

**EDIT 3**: -23 bytes. Merged functions `a` and `b`, merged for loops.

**EDIT 4**: -20 bytes. Turned `c` from a recursive into a loop. Then, removed function `c` and put its code into the global namespace.

**EDIT 5**: -2 bytes. Thanks to @Titus for the `-r` flag.
> 0 votes

# Answer
# PHP, ~~296 281~~ 267 bytes

```
function f(&$s){for(;$c=$s[$i++];$m>$c||$m=$c)$p+=ord($c)&31;for($s=str_replace($m,'',$s);9<$p=array_sum(str_split($p)););return$p;}for(list($a,$b)=$x=fgetcsv(STDIN);$s==$t&&$a&$b;$t=f($b))$s=f($a);echo($s-=$t)||($s=strlen($x[0])-strlen($x[1]))?$x[+($s<0)]:STALEMATE;

```

run with `-n` or try it online (TiO includes breakdown).

Back in Feb 2011, the current PHP version was 5.3.5; so I could not

* use shorthand list assignment (`[$a,$b]=fgetcsv(...)` and such)
* alias `count_chars` inline
* index function results directly
* use negative string indexes instead of `substr`

But neither would have saved a lot; so it doesn´t matter much.

Most costly things were the loops (of course) and rule #4 (~~40~~ 36 bytes).
> 0 votes

---
Tags: code-golf, math, word, word-puzzle
---


title: Let's golf a BIBABOBU decoder

text:
# Question
Title: Let's golf a BIBABOBU decoder
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!

```

# Answer
> 15 votes
# 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

```

# Answer
> 14 votes
# 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.

```

# Answer
> 13 votes
# 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!

# Answer
> 8 votes
# 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!

# Answer
> 6 votes
# 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!"

```

# Answer
> 6 votes
# 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!

# Answer
> 6 votes
# 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!

# Answer
> 5 votes
# 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

```

# Answer
> 5 votes
# , ~~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.

# Answer
> 5 votes
# 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!)

# Answer
> 4 votes
# 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.

# Answer
> 4 votes
# 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!

# Answer
> 4 votes
# 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!

# Answer
> 3 votes
# 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!

# Answer
> 3 votes
# 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!

# Answer
> 3 votes
# Ruby, ~~86~~ 75 bytes

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

```

Try it online!

# Answer
> 3 votes
# 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'⍷⍵)⊂⍵}

```

# Answer
> 2 votes
# 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.

# Answer
> 2 votes
# 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"

```

# Answer
> 2 votes
# 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.
<>

```

# Answer
> 2 votes
# 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

# Answer
> 2 votes
**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

# Answer
> 1 votes
# 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!

# Answer
> 1 votes
# 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.

```

# Answer
> 1 votes
# Charcoal, 36 bytes

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

```

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

```
ＦＳ≡ι

```

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.

# Answer
> 1 votes
# 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:

# Answer
> 1 votes
# 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).

# Answer
> 0 votes
# 05AB1E, 40 bytes

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

```

Try it online!

# Answer
> 0 votes
# 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.

# Answer
> 0 votes
# 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.

---
Tags: code-golf, string, hexadecimal
---


# Question
Title: Magic: The Gathering Combat with Abilities
Related

# Goal:

Given two creatures with optional combat abilities, return unique but consistent values that represent which creatures died, if any.

# Input:

```
#Longest form:
[[P,T, "<abilities>"], [P,T, "<abilities>"]]
#Shortest form:
[[P,T], [P,T]]

```

Each creature will be given in the form of `[P,T,"<abilities>"]`. It will be in the form `[P,T]`, `[P,T,""]`, or `[P,T,0]` if it has no abilities, your choice on form. P is an integer \>=0, T is an integer \>=1. `<abilities>` is a subset of `"DFI"`, or can be represented via a single number/bitstring if you wish. Order of the flags is also up to you.

# Combat Mechanics:

Each creature has two stats, Power and Toughness in that order, and optional abilities. A creature's power is \>=0. A creature's Toughness is \>=1.

Each creature will simultaneously do damage equal to its power to the opposing creature (unless one has first-strike). If the value is greater than or equal to the opponent's toughness, it will die (unless it is indestructible).

Example: Alice is a `2/2`, Bob is a `3/4`, both with no abilities. Alice will do 2 damage to Bob and take 3 damage in return. Alice's toughness is 2 so it will die, Bob's toughness is 4 so it will live.

There are only 3 optional abilities we will consider for this (although there are more in the game). These will be one character flags:

* \[D\]eathtouch: Any amount of damage (X\>0) is considered lethal.
* \[F\]irst Strike: Will deal its damage first, able to kill the other creature before it can attack back. If both creatures have First Strike, Resolve combat as normal.
* \[I\]ndestructible: No amount of damage is considered lethal, including Deathtouch.

# Output:

Any consistent value for each of the following four cases. State the four values in your answer, please. Example return value in parens:

* Neither creature died (0)
* 1st creature died (1)
* 2nd creature died (2)
* Both creatures died (3)

# Rules:

* Input is guaranteed to have two correctly formatted creatures.
* If you are using characters for abilities, you can assume they're ordered how you want but post the order used if relevant.
* If you are using a number/bitstring for abilities, post what encoding you're using. e.g.: `111` is `D/F/I`, `7` is `D/F/I`, etc.
* If a creature has no abilities, It can also be taken as `[P,T, ""]` or number equivalent
* Standard Loopholes Forbidden
* This is so shortest code wins.

# Examples:

```
Input: [[2,2], [1,1]]
Output: 2nd Dies

Input: [[0,2], [0,1]] #0/2 vs 0/1
Output: Neither Die

Input: [[2,1], [2,1]] #2/1 vs 2/1
Output: Both Die

Input: [[1,1, "D"], [2,2]] #1/1 Deathtoucher vs 2/2
Output: Both Die

Input: [[2,2], [0,1, "D"]] #2/2 vs 0/1 Deathtoucher
Output: 2nd Dies

Input: [[2,2], [1,1, "DF"]] #2/2 vs 1/1 Deathtouch First-striker
Output: 1st Dies

Input: [[0,2, "D"], [0,1, "DF"]] #0/2 Deathtoucher vs 0/1 Deathtouch First-striker
Output: Neither Die

Input: [[2,2], [2,2, "F"]] #2/2 vs 2/2 First-striker
Output: 1st Dies

Input: [[2,2, "I"], [1,1, "DF"]] #2/2 Indestructible vs 1/1 Deathtouch First-striker
Output: 2nd Dies

Input: [[9999,9999], [1,1, "I"]] #9999/9999 vs 1/1 Indestructible
Output: Neither Die

Input: [[2,2, "F"], [1,1, "F"]] #2/2 First-Striker vs 1/1 First-Striker
Output: 2nd Dies

#9/9 Deathtouch, Indestructible First-Striker vs 9/9 Deathtouch, Indestructible First-Striker
Input: [[9,9, "DFI"], [9,9, "DFI"]]
Output: Neither Die

```

# Answer
# Perl 5, 248 bytes

...without spaces and newlines:

```
sub c{eval'
(P,T,A,p,t,a)=@_;
     A=~/F/&&a!~/F/&&a!~/I/ ? c( P,2e9,A=~s/F//r,p,t, a         )
    :a=~/F/&&A!~/F/&&A!~/I/ ? c( P,T, A,        p,2e9,a=~s/F//r )
    : do{
        P=1e9 ifA=~/D/&&P>0;
        p=1e9 ifa=~/D/&&p>0;
        T=3e9 ifA=~/I/;
        t=3e9 ifa=~/I/;
        T-=p;
        t-=P;
        T>0&&t>0  ? 0
            : T>0 ? 2
            : t>0 ? 1
            :       3
}'=~s,[pta],\$$&,gri }

```

Try it online!

My ungolfed version with the ten tests from @Veskah (OP), tests passes:

```
sub co { #combat
    my($p1,$t1,$a1, $p2,$t2,$a2)=@_; #p=power, t=toughness, a=abilities
    $a1=~s/F// and $a2=~s/F// if "$a1$a2"=~/F.*F/; #both F, no F
    return co($p1,2e9,$a1=~s/F//r, $p2,$t2,$a2        ) if $a1=~/F/ && $a2!~/I/;
    return co($p1,$t1,$a1,         $p2,2e9,$a2=~s/F//r) if $a2=~/F/ && $a1!~/I/;
    $p1=1e9 if $a1=~/D/ and $p1>0;
    $p2=1e9 if $a2=~/D/ and $p2>0;
    $t1=3e9 if $a1=~/I/;
    $t2=3e9 if $a2=~/I/;
    $t1-=$p2;
    $t2-=$p1;
    $t1<=0 && $t2<=0 ? "Both Die"
   :$t1<=0           ? "1st Dies"
   :$t2<=0           ? "2nd Dies"
                     : "Neither Die"
}

my @test=map{[/Input: .*? (\d+),(\d+)(?:,\s*"([FDI]+)")?
                      .*? (\d+),(\d+)(?:,\s*"([FDI]+)")?
           .*? Output: \s* (1st.Dies|2nd.Dies|Both.Die|Neither.Die)? /xsi]}
         split/\n\n/,join"",<DATA>;
my $t=0;
for(@test){ $t++;
  my $r=co(@$_);#result
  $r=~s,0,Neither Die,; $r=~s,3,Both Die,;
  print $$_[-1]=~/^$r/
    ? "Ok $t\n"
    : "Not ok, combat $t --> $r, wrong! (".join(",",@$_).")\n"
}
__DATA__
Input: [[2,2], [1,1]]
Output: 2nd Dies

Input: [[0,2], [0,1]] #0/2 vs 0/1
Output: Neither Die

Input: [[2,1], [2,1]] #2/1 vs 2/1
Output: Both Die

Input: [[1,1, "D"], [2,2]] #1/1 Deathtoucher vs 2/2
Output: Both Die

Input: [[2,2], [0,1, "D"]] #2/2 vs 0/1 Deathtoucher
Output: 2nd Dies

Input: [[2,2], [1,1, "DF"]] #2/2 vs 1/1 First-strike, Deathtoucher
Output: 1st Dies

Input: [[2,2], [2,2, "F"]] #2/2 vs 2/2 First-striker
Output: 1st Dies

Input: [[2,2, "I"], [1,1, "DF"]] #2/2 Indestructible vs 1/1 First-strike, Deatht.
Output: 2nd Dies

Input: [[99999,99999], [1,1, "I"]] #99999/99999 vs 1/1 Indestructible
Output: Neither Die

Input: [[2,2, "F"], [1,1, "F"]] #2/2 First-Striker vs 1/1 First-Striker
Output: 2nd Dies

```
> 6 votes

# Answer
# JavaScript, ~~137~~ ~~125~~ ~~120~~ 111 bytes

```
i=>(k=(a,b)=>!(b[2]%2)&&a[0]/(a[2]<=3)>=b[1],[c,d]=i,g=c[2]&2,h=k(c,d),j=k(d,c),d[2]&2-g&&(g?h&&2:j&&1)||j+2*h)

```

I am using bitmap numbers for abilities D=4 F=2 I=1 do `"DFI"` would be `7`. My output is Neither Died `0`, 1st Died `1`, 2nd Died `2`, Both died `3`.

Tests with:

```
f([[2, 2, 0], [1,1, 0]]); // 2
f([[0, 2, 0], [0,1, 0]]); // 0
f([[2, 1, 0], [2,1, 0]]); // 3
f([[1, 1, 4], [2,2, 0]]); // 3
f([[2, 2, 0], [0,1, 4]]); // 2
f([[2, 2, 0], [1,1, 6]]); // 1
f([[2, 2, 0], [2,2, 2]]); // 1
f([[2, 2, 1], [1,1, 6]]); // 2
f([[99999, 99999, 0], [1,1, 1]]); // 0
f([[2, 2, 2], [1,1, 2]]); // 2)

```

This was my my first working code

```
const kills = (c1, c2) => { // Return true if c1 kills c2
    if (c2[2] % 2) {
        console.log("Indestructible");
        return false;
    }
    const c1p = c1[0] / (c1[2] <= 3); // Infinity if Deathtoucher && P > 0
    const c2t = c2[1];
    return c1p >= c2t;
}
const f = (input) => {
    console.log("Match:", input);
    const [c1, c2] = input;
    const f1 = (c1[2] & 2);
    const f2 = (c2[2] & 2);
    if (f2 !== f1) {
        if (f1) {
            if (kills(c1, c2)) {
                console.log("c1 killed c2 in first round");
                return 2;
            }
        } else {
            if (kills(c2, c1)) {
                console.log("c2 killed c1 in first round");
                return 1;
            }
        }
    }
    return kills(c2, c1) + 2 * kills(c1, c2);
};

```

Which I reduced to this intermediate:

```
const f = i => {
    const k = (a, b) => !(b[2] % 2) && a[0] / (a[2] <= 3) >= b[1];
    const [c, d] = i;
    const g = c[2] & 2;
    const h = k(c, d);
    const j = k(d, c);
    return d[2] & 2 - g &&
        (g  ? h && 2
            : j && 1
        ) || j + 2 * h
}

```
> 4 votes

# Answer
# JavaScript (ES6), ~~83~~ 76 bytes

Takes input as 6 distinct arguments: 2 x (Power, Toughness, Abilities). Abilities are expected as bitmasks with:

* \\$1\\$ = Death Touch
* \\$2\\$ = First Strike
* \\$4\\$ = Indestructible

Returns \\$0\\$ for *Neither Die*, \\$1\\$ for *1st Dies*, \\$2\\$ for *2nd Dies* or \\$3\\$ for *Both Die*.

```
(p,t,a,P,T,A)=>(x=A<4&&p>=T|a&!!p)&(y=a<4&&P>=t|A&!!P)&&(a^A)&2?a+2>>1:x*2+y

```

Try it online!

### Commented

```
(p, t, a, P, T, A) => // (p, t, a) = arguments for the first player (P1)
                      // (P, T, A) = arguments for the second player (P2)
  ( x =               // x is a flag which means 'P1 can kill P2',
                      // regardless of the 'First Strike' abilities
    A < 4 &&          // it is set to 1 if P2 is not Indestructible and:
    p >= T |          //   the power of P1 is greater than or equal to the toughness of P2
    a & !!p           //   or the power of P1 is not zero and P1 has the Death Touch
  ) &                 //
  ( y = a < 4 &&      // y is the counterpart of x and is computed the same way
    P >= t |          //
    A & !!P           //
  ) &&                // if both x and y are set
  (a ^ A) & 2 ?       // and exactly one player has the First Strike:
    a + 2 >> 1        //   return 2 if P1 has the First Strike, or 1 otherwise
  :                   // else:
    x * 2 + y         //   return the default outcome: x * 2 + y

```
> 3 votes

# Answer
# C (gcc), ~~114~~ ~~113~~ 95 bytes

A lot of golfing thanks to ceilingcat and Logern.

```
g(Z{return F&1|F&4&&!(f&4||P<t)||!(f&2)&T>p;}
f(Z{return g(Z+2*g(p,t,f,P,T,F);}

```

Compile with `-DZ=P,T,F,p,t,f)`.

Try it online!

We check (independently, because of the symmetry of combat mechanics) whether each of creatures survives the combat, which happens if either is true:

* the creature is indestructible;
* the creature has first strike AND the other one does not AND its power is greater or equal to other's toughnes (therefore we may disregard other's death touch);
* other creature does not have death touch AND its power is less than our toughness.

(The former conditions are more important).

The inputs are power and toughness as integers, and abilities as a bitfield (1 = Indestructible, 2 = Death touch, 4 = First strike), the output is also a bitfield (1 = First creature survives, 2 = Second creature survives).
> 3 votes

# Answer
# Retina 0.8.2, 123 bytes

```
\d+
$*
(.*1)(.*;)(.*1)
$3$2$1
F(.*)F
$1
1+D
1
1*(,1+)I
$1
(1+)(F?;1*,)(1+)
$3$2$1
(1*)1*,\1(1+)?
$#2
0(F)?;0(F)?
$#1;$#2
F

```

Try it online! Link includes test cases, although I've substituted `9` for `99999` for speed. Input uses the letters `DFI` although `D` must precede `I`. Output is in the format `1` for survives and `0` for dies. Explanation:

```
\d+
$*

```

Convert the stats to unary.

```
(.*1)(.*;)(.*1)
$3$2$1

```

Exchange the stats temporarily.

```
F(.*)F
$1

```

Two `F`s cancel out.

```
1+D
1

```

Death Touch lowers the opponent's Toughness to 1.

```
1*(,1+)I
$1

```

Indestructable lowers the opponent's Power to 0.

```
(1+)(;1*,)(1+)
$3$2$1

```

Switch the Toughness back, so now you have P2,T1,F1;P1,T2,F2

```
(1*)1*,\1(1+)?
$#2

```

If the Toughness is higher than the opponent's Power then it survives.

```
0(F)?;0(F)?
$#1;$#2

```

If both would die, the one with First Strike survives.

```
F

```

Otherwise First Strike makes no difference.
> 2 votes

# Answer
## C++, 177 131 127 121 bytes

Here's my not so short solution in C++. Abilities are 3 bits for each creature:

1. D = 0x1 (0001)
2. F = 0x2 (0010)
3. I = 0x4 (0100)

And it simply returns ***0***: if nobody dies, ***1***: if the first creatures dies, ***2***: if the second creature dies and ***3***: if both creatures die.

```
[](int p,int t,int a,int r,int k,int b){return(a&2&&b^4)^(b&2&&a^4)?1+(a&2):((t<r||b&1&&r)&&a^4)+((k<p||a&1&&p)&&b^4)*2;}

```

Try it Online!

## C++, 85 81 bytes (Alternative)

By slightly cheating and capture the variables in lambda and not pass them as arguments it is possible to get down to 81 bytes. I don't know if that's an acceptable solution so I post it as an alternative.

```
[&]{s=(a&2&&b^4)^(b&2&&a^4)?1+(a&2):((t<r||b&1&&r)&&a^4)+((k<p||a&1&&p)&&b^4)*2;}

```

Try it Online!
> 1 votes

# Answer
# Perl 5, 245 bytes

```
$F[0]*=$F[4]if$F[2]=~/D/;$F[3]*=$F[1]if$F[5]=~/D/;$F[3]=0 if$F[2]=~/I/;$F[0]=0 if$F[5]=~/I/;$F[4]-=$F[0]if$F[2]=~/F/;$F[1]-=$F[3]if$F[5]=~/F/;if($F[1]>0&&$F[4]>0){$F[4]-=$F[0]if$F[2]!~/F/;$F[1]-=$F[3]if$F[5]!~/F/}$_=(0+($F[1]<=0)).(0+($F[4]<=0))

```

Run with `-lapE`

Ungolfed:

```
# Takes input in one lines, of the form:
# PPP TTT "<abilities>" PPP TTT "<abilities>"

$F[0] *= $F[4] if $F[2] =~ /D/;
$F[3] *= $F[1] if $F[5] =~ /D/;

$F[3] = 0 if $F[2] =~ /I/;
$F[0] = 0 if $F[5] =~ /I/;

$F[4] -= $F[0] if $F[2] =~ /F/;
$F[1] -= $F[3] if $F[5] =~ /F/;

if ($F[1] > 0 && $F[4] > 0) {
    $F[4] -= $F[0] if $F[2] !~ /F/;
    $F[1] -= $F[3] if $F[5] !~ /F/;
}

$_ = (0+ ($F[1] <= 0)) . (0+ ($F[4] <= 0));

```

"Deathtouch" translates to "your power is now multiplied by your enemy's toughness", and "indestructible" translates to "your enemy's power is now zero", with the latter taking precedent. The code runs two rounds, one where only the first-strikers get to attack, and the other where only non-first-strikers can attack. If the first round results in a death, the second round doesn't happen. Since we already dealt with the deathtouch and indestructible at the beginning, "death" is as simple as checking whether toughness is greater than zero or not.
> 1 votes

---
Tags: code-golf, decision-problem, game
---


title: Extract and Divide

text:
# Question
Title: Extract and Divide
## Challenge

For a given positive integer \\$n\\$:

1. Repeat the following until \\$n \< 10\\$ (until \\$n\\$ contains one digit).
2. Extract the last digit.
3. If the extracted digit is even (including 0) multiply the rest of the integer by \\$2\\$ and add \\$1\\$ ( \\$2n+1\\$ ). Then go back to `step 1` else move to `step 4`.
4. Divide the rest of the integer with the extracted digit (integer / digit) and add the remainder (integer % digit), that is your new \\$n\\$.

**Note**: In case `n < 10` at the very beginning obviously you don't move to step 2. Skip everything and print \\$\[n, 0\]\\$.

---

## Input

**n**: Positive integer.

---

## Output

**\[o, r\]**: `o`: the last `n`, `r`: number of repeats.

---

## Step-by-step example

For input `n = 61407`:

```
Repeat 1: 6140_7 -> 6140 / 7 = 877, 6140 % 7 = 1 => 877  + 1 = 878
Repeat 2: 87_8   -> 2 * 87 + 1 = 175 (even digit)
Repeat 3: 17_5   -> 17   / 5 = 3,   17   % 5 = 2 => 3    + 2 = 5 ( < 10, we are done )

```

The output is `[5, 3]` (last `n` is 5 and 3 steps repeats).

---

## Rules

There are really no rules or restrictions just assume `n > 0`. You can either print or return the output.

# Answer
# , 93 bytes

```
function(n,r=0,e=n%%10,d=(n-e)/10)"if"(n<10,c(n,r),"if"(e%%2,f(d%/%e+d%%e,r+1),f(d*2+1,r+1)))

```

Try it online!
> 6 votes

# Answer
# Python 2, ~~78 77 76~~ 73 bytes

Recursive version. Saved 3 bytes thanks to Jonathan Frech.

```
f=lambda n,r=0:n>9and f(n%2*sum(divmod(n/10,n%10))or n/10*2+1,-~r)or[n,r]

```

Try it online!

# 74 bytes

Full program.

```
n,i=input(),0
while n>9:i+=1;r,R=n/10,n%10;n=[r-~r,r/R+r%R][R&1]
print n,i

```

Try it online!
> 4 votes

# Answer
# JavaScript (ES6), ~~62~~ 59 bytes

```
f=(n,r=0)=>(x=n/10|0)?f((n%=10)&1?x/n+x%n|0:x-~x,r+1):[n,r]

```

Try it online!

### Commented

```
f = (n, r = 0) =>         // n = input, r = number of iterations
  (x = n / 10 | 0) ?      // x = floor(n / 10); if x is not equal to 0:
    f(                    //   do a recursive call:
      (n %= 10) & 1 ?     //     n = last digit; if odd:
        x / n + x % n | 0 //       use quotient + remainder of x / n
      :                   //     else:
        x - ~x,           //       use x - (-x - 1) = x + x + 1 = 2x + 1
      r + 1               //     increment the number of iterations
    )                     //   end of recursive call
  :                       // else:
    [n, r]                //   return [ final_result, iterations ]

```
> 3 votes

# Answer
# 05AB1E (legacy), 19 bytes

```
[DgD–#ÁćDÈi\·>ë‰O]?

```

Explanation:

```
[                     Start infinite loop
 DgD                  Get the length
    –#                If it's 1, print the loop index and break.
      ÁćD             Extract: "hello" -> "hell", "o"
         Èi           if even,
           \·>        Double and increment
              ë       else,
               ‰O     Divmod, and sum the result (div and mod).
                 ]    End if statement & infinite loop
                  ?   Print

```

Try it online!
> 3 votes

# Answer
# Julia 1.0, ~~81~~ ~~80~~ 79 bytes

```
function d(n,c=0)l,r=n÷10,n%10;n>9 ? d(r%2<1 ? 2l+1 : l÷r+l%r,c+1) : [n,c]end

```

Try it online!

* -1 (thanks Mr. Xcoder)
> 3 votes

# Answer
# Ruby, 61 bytes

```
f=->n,r=0{n>9?(a=n%10;n/=10;f[a%2<1?n-~n:n/a+n%a,r+1]):[n,r]}

```

Try it online!
> 2 votes

# Answer
# Retina, 79 bytes

```
(\d+)[02468]$
;$.(_2*$1*
(\d+)(.)
$2*_;$1*
}`(_+);(\1)*(_*)
;$.($3$#2*
^;*
$.&;

```

Try it online! Explanation:

```
(\d+)[02468]$
;$.(_2*$1*

```

If the last digit is even, multiply the rest of the integer by 2 and add 1. This always results in an odd number, so we don't need to repeat this.

```
(\d+)(.)
$2*_;$1*

```

Split off the last digit and convert to unary for the divmod.

```
}`(_+);(\1)*(_*)
;$.($3$#2*

```

Divide the rest of the integer by the last digit and add the remainder. Then repeat the whole program until there's only one digit left.

```
^;*
$.&;

```

Count the number of operations performed.
> 2 votes

# Answer
# Perl 6, 61 bytes

```
{tail kv $_,{$1%2??$0/$1+$0%$1+|0!!$0*2+1}...{!/(.+)(.)/}: 2}

```

Try it online!

Returns (r, o).
> 2 votes

# Answer
# Swift 4, ~~112~~ ~~104~~ ~~100~~ 93 bytes

```
var n=Int(readLine()!)!,r=0,p=n%10;while n>9{n=[n/10*2+1,n/10/p+n/10%p][n%2];r+=1};print(n,r)

```

Try it online!

Prints `n r`

* -7 (Thanks to Mr. Xcoder)
> 2 votes

# Answer
# Brachylog, 43 bytes

Feels messy and bad but here it is anyway

```
;0{hl1&|⟨{h⟨k{t%₂0&h×₂+₁|⟨÷+%⟩}t⟩}↰₁{t+₁}⟩}

```

Try it online!
> 2 votes

# Answer
**VBA (Excel), ~~145?, 142, 139,~~ 123 bytes**

Condensed Form:

```
Sub t(n)
While n>10
e=Right(n, 1)
n=Left(n,Len(n)-1)
If e Mod 2=0Then n=n*2+1 Else n=Int(n/e)+n Mod e
c=c+1
wend
Debug.?n;c
End Sub

```

Expanded (with comments)

```
Sub test(n) 'For a given positive integer n
    'Repeat the following until n<10
    While n > 10
        'Extract the last digit
        e = Right(n, 1)
        'Remove the last digit
        n = Left(n, Len(n) - 1)
        'If the extracted digit is even...
        If e Mod 2 = 0 Then
            'Multiply the rest of the integer by 2 and add 1
            n = n * 2 + 1
        Else
            'Divide the rest of the integer with the extracted digit and add the remainder
            n = Int(n / e) + n Mod e
        End If
        'Keep count
        c = c + 1
    'End the Loop
    Wend
    'Give the output
    Debug.Print (n ; c)
End Sub

```

(Do excuse me, as this is my first post. I will happily edit! Right now, it looks like to test it you open the Immediate Window and type 't n' where n is your number to test :D)
> 2 votes

# Answer
# 8086 machine code, 35 bytes

```
00000000  31 c9 31 d2 bb 0a 00 f7  f3 85 c0 74 14 f6 c2 01  |1.1........t....|
00000010  75 05 d1 e0 40 e2 eb 89  d3 88 f2 f7 f3 01 d0 e2  |u...@...........|
00000020  e1 f7 d9                                          |...|
00000023

```

Input: `AX = n`
Output: `DX = o`, `CX = r`

Assembled from:

```
        xor cx, cx
next:   xor dx, dx
        mov bx, 10
        div bx
        test ax, ax
        jz done
        test dl, 1
        jnz odd
        shl ax, 1
        inc ax
        loop next
odd:    mov bx, dx
        mov dl, dh
        div bx
        add ax, dx
        loop next
done:   neg cx

```
> 1 votes

# Answer
# Jelly, 19 bytes

```
dd/Sɗ:Ḥ‘ɗḂ?Ƭ⁵ṖṖṪ,LƊ

```

Try it online!
> 1 votes

# Answer
# Common Lisp, 145 bytes

A function which takes the `n` provided and returns the list `(n r)`. Lisp syntax is fun.

```
(defun f(n &optional(r 0))(if(< n 10)`(,n,r)(let((h(floor n 10))(l(mod n 10)))(if(evenp l)(f(1+(* 2 h))(1+ r))(f(+(mod h l)(floor h l))(1+ r)))))

```
> 1 votes

# Answer
## Haskell, 78 bytes

```
f n|n<10=(n,0)|(d,m)<-divMod n 10=(1+)<$>f(last$2*d+1:[div d m+mod d m|odd n])

```

Try it online!
> 1 votes

# Answer
# Red, 131 bytes

```
func[n][s: 0 while[n > 9][r: do form take/last t: form n t: do t
n: either r % 2 = 1[t / r +(t % r)][2 * t + 1]s: s + 1]print[n s]]

```

Try it online!

## More readable:

```
f: func [ n ] [
    s: 0
    while [ n > 9 ] [
        r: do form take/last t: form n
        t: do t
        n: either r % 2 = 1
            [ t / r + (t % r) ]
            [ 2 * t + 1 ]
        s: s + 1
    ]
    print [ n s ]
]

```
> 1 votes

---
Tags: code-golf, number, arithmetic, division
---


title: Hey, what time is it?

text:
# Question
Title: Hey, what time is it?
## Challenge

Given a `number width`, `number height`, `hours` and `minutes` print the time using the following format style:

```
------  -  ------  ------  -    -  ------  ------  ------  ------  ------
|    |  |       |       |  |    |  |       |            |  |    |  |    |
|    |  |  ------  ------  ------  ------  ------       |  ------  ------
|    |  |  |            |       |       |  |    |       |  |    |       |
|    |  |  |            |       |       |  |    |       |  |    |       |
------  -  ------  ------       -  ------  ------       -  ------  ------

```

For numbers with a mid line, when the height is odd just place it in the middle (example for `height = 3`):

```
------
|    |
------
|    |
------

```

However, when the height is even you can choose up or down:

```
------  ------
|    |  |    |
|    |  ------
------  |    |
|    |  |    |
------  ------

```

Of course, you need to specify this and use it every time.

---

## Input

* **W**: The width of each number
* **H**: The height of each number
* **HRS**: Time hours
* **MINS**: Time minutes

---

## Output

You can either print the time, return a string (including the newlines) or return a list of strings (one string per line).

---

## Rules

1. Assume number width `> 2`
2. Assume number height `> 2`
3. The space between numbers is fixed to `2`
4. The space between hours and minutes is fixed to `4`
5. If hours or minutes are `< 10` (single digit), make sure to add a `0` (see example)
6. Assume that input hours and minutes will always be valid time
7. Digit `1` is a special case which always has the same width `1` and only it's height changes.
8. Height is considered the inner height, excluding the upper and lower rows of `---` (see example)

---

## Example

Here's an example for `W=6`, `H=4`, `hrs=2`, `mins=18`:

```
------  ------    -  ------
|    |       |    |  |    |
|    |  ------    |  ------
|    |  |         |  |    |
|    |  |         |  |    |
------  ------    -  ------

```

# Answer
# JavaScript (ES8), ~~258~~ ~~245~~ ~~242~~ 239 bytes

```
(w,h,H,M)=>[2,h-1,2,h,2].map((r,y)=>`${(g=x=>((k=[876,,1284,260,8461,276,788,8484,780,268][x%10|0])?(s=x=>' -|'[[21,8,5,10,4,2][k*2>>y*3&7]>>x&3])().padEnd(w-2,s(4))+s(2):'-|||-'[y])+'  ')(H/10)+g(H)}  ${g(M/10)+g(M)}
`.repeat(r/2)).join``

```

Try it online!

### Character encoding

Digits are made of 3 distinct characters:

* 0: space
* 1: `-`
* 2: `|`

### Pattern encoding

Each digit is made of 5 patterns:

```
0:  -----  <-- top pattern
1:  |   |  <-- upper side repeated pattern
2:  -----  <-- middle pattern
3:      |  <-- lower side repeated pattern
4:  -----  <-- bottom pattern

```

Each pattern is made of a leading character \\$L\\$, followed by a repeated middle character \\$R\\$, followed by a trailing character \\$T\\$.

All digits can be built by using only 6 distinct patterns, which are encoded as:

$$L+R\times16+T\times4$$

```
 ID | Leading | Repeated | Trailing | Codes | Encoded as
----+---------+----------+----------+-------+------------
  0 |   "-"   |   "-"    |   "-"    | 1,1,1 |    21
  1 |   " "   |   " "    |   "|"    | 0,0,2 |     8
  2 |   "-"   |   " "    |   "-"    | 1,0,1 |     5
  3 |   "|"   |   " "    |   "|"    | 2,0,2 |    10
  4 |   " "   |   " "    |   "-"    | 0,0,1 |     4
  5 |   "|"   |   " "    |   " "    | 2,0,0 |     2

```

### Digit encoding

Because of its non-standard width, \\$1\\$ is a special case and is processed separately.

All other digits are encoded as:

$$\frac{1}{2}\sum\limits\_{n=0}^{4}2^{3n}P\_n$$

where \\$P\_n\\$ is the \\$n\\$-th pattern for this digit (0-indexed, from top to bottom).

```
 Digit | Patterns  | Encoded as
-------+-----------+------------
   0   | 0,3,3,3,0 |     876
   1   |    n/a    |     n/a
   2   | 0,1,0,5,0 |    1284
   3   | 0,1,0,1,0 |     260
   4   | 2,3,0,1,4 |    8461
   5   | 0,5,0,1,0 |     276
   6   | 0,5,0,3,0 |     788
   7   | 0,1,1,1,4 |    8484
   8   | 0,3,0,3,0 |     780
   9   | 0,3,0,1,0 |     268

```
> 4 votes

# Answer
# Python 2, ~~296~~ ~~270~~ ~~256~~ ~~249~~ ~~244~~ 241 bytes

```
w,h,H,M=input()
a,d,e='| -'
b,c=d*(w-2),e*w
f,g=e+b+e,d+b+e
l,r,m=a+b+d,d+b+a,a+b+a
E=eval
for L in['ceccfccccc']+~-h/2*['marrmllrmm']+['macccccrcc']+h/2*['malrrrmrmr']+['ceccgccgcc']:print E(L[H/10]),d+E(L[H%10]),d+d,E(L[M/10]),d+E(L[M%10])

```

Try it online!
> 3 votes

# Answer
# Canvas, ~~101~~ ~~98~~ 96 bytes

```
┘｛ｌ２∔0×；＋｛ø；┤“\⤢ＹJ>`Ｓ‰/„２┬７ｎ＠｛⁴Ｙ？ｙ５＜？⁸»├⁸⇵|＊-∔ｙ３＜？↕；┐１；｝１ｙ２％‽⁷＋╷｝┘╋］⁷-×１ｙ５－⁸╵×⇵╵╋╋｝｝｝｝  ×＋｝ ４××＋

```

Try it here!

Nothing too fancy - stores the 7 bytes of info of each number and draws according to them.
While making this I fixed 3 bugs in Canvas (though only one resulted in shortening the answer; this is how the result would've looked without that commit)

Explanation:

```
┘{                   for each item of the 3rd input
  l2∔0×;+              prepend 2-length 0s to the item
  {                    for each character
    ø;                   push an empty canvas below the character
    ┤                    cast the character to a digit
    “...„２┬７n            the number 741859858201224148989 base-2 decoded & split into chunks of 7 - the digit data
    @                    pick the item in that list corresponding to the current number
    {                    for each bit there
      ⁴Y                 store the index in the loop in Y
      ?                  if the current bit is set:
        ｙ5<?               if y < 5 (aka one of the vertical parts)
          ⁸»├                push height>>1 + 2 (y position of the part)
          ⁸⇵|*               push a list of ceil(height/2) "|"s
          -∔                 prepend a "-" to that
          y3<?               if y < 3 (aka the top parts)
            ↕                  reverse that list
            ;┐１;               replace the y position with 1
          }
          1                  push 1 (x position of the part)
          y2%‽               if y%2 is 0
            ⁷+╷                add the width to that, then decrement
          }
          ┘╋                 at those coordinates enter that array in the canvas pushed earlier
        ]                  else (aka y >= 5, the horizontal parts)
          ⁷-×                repeat "-" width times
          1                  push 1
          y5-⁸╵×⇵╵           push ceil((y-5) * (height+1) / 2) + 1
          ╋╋                 at (1; above line) in the canvas, place the dashes, without smart overlapping
        }
      }
    }
  }
    ×＋                 join the 2 digits with 2 spaces
}
  4××＋               join the 2 numbers with 4 spaces

```
> 1 votes

# Answer
# Charcoal, 101 bytes

```
ＮθＮη⊞υ¶Ｆ-|Ｆ⟦ι◧ιθ⁺◨ι⊖θι×ιθ⟧⊞υ⁺κ¶ＦＥ⪫Ｅ²◧ＩＮ²:⭆§⪪”)⧴9;ïjÞ⊟Pj%Uδ>LτS·Ｑr^ψＱ”⁵﹪℅ι¹⁶×÷§⟦²⊖η²η⟧μ²§υＩλ«Ｐι§⪪ι¶⁰→→

```

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

```
ＮθＮη

```

Input the height and width.

```
⊞υ¶

```

Push a newline to the predefined empty list.

```
Ｆ-|

```

Loop over the characters `-` and `|`.

```
Ｆ⟦ι◧ιθ⁺◨ι⊖θι×ιθ⟧

```

Loop over the four values given by the character, the character padded to the width, the character on both sides of the width, and the character repeated across the width.

```
⊞υ⁺κ¶

```

Push those values plus a newline to the list. This results in the following elements for a width of 6:

```
-
     -
-    -
------
|
     |
|    |
||||||

```

(Note that the last one is unused, and the first and fifth elements are only one character wide.)

```
ＦＥ⪫Ｅ²◧ＩＮ²:

```

Input two numbers, convert to string, left pad to a width of 2, join them with `:`, then loop over the characters in that string.

```
⭆§⪪”)⧴9;ïjÞ⊟Pj%Uδ>LτS·Ｑr^ψＱ”⁵﹪℅ι¹⁶

```

Split the compressed literal `4777415551464544646437462454644547446662474744746400000` into blocks of 5, then take the block indexed by the code point of the current character modulo 16, thus mapping space to 0 and `:` to 10. Map over those characters.

```
×÷§⟦²⊖η²η⟧μ²§υＩλ

```

Look up the character in the predefined list, then multiply it according to its index; the first, middle and last strings get multiplied by `2/2` while the intermediate strings get multiplied according to the height.

```
«Ｐι§⪪ι¶⁰→→

```

Print the string without moving the cursor, then print the first line of the string again, then move the cursor a further two squares to the right. This means that `1` is special-cased because its first line is only a `-` while `:` is special-cased to have no intrinsic with at all and merely ends up doubling the space between digits.
> 1 votes

---
Tags: code-golf, ascii-art, date
---


title: Repeat a rhyme and loop on the vowels

text:
# Question
Title: Repeat a rhyme and loop on the vowels
# Vowels rhyme: Apples and Bananas

There is a traditional children's song that repeats the same text over and over, only each time every vowel is replaced with a random vowel, but constant across the current stanza.

## Challenge

The objective is to propose the shortest code that performs such a transformation on an input text.

## Rules

1. You must print the rhyme as many times as there are distinct vowels in it.
2. Each print must be separated with a line break (platform-specific combo of `\n` and `\r` is accepted).
3. For iteration `i`, replace each vowel with the `i`th distinct vowel in the original text.
4. The input text is a sequence of printable ASCII characters (range `[32, 126]`.
5. Input will not contain embedded line breaks.
6. Only vowels characters must be affected, other must be output exactly as input.
7. Only vowels characters count: nasal vowels, although sounding like vowels (like in French *"Tintin"*), must not be handled as a single vowel.
8. Case matters for the output, but is positional (replacing an uppercase vowel is done with the uppercase replacement vowel)
9. Uppercase vowels are not distinct from their lowercase counterpart (ie `a` \<=\> `A`)
10. Consecutive vowels are always considered separately (ie. `Boat` yields both `Boot` and `Baat`)
11. Since the letter `y` represents either a vowel or consonant soun (as we're speaking English), handling it as a vowel or a consonant is allowed, however answers must explicitly state whether they handle `y` as a vowel or not.

## Examples:

**Hello world**

```
Hello world!

```

gives:

```
Helle werld!
Hollo world!

```

**Excerpt from the original French text (translated), with `y` handled as a vowel:**

```
An elephant that was rambling all gently in the woods...

```

gives:

```
An alaphant that was ramblang all gantla an tha waads...
En elephent thet wes rembleng ell gentle en the weeds...
In iliphint thit wis rimbling ill gintli in thi wiids...
Yn ylyphynt thyt wys rymblyng yll gyntly yn thy wyyds...
On olophont thot wos romblong oll gontlo on tho woods...

```

Note the behaviour on leading uppercase vowel: case is kept at its index (rules 8 and 9).

**Vowelless example**

Input that does not contain any vowel, like:

```
lgn@hst:~$ rm -rf ./* ~ /

```

must produce no output, or a single line break.

**Single-vowel input**

Input containing a single vowel is output as is.

```
Dad sat at a car and saw a fat bat.

```

gives:

```
Dad sat at a car and saw a fat bat.

```

This is , so fewest bytecount code wins (nothing but eternal PPCG glory)!

# Answer
# Retina, 45 bytes

```
~(K`A\EI\OU
L$`\\?(.)
./$1/i&$*\T`Vv`5*$&$L$&

```

Try it online! Does not count `y` as a vowel. Explanation:

```
K`A\EI\OU

```

Replaces the text with the literal string `A\EI\OU`.

```
L$`\\?(.)

```

Matches each letter optionally preceded by a backslash.

```
./$1/i&$*\T`Vv`5*$&$L$&

```

Outputs a line of Retina code for each letter.

```
~(

```

Evaluates the generated code (shown below) using the original input. The `.` causes the code not to output the (final) buffer. The `/<vowel>/i&` causes the rest of the line to run only if the input contains the given vowel (case-insensitively). The `*` causes the result of the line to be ignored, so that the next vowel can be tested. The `\` causes the result to be printed on its own line before it is ignored. The `T`Vv`AAAAAa` transliterates uppercase `V`owels to `AAAAA`s and all lowercase `v`owels to `a`. `\A` is an escape that refers to ASCII 07 (BEL), but `E`, `O` and `o` are built-in character classes that needs to be escaped to give their literal values (`e` is not a character class, but fortunately it is also not an escape.)

```
./A/i&*\T`Vv`AAAAAa
./E/i&*\T`Vv`\E\E\E\E\E\e
./I/i&*\T`Vv`IIIIIi
./O/i&*\T`Vv`\O\O\O\O\O\o
./U/i&*\T`Vv`UUUUUu

```
> 6 votes

# Answer
# Ruby, 78 bytes

```
->s{s.downcase.scan(/[aeiou]/).uniq.map{|v|s.tr"AEIOUaeiou",v.upcase*5+v}*?\n}

```

Try it online!

A quick and naive approach. Y is not considered a vowel.
> 5 votes

# Answer
# Japt v2.0a0 `-R`, ~~24~~ 22 bytes

Treats `y` as a vowel. Change both occurences of `\y` to `\v` to treat it as a consonant.

```
v f\y â £r\y_Xc^H*ZøZu

```

Try it

---

## Explanation

```
v                          :Lowercase
   \y                      :RegEx /[aeiouy]/gi (\v is /[aeiou]/gi)
  f                        :Get all matches as an array
      â                    :Deduplicate
        £                  :Map each X
         r\y               :  Replace all matches of the RegEx above in the input
             _             :  Pass matches through a function as Z
              Xc^          :    XOR the character code of X with
                 H*        :     32 multiplied by
                   Zø      :     Does Z contain
                     Zu    :      Uppercase Z
                           :Implicitly join with newlines and output

```
> 4 votes

# Answer
## bash, 96 bytes

Two equal-length solutions:

```
v=aeiouAEIOU;for x in `grep -o [$v]<<<$1|sed 's/./\L&&&&&\U&/'|awk !a[\\$0]++`;{ tr $v $x<<<$1;}
v=aeiouAEIOU;for x in `tr -cd $v<<<$1|sed 's/./\L&&&&&\U&\n/g'|awk !a[\\$0]++`;{ tr $v $x<<<$1;}

```

Try it online!

Takes input as a command line argument and outputs to STDOUT.
> 4 votes

# Answer
# 05AB1E (legacy), 19 bytes

(Indirectly) saved one byte thanks to Kevin (printing directly inside the loop rather than joining, only work in the legacy version).

```
lžMÃÙεžMDu«s5×Du«‡=

```

Try it online!

### Using the Elixir rewrite, 20 bytes

```
lžMÃÙεžMDu«s5×Du«‡}»

```

**Try it online!** (without `y`) | **Try it online!** (with `y`, `žM` being replaced by `žO` – same applies for the legacy version)

### How it works

```
lžMÃÙεžMDu«s5×Du«‡}»     Full program. Example: "Hello"
l                        Convert the input to lowercase. "Hello" –> "hello"
 žMÃ                     Keep only lowercase vowels. "hello" –> "eo"
    Ù                    Remove duplicates. "eo" –> "eo"
     ε            }      For each of the characters (example with "e"):
      žMDu«              Yield "aeiouAEIOU"
           s5×           Swap, and repeat the current char 5 times. "e" –> "eeeee"
              Du«        Duplicate, uppercase and merge. "eeeee" –> "eeeeeEEEE"
                 ‡       Transliteration. For each item in B, replace it in A with
                         the corresponding item in C.
                   »     Join on newlines.

```
> 4 votes

# Answer
# Jelly,  ~~23 20 18~~  17 bytes

-2 Thanks to Erik the Outgolfer

```
ØcŒHZx5fƇðØc,yð€Y

```

To treat `y` as a vowel replace both `c`s with `y`s.

**Try it online!**

### How?

```
ØcŒHZx5fƇðØc,yð€Y - Link: list of characters, S
Øc                - vowels -> "AEIOUaeiou"
  ŒH              - split in half -> ["AEIOU", "aeiou"]
    Z             - transpose -> ["Aa", "Ee", "Ii", "Oo", "Uu"]
     x5           - times 5 -> ["AAAAAaaaaa", "EEEEEeeeee", "IIIIIiiiii", "OOOOOooooo", "UUUUUuuuuu"]
        Ƈ         - filter keep if:
       f          -   filter keep only -> those of X which have required vowels
                  -                       ...i.e. if S = "blah" then ["AAAAAaaaaa"]
         ð    ð€  - dyadic chain for €ach:
          Øc      -   vowels -> "AEIOUaeiou"
            ,     -   pair       e.g. ["AEIOUaeiou","AAAAAaaaaa"]
             y    -   translate  e.g. swap A for A, E for A, ...
                Y - join with newlines

```
> 3 votes

# Answer
# Red, 229 bytes

Taking `y` for a non-vowel

```
func[s][v: charset"aoeiu"w: charset"AOEIU"p: copy""parse s[any[[copy c[v | w](if not find p c[append p c lowercase c
parse s[any[[copy n to[v | w | end]](prin n)opt[v(prin c)|[w(prin uppercase copy c)]| skip]]]print""])]| skip]]]

```

Try it online!

Slightly more readable:

```
f: func [ s ] [
    v: charset "aoeiu"
    w: charset "AOEIU"
    p: copy ""
    parse s[
        any [
            [ copy c [ v | w ]
                ( if not find p c [
                    append p c
                    lowercase c
                    parse s [
                        any [
                            [ copy n to [ v | w | end ] ]
                                 ( prin n )
                            opt [ v ( prin c )
                                | [ w ( prin uppercase copy c ) ]
                                | skip
                                ]
                            ]
                        ]
                    print ""
                ] )
            ]
            | skip
        ]
    ]
]

```
> 3 votes

# Answer
# , ~~138~~, 129 bytes

```
function(x,U=utf8ToInt,a=U(V<-'aeiouAEIOU'))for(i in (which(a%in%U(x))-1)%%5)cat(chartr(V,intToUtf8(rep(a[i+c(1,6)],e=5)),x),'
')

```

Try it online!

* `y` is not considered a vowel
> 3 votes

# Answer
## Python, 129 119 112 bytes

```
import re
f=lambda s:'\n'.join(r('[AEIOU]',v.upper(),r('[aeiou]',v,s))for v in'aeiou'if v in s.lower());r=re.sub

```

Try it Online!

Doesn't treat \\$y\\$ as vowel.

-7 bytes thanks to @Mr.Xcoder
> 2 votes

# Answer
# JavaScript (Node.js), 99 bytes

Treats \\$y\\$ as a consonant.

```
s=>(g=F=>Buffer(s).map(c=>2130466>>c&c>64?F(c):c)+`
`)(v=>g[v&=31]||(g[v]=S+=g(c=>c&96|v)),S='')&&S

```

Try it online!

### Commented

```
s => (                   // s = input string
  g = F =>               // g = helper function taking a callback function F
    Buffer(s)            // turn s into a Buffer
    .map(c =>            // for each ASCII code c in s:
      2130466            //   2130466 is a vowel bitmask: 1000001000001000100010
                         //                               u     o     i   e   a
      >> c               //   the ECMAScript specification enforces that the shiftCount is
                         //   the result of masking out all but the least significant 5 bits
      & c > 64           //   also make sure to ignore non-letter characters
      ?                  //   if a vowel is identified:
        F(c)             //     invoke F with c
      :                  //   else:
        c                //     just yield c
    ) + `\n`             // end of map(); coerce back to a string and append a newline
  )(v =>                 // invoke g with a callback that takes v:
    g[v &= 31] || (      //   unless this vowel has already been encountered:
      g[v] =             //     mark it as encountered
      S +=               //     and append to the output string S
      g(                 //     the result of another call to g:
        c => c & 96 | v  //       where vowels are replaced with v, using the original case
      )                  //     end of inner call to g
    ),                   //
    S = ''               //   start with S = ''
  ) && S                 // end of outer call to g; return S

```
> 2 votes

# Answer
# Java 10, ~~196~~ 188 bytes

```
s->{var d=new int[99];for(var c:s.toUpperCase().replaceAll("[^AEIOU]","").toCharArray())if(d[c]++<1)System.out.println(s.replaceAll("[AEIOU]",c+"").replaceAll("[aeiou]",(char)(c+32)+""));}

```

-8 bytes thanks to *@joH1*.

Without `y` as vowel to save bytes.

Try it online.

**Explanation:**

```
s->{                       // Method with String parameter and no return-type
  var d=new int[99];       //  Integer-array indicating which vowels we've already output
  for(var c:s.toUpperCase()//  Convert the input to uppercase
            .replaceAll("[^AEIOU]","")
                           //  Remove all non-vowels
            .toCharArray())//  Convert it to a character array)
                           //  And loop over those vowel-characters
    if(d[c]++              //   Increase the vowel-count by 1
             <1)           //   And if it was 0 this iteration:
      System.out.println(  //    Print with trailing newline:
        s                  //     The input,
         .replaceAll("[AEIOU]",c+"")
                           //     with every uppercase vowel replace with the current vowel
         .replaceAll("[aeiou]",(char)(c+32)+""));}
                           //     and every lowercase vowel replaced as well

```
> 2 votes

# Answer
# Python 2, 112 bytes

```
s=input()
V='aeiouAEIOU'
for v in V:
 if v in s.lower():print''.join([c,[v.upper(),v][c>'Z']][c in V]for c in s)

```

Try it online!

Treats `y` as a consonant.
> 1 votes

# Answer
# Perl 6, 64 bytes

```
{m:g:i/<[aeiou]>/».lc.unique».&{$^v;say S:g:ii[<[aeiou]>]=$v}}

```

Try it online!
> 1 votes

# Answer
# Java (OpenJDK 8), 184 bytes

y is a vowel

```
s->s.chars().mapToObj(c->""+(char)(c>96?c:c+32)).filter("aeiouy"::contains).distinct().forEach(c->System.out.println(s.replaceAll("[aeiouy]",c).replaceAll("[AEIOUY]",c.toUpperCase())))

```

Try it online!
> 1 votes

---
Tags: code-golf, string
---


# Question
Title: A regex to match three consecutive integers iff the third integer is the sum of the first two
Write a regular expression which matches a given string consisting of three non-negative, space-separated integers if and only if the last integer is the sum of the previous two. Answers may be for integers of any numeral system with radix between 2 and 10.

## Test cases

These should fail:

```
0 1 2
10 20 1000

```

These should match:

```
10 20 30
28657 46368 75025
0 0 0

```

## Rules

Your answer should consist of a single regex, without any additional code (except, optionally, a list of regex modifiers required to make your solution work). You must not use features of your language's regex flavour that allow you to invoke code in the hosting language (e.g. Perl's e modifier).

Please specify your regex flavour in your answer.

This is regex golf, so the shortest regex in bytes wins. If your language requires delimiters (usually /.../) to denote regular expressions, don't count the delimiters themselves. If your solution requires modifiers, add one byte per modifier.

Credits to Martin Ender and jaytea for the regex-golfing rules.

---

I have reason to believe it's possible based on the solution of Martin Ender for finding and incrementing integers with regex.

# Answer
## Perl/PCRE: 2,685 bytes

```
^(?!(?!0*+(?=(\d*?)((?:(?=\d+ 0*+(\d*?)(\d(?(4)\4)) 0*(\d*?)(\d\6?+)$)\d)+) )(?=(?(?!\1(?:(?=\d+ 0*\3((\7?+)\d))(?=\d(\d* 0*\3\8))(?=0\9[9]|1\9[8]|2\9[7]|3\9[6]|4\9[5]|5\9[4]|6\9[3]|7\9[2]|8\9[1]|9\9[0])\d)*+(?=\d(\d* 0*\3\8?+))(?=[5-9]\10[5-9]|1\10[9]|2\10[89]|3\10[7-9]|4\10[6-9]|6\10[4]|7\10[34]|8\10[2-4]|9\10[1-4]))(?=\d+ \d+ 0*\1\3\6$)|(?(?!.*+\3)\d+ )(?=\d*(\2|\4)( .*?0*+)\d+$)(?(?=9*\11 )(?:9(?=\d*\12[1](\13?+0)))*?(?=\11 )\11\12[1]\13?+\6$|(?:(\d)(?=\d*\12(\15?+\14)))*(?=\d(\d*\12\15?+))(?=0\16[1]|1\16[2]|2\16[3]|3\16[4]|4\16[5]|5\16[6]|6\16[7]|7\16[8]|8\16[9])\d(?:9(?=\d*\12\15?+\d(\17?+0)))*?\11\12\15?+\d\17?+\6$)))\1(?:(?=(\d)\d* 0*+\3((\19?+)\d)\d* 0*+\5((\21?+)\d))(?=\d(\d* 0*+\3\20)\d(\d* 0*+\5\22))(?(?!\18(?:(?=\d+ 0*+\3\19((\25?+)\d))(?=\d(\d* 0*+\3\19\26))(?=0\27[9]|1\27[8]|2\27[7]|3\27[6]|4\27[5]|5\27[4]|6\27[3]|7\27[2]|8\27[1]|9\27[0])\d)*+(?=\d(\d* 0*+\3\19\26?+))(?=[5-9]\28[5-9]|1\28[9]|2\28[89]|3\28[7-9]|4\28[6-9]|6\28[4]|7\28[34]|8\28[2-4]|9\28[1-4]))(?=1\23(?:1\24[2]|2\24[3]|3\24[4]|4\24[5]|5\24[6]|6\24[7]|7\24[8]|8\24[9]|9\24[0])|2\23(?:1\24[3]|2\24[4]|3\24[5]|4\24[6]|5\24[7]|6\24[8]|7\24[9]|8\24[0]|9\24[1])|3\23(?:1\24[4]|2\24[5]|3\24[6]|4\24[7]|5\24[8]|6\24[9]|7\24[0]|8\24[1]|9\24[2])|4\23(?:1\24[5]|2\24[6]|3\24[7]|4\24[8]|5\24[9]|6\24[0]|7\24[1]|8\24[2]|9\24[3])|5\23(?:1\24[6]|2\24[7]|3\24[8]|4\24[9]|5\24[0]|6\24[1]|7\24[2]|8\24[3]|9\24[4])|6\23(?:1\24[7]|2\24[8]|3\24[9]|4\24[0]|5\24[1]|6\24[2]|7\24[3]|8\24[4]|9\24[5])|7\23(?:1\24[8]|2\24[9]|3\24[0]|4\24[1]|5\24[2]|6\24[3]|7\24[4]|8\24[5]|9\24[6])|8\23(?:1\24[9]|2\24[0]|3\24[1]|4\24[2]|5\24[3]|6\24[4]|7\24[5]|8\24[6]|9\24[7])|9\23(?:1\24[0]|2\24[1]|3\24[2]|4\24[3]|5\24[4]|6\24[5]|7\24[6]|8\24[7]|9\24[8])|0\23(\d)\24\29|(\d)\23[0]\24\30)|(?=1\23(?:0\24[2]|1\24[3]|2\24[4]|3\24[5]|4\24[6]|5\24[7]|6\24[8]|7\24[9]|8\24[0]|9\24[1])|2\23(?:0\24[3]|1\24[4]|2\24[5]|3\24[6]|4\24[7]|5\24[8]|6\24[9]|7\24[0]|8\24[1]|9\24[2])|3\23(?:0\24[4]|1\24[5]|2\24[6]|3\24[7]|4\24[8]|5\24[9]|6\24[0]|7\24[1]|8\24[2]|9\24[3])|4\23(?:0\24[5]|1\24[6]|2\24[7]|3\24[8]|4\24[9]|5\24[0]|6\24[1]|7\24[2]|8\24[3]|9\24[4])|5\23(?:0\24[6]|1\24[7]|2\24[8]|3\24[9]|4\24[0]|5\24[1]|6\24[2]|7\24[3]|8\24[4]|9\24[5])|6\23(?:0\24[7]|1\24[8]|2\24[9]|3\24[0]|4\24[1]|5\24[2]|6\24[3]|7\24[4]|8\24[5]|9\24[6])|7\23(?:0\24[8]|1\24[9]|2\24[0]|3\24[1]|4\24[2]|5\24[3]|6\24[4]|7\24[5]|8\24[6]|9\24[7])|8\23(?:0\24[9]|1\24[0]|2\24[1]|3\24[2]|4\24[3]|5\24[4]|6\24[5]|7\24[6]|8\24[7]|9\24[8])|9\23(?:0\24[0]|1\24[1]|2\24[2]|3\24[3]|4\24[4]|5\24[5]|6\24[6]|7\24[7]|8\24[8]|9\24[9])|0\23(?:0\24[1]|1\24[2]|2\24[3]|3\24[4]|4\24[5]|5\24[6]|6\24[7]|7\24[8]|8\24[9]|9\24[0])))\d)+\ |^0+\ 0*(\d+)\ 0*\g{-1}$|^0*(\d+)\ 0+\ 0*\g{-1}$)).+
```

Try it online!

I've been on the prowl for difficult challenges after a hiatus from regex, and just happened to stumble across this doozy. Verifying addition (with Perl/PCRE) is something I've thought about before, but promptly dismissed as either impossible or beyond my ability. However, I took another crack at it now and I'm quite thrilled to say that I've actually done it!

I didn't really golf this other than considering short algorithms and overall matching technique when I wrote it. I'm just really happy I got it done :D

If people are interested, I could add comments and explain how it works.

Edit: I made a detailed post on my blog about this, with explanations and comments :) enjoy: http://www.drregex.com/2018/09/a-regex-i-submitted-to-reddit-climbed.html
> 16 votes

# Answer
## .NET flavour, ~~139~~ ~~111~~ 106 + 1 = 107 bytes

Needs the `RightToLeft` modifier `r`. Input in binary.

```
(?(2)!)^\5 \7 ((?(2)()(?(2)!)(?<-2>){2})(0|(?<-2>1))(?<=(((0|(?<2>1)|\b)(?=.*(?<=(\5).*))?\7?) \d*){2}))+$

```

Try it online! (Using Retina.)

Yay for balancing groups. I'll explain this later...

### Decimal version, ~~340~~ 243 + 1 = 244 bytes

```
(?(2)!)^\5 \7 ((?(2)()(?(2)!)(?<-2>){10})(0|(?<-2>1|(?<-2>2|(?<-2>3|(?<-2>4|(?<-2>5|(?<-2>6|(?<-2>7|(?<-2>8|(?<-2>9))))))))))(?<=(((0|(?<2>1|(?<2>2|(?<2>3|(?<2>4|(?<2>5|(?<2>6|(?<2>7|(?<2>8|(?<2>9)))))))))|\b)(?=.*(?<=(\5).*))?\7?) \d*){2}))+$

```

Try it online!
> 6 votes

# Answer
# .NET, 96 bytes

```
^\4 \6((?(2)()(?(2)^)(?<-2>){2}| ?)(0|(?<-2>1))(?<=((0|(?<2>1)|)\4?) .*((0|(?<2>1)|)\6?) .*))+$

```

Flag: `r`

Try it online!

### Decimal version, 238 bytes

```
^\5 \6(?<-6>)((?(2)()(?(2)^)(?<-2>){10}| ?)((?<-2>[1469]|(?<-2>[27]))|[0358])(?([5-9])(?<-2>){5})(?([3489])(?<-2>){3})(?<=(((((?=[5-9](?<2>){5}|)(?=[3489](?<2>){3}|)((?<2>[1469]|(?<2>[27]))|.))?(?( .*)\6?(?<-6>)?|\5?(?<-5>)))) .*){2}))+$

```

Flag: `r`

Try it online!

Similar to Martin's answer.
> 2 votes

---
Tags: code-golf, arithmetic, regular-expression
---