# Split as number, join as string, repeat

Consider the process of:

1. Taking a non-negative integer N.
e.g. 27.

2. Spliting it into integers N - floor(N/2) and floor(N/2) (a 'bigger' and 'smaller' half) and writing them in that order.
e.g.27 becomes 14 13.

3. Removing the space to join the integers into a new, much larger integer.
e.g. 14 13 becomes 1413.

4. Repeating steps 2 and 3 some desired number of times.
e.g. 1413707 706707706353853 353853353853353853 → ...

This challenge is about doing exactly this, but not always in base 10.

# Challenge

Write a program that takes in three numbers, B, N, and S:

• B is an integer from 2 to 10 that is the base of N (binary to decimal).

• N is the non-negative integer to apply the splitting-rejoining process to. To make user input easier, it is given as a string in base B, not an integer.

• S is a non-negative integer that is the number of times to repeat the splitting-rejoining process.

The output of the program is the string representation of N in base B after S split-join procedures.

When S is 0, no splits are done, so the output is always N.

When N is 0, all splits have the form 0 0 and reduce to 0 again, so the output is always 0.

# Examples

• B = 10, N = 27, S = 11413
• B = 10, N = 27, S = 2707706
• B = 9, N = 27, S = 11413
• B = 9, N = 27, S = 2652651
• B = anything, N = anything, S = 0N
• B = anything, N = 0, S = anything0

Table for all B with N = 1 for S = 0 to 7:

B       S=0     S=1     S=2     S=3         S=4             S=5                 S=6                                 S=7
2       1       10      11      101         1110            111111              10000011111                         10000100001000001111
3       1       10      21      1110        202201          101101101100        1201201201212012012011              212100212102121002121212100212102121002120
4       1       10      22      1111        223222          111311111311        2232222232322322222322              11131111131311311111311113111113131131111131
5       1       10      32      1413        432431          213441213440        104220331443104220331442            2433241322130211014044424332413221302110140443
6       1       10      33      1514        535535          245550245545        122553122553122553122552            4125434125434125434125441254341254341254341254
7       1       10      43      2221        11111110        40404044040403      2020202202020220202022020201        10101011010101101010110101011010101101010110101011010100
8       1       10      44      2222        11111111        44444454444444      2222222622222222222226222222        11111113111111111111131111111111111311111111111113111111
9       1       10      54      2726        13581357        62851746285173      3142536758708231425367587081        15212633743485606571782880411521263374348560657178288040
10      1       10      55      2827        14141413        70707077070706      3535353853535335353538535353        17676769267676676767692676771767676926767667676769267676


Table for all B with random N for S = 0 to 3:

B       S=0     S=1         S=2                 S=3
2       11011   11101101    11101111110110      11101111110111110111111011
3       2210    11021101    20102012010200      1001212100121210012121001211
4       1113    230223      112112112111        2302302302323023023022
5       101     2323        11341134            31430423143042
6       120     4040        20202020            1010101010101010
7       134     5252        24612461            1230456412304564
8       22      1111        445444              222622222622
9       4       22          1111                505505
10      92      4646        23232323            1161616211616161


# Details

• Take input via stdin or the command line. Output to stdout.
• Instead of a program, you may write a function that takes B, N, and S and prints the result normally or returns it (as a string).
• B, N, and S may be taken in any order.
• All inputs that produce outputs whose decimal values are below 232 should work.
• N is represented in the usual way. i.e. most significant digit first and no leading zeros except in zero itself which is written 0. (Outputting 00 instead of 0 is invalid.)
• The shortest code in bytes wins.

Iff you enjoy my challenges, consider giving Block Building Bot Flocks! some love :)

• I don't know if a leaderboard for answers is really necessary.
– orlp
May 25 '15 at 23:00
• @orlp Probably not. I'll remove it and put it back if there are a bunch of answers. I just wanted to show off my and Optimizers Stack Snippet shenanigans. May 25 '15 at 23:02

# Pyth, 29 21 bytes

jku+j-JiGQK/J2QjKQvwz


Really straightforward implementation.

Takes input on stdin in the following format:

N
B
S

• This gives the wrong output 00 for N=0. May 26 '15 at 6:12

# Mathematica, 101 bytes

Nest[a~Function~(b=FromDigits)[Through@((c=IntegerString)@*Ceiling<>c@*Floor)[a/2],#],#2~b~#,#3]~c~#&


Uses some Through trickery to apply both the ceiling and floor functions. Just ignore the errors.

# CJam, 24 bytes

q~:B;{:~Bb_)\]2f/Bfbs}*i


Test it here. Takes input as "N" S B.

## Explanation

q~                       e# Read an eval input.
:B;                    e# Store the base in B and discard it.
{               }*  e# Repeat S times.
:~                 e# Turn the string N into an array of digits.
Bb               e# Interpret as base B.
_)\            e# Duplicate and increment. Swap order.
]2f/        e# Wrap them in an array and (integer-)divide both by 2.
Bfb     e# Convert both to base B.
s    e# Flatten into a single string.
i e# Convert to an integer to fix the N = 0 case.

• "0" 1 9 outputted 00. I tried to golf it: q~:B;{:~Bb,2/z:,Bfbs}*, but also invalid because it outputted empty string instead. May 26 '15 at 1:22
• An i at the end would take care of 00. You can get the byte back by replacing 2/:I-I] with )\]2f/. May 26 '15 at 3:21

# Pyth, 21 19 bytes

vujksmjldQc2UiGQvwz


Takes input in the format N\nB\nS. Try it online: Demonstration or Test harness

### Explanation

                      implicit: z = 1st input (N)
Q = 2nd input evaluated (B)
u              vwz   reduce z (evaluated 3rd input) times by:
iGQ         convert string from base Q to base 10
U            create a range [0, 1, ..., ^-1]
c2             split into 2 lists (lengths are N-[N/2] and [N/2])
m                   map each list d to:
ld                   their length
j  Q                  in base Q
s                    join both lists
jk                     join the numbers by ""
v                     convert string to int (getting rid of leading zeros)


# JavaScript (ES6) 78 79

Recursive function. Run snippet to test (Firefox only)

Edit 1 byte saved thx @DocMax

F=(b,n,s,S=x=>x.toString(b),m=parseInt(n,b))=>m*s?F(b,S(-~m>>1)+S(m>>1),s-1):n

// Ungolfed

U=(b,n,s)=>
{
var S=x=>x.toString(b) // function to convert in base b
var m=parseInt(n,b) // string in base b to integer
if (m==0 || s==0)
return n
else
return F(b,S((m+1)>>1) + S( m>>1 ),s-1)
}

// Test
test=[
{B: 10, N: '0', S:3, K: '0' }, {B: 10, N: '27', S: 1, K: '1413' }, {B: 10, N: '27', S: 2, K: '707706' }, {B: 9, N: '27', S: 1, K: '1413' }, {B: 9, N: '27', S: 2, K: '652651' }
];

test2=[[2, '11011', '11101101', '11101111110110', '11101111110111110111111011'],[3, '2210', '11021101', '20102012010200', '1001212100121210012121001211'],[4, '1113', '230223', '112112112111', '2302302302323023023022'],[5, '101', '2323', '11341134', '31430423143042' ]  ,[6, '120', '4040', '20202020', '1010101010101010'],[7, '134', '5252', '24612461', '1230456412304564'],[8, '22', '1111', '445444', '222622222622'],[9, '4', '22', '1111', '505505'],[10, '92', '4646', '23232323', '1161616211616161' ]
]
test2.forEach(r=>test.push(
{B:r,N:r,S:1,K:r}, {B:r,N:r,S:2,K:r}, {B:r,N:r,S:3,K:r}
))

test.forEach(t => (
r=F(t.B, t.N, t.S),
B.innerHTML += '<tr><th>'+(r==t.K?'Ok':'Failed')
+'</th><td>'+t.B +'</td><td>'+t.N
+'</td><td>'+t.S +'</td><td>'+r +'</td><td>'+t.K +'</td></tr>'
))
th,td { font-size: 12px; padding: 4px; font-family: helvetica }
<table><thead><tr>
<th>Test<th>B<th>N<th>S<th>Result<th>Check
<tbody id=B></tbody>
</table>

• I truly love how elaborate your proofs of success are. Also, you can save 1 by replacing m&&s with m*s. May 26 '15 at 16:47
• @DocMax it's a real and useful unit test. It's too easy to break everything while golfing. May 26 '15 at 17:12

# ECMAScript 6, 90 bytes

var f=(B,N,S)=>((n,s)=>S?f(B,s(n+1>>1)+s(n>>1),S-1):s(n))(parseInt(N,B),x=>x.toString(B))


Defining a recursive function using a variable is not really good style, but it is the shortest code I could come up with in ECMAScript 6.

Getting the corner case "00" => "0" right wastes three bytes (s(n) instead of simply N).

To try it out, you can use Babel's REPL: copy/paste the code and print example invocation results like so: console.log(f(9, "27", 2)).

# Common Lisp - 113 characters

(lambda(b n s)(dotimes(i s)(setf n(format ()"~vR~vR"b (- #1=(parse-integer n :radix b)#2=(floor #1# 2))b #2#)))n)


# Ungolfed

(lambda(b n s)
(dotimes(i s)
(setf n (format () "~vR~vR" b (- #1=(parse-integer n :radix b)
#2=(floor #1# 2))
b #2#)))
n)

• The ~vR format directive outputs integer in base v, where v is provided as an arguments to format.
• parse-integer accepts a :radix argument for converting from a specified base.
• #1= and #1# (respectively assign and use) are reader variables which allow to share common sub-expressions. When expanded, they give the following code:

(lambda (b n s)
(dotimes (i s)
(setf n
(format nil "~vr~vr" b
(floor (parse-integer n :radix b) 2))
b (floor (parse-integer n :radix b) 2))))
n)


# Pip, 27 bytes

Lcb:+J[(bFB:a)%2i]+b//2TBab


Takes base, integer, and number of repetitions as command-line arguments. The algorithm is straightforward, but uses a couple interesting language features:

                             a, b, c initialized from cmdline args, and i = 0 (implicit)
Lc                           Do c times:
bFB:a                Convert b from base a to decimal and assign back to b
[(     )%2i]           Construct a list containing b%2 and 0 (using i to avoid
scanning difficulties)
+b//2      Add floor(b/2) to both elements of list; the list now contains
b-b//2 and b//2
TBa   Convert elements of list back to base a
J                       Join list
+                        Coerce to number (necessary to turn 00 into plain 0)
b:                         Assign back to b
b  Print b at the end


Pip's scalar type, which represents both numbers and strings, is handy here, as are item-wise operations on lists; unfortunately, parentheses and the two-character operators FB, TB, and // negate any advantage.

Alternate solution, without the intermediate assignment but still 27 bytes:

Lcb:+J[bFBa%2i]+bFBa//2TBab


# C, 245 bytes

int b,z,n,f,r;c(char*t,n){return n?((z=c(t,n/b)),z+sprintf(t+z,"%d",n%b)):0;}main(){char t,*p;gets(t);b=atoi(t);f=n=strtol(p=strchr(t,32)+1,0,b);if(!(r=atoi(strchr(p,32)+1)))f=0;while(r--)n=strtol(t+c(t+c(t,n-n/2),n/2)*0,0,b);puts(f?t:"0");}


This isn't going to win anything, but it was fun to make!

# PHP, 115 112 bytes

function($b,$n,$s){while($s--)$n=($c=base_convert)(ceil($n=$c($n,$b,10)/2),10,$b).$c(floor($n),10,$b);return$n;}  Try it online! Ungolfed: function split_join_repeat($b, $n,$s ) {
// repeat S times
for( $x=0;$x < $s;$x++ ) {
// convert N from base B to base 10 for arithmetic
$n = base_convert($n, $b, 10 ); // divide and split in base 10, convert back to base B and join$n = base_convert( ceil( $n / 2 ), 10,$b ) .
base_convert( floor( $n / 2 ), 10,$b );
}
return \$n;
}


Output

B = 10, N = 27, S = 1   1413
B = 10, N = 27, S = 2   707706
B = 9, N = 27, S = 1    1413
B = 9, N = 27, S = 2    652651

2   1   10  11  101 1110    111111  10000011111 10000100001000001111
3   1   10  21  1110    202201  101101101100    1201201201212012012011  212100212102121002121212100212102121002120
4   1   10  22  1111    223222  111311111311    2232222232322322222322  11131111131311311111311113111113131131111131
5   1   10  32  1413    432431  213441213440    104220331443104220331442    12141204110401030043301214120411040103004330
6   1   10  33  1514    535535  245550245545    122553122553122553122552    131022143412311313533131022143412311313533
7   1   10  43  2221    11111110    40404044040403  2020202202020220202022020201    40556522600645213204055652260064521320
8   1   10  44  2222    11111111    44444454444444  2222222622222222222226222222    76650460747555347665046074755534
9   1   10  54  2726    13581357    62851746285173  3142536758708231425367587081    4861155667688600048611556676886000
10  1   10  55  2827    14141413    70707077070706  3535353853535335353538535353    17676769267677271767676926767727


# Japt, 17 bytes

_nW o ó ®ÊsWÃq}gV


Try it online!

Takes input in the order S, N, B with N as a singleton list. Accepting N without a singleton list costs 2 bytes.

Explanation:

_             }g     #Get the Sth item generated by this function...
V    #...Starting with N as the 0th item:
nW                  # Evaluate the previous item as a base B number
o                # Create a list with that length
ó              # Divide it into two lists as evenly as possible
®   Ã        # For each of those lists:
Ê           #  Get the length
sW         #  Convert it to base B
q       # Join the two strings together


# Forth (gforth), 105 bytes

: f base ! 0 ?do 0. 2swap >number nip 2drop 2 /mod >r i + r> 0 tuck <# #s 2drop #s #> loop type decimal ;


Try it online!

### Explanation

Changes the base to B, then in a loop that runs S times:

• Converts string to a number
• Splits number in 2 halves (one larger than the other if odd)
• Combines the two numbers back into a string

Prints the string when finished and sets the base back to 10 (so we can run multiple times in a row)

### Code Explanation

:f                    \ start a new word definition
base !              \ set the base to B
0 ?do               \ loop from 0 to S-1 (runs S times)
0. 2swap          \ places a double-length 0 on the stack behind the string
>number           \ converts the string to a number in the current base
nip 2drop         \ get rid of string remainder and second part of double
2 /mod            \ get the quotient and remainder of dividing by 2
>r                \ throw the quotient on the return stack
i                 \ get a copy of the quotient from the return stack
+                 \ add quotient and remainder
r>                \ move quotient from return stack to stack
0 tuck            \ convert both to double-length numbers
<#                \ start a pictured numeric output
#s              \ add entire number to output
2drop           \ drop empty number
#s              \ add second number to output
#>                \ convert output to a string and drop number from stack
loop                \ end loop
type                \ print output string
decimal             \ set base back to 10
;                     \ end word definition