9
\$\begingroup\$

Computers live by binary. All programmers know binary.

But the 2**x bases are often neglected as non-practical, while they have beautiful relations to binary.

To show you one example of such a beatiful relation, 19 will be my testimonial.

19 10011 103 23 13 j
  • 19 is decimal, included for clarity.

  • 10011 is 19 in binary.

  • 103, in base 4 is made starting from binary this way:

    • log2(4) == 2, let us remember two.
    • Pad 10011 so that it has a multiple of 2 length -> 010011
    • Take digits 2 by 2 from left to right and treat them as 2-digits binary numbers:

      • 01 -> 1
      • 00 -> 0
      • 11 -> 3

    Done, 10011 in base-4 is 103.

For base 8, do the same but 3-by-3 as log2(8) = 3.

  • Pad 010011
  • 010 -> 2
  • 011 -> 3

    23, Done.

For base 16, do the same but 4-by-4 as log2(16) = 4.

  • Pad 00010011
  • 0001 -> 1
  • 0011 -> 3

    13, Done.

Task

Given a max number as input, you shall output a table

base-ten-i base-two-i base-four-i base-eight-i base-sixteen-i base-thirtytwo-i

for i that goes from 0 to n inclusive. Binary numbers are the epitome of the absolute minimum needed to work, so your code should be as short as possible.

Restrictions and bonuses

  • Base-ten -> binary and binary -> Base-ten built-ins are considered loopholes as Base-a -> Base-b are.

  • If you generate all the 2**i (for i > 2) bases by using the relations over mentioned you get a *0.6 bonus, but general base conversions (written by yourself) are allowed.

Example table

> 32
0 0 0 0 0 0
1 1 1 1 1 1
2 10 2 2 2 2
3 11 3 3 3 3
4 100 10 4 4 4
5 101 11 5 5 5
6 110 12 6 6 6
7 111 13 7 7 7
8 1000 20 10 8 8
9 1001 21 11 9 9
10 1010 22 12 a a
11 1011 23 13 b b
12 1100 30 14 c c
13 1101 31 15 d d
14 1110 32 16 e e
15 1111 33 17 f f
16 10000 100 20 10 g
17 10001 101 21 11 h
18 10010 102 22 12 i
19 10011 103 23 13 j
20 10100 110 24 14 k
21 10101 111 25 15 l
22 10110 112 26 16 m
23 10111 113 27 17 n
24 11000 120 30 18 o
25 11001 121 31 19 p
26 11010 122 32 1a q
27 11011 123 33 1b r
28 11100 130 34 1c s
29 11101 131 35 1d t
30 11110 132 36 1e u
31 11111 133 37 1f v
32 100000 200 40 20 10
\$\endgroup\$
  • 4
    \$\begingroup\$ Downvoted because of "You must generate all the 2**i (for i > 2) bases by using the relations over mentioned". Requiring a specific algorithm removes a lot of what makes code golf interesting. You can ban built-in base conversion functions while still allowing a choice of algorithm. \$\endgroup\$ – xnor Sep 19 '15 at 1:02
  • \$\begingroup\$ @xnor now using my method only gives a bonus, to give more freedom to golfers \$\endgroup\$ – Caridorc Sep 19 '15 at 9:21
  • 1
    \$\begingroup\$ I'm not a fan of the bonus either. It effectively means you have to use either a built-in or your algorithm, and no other algorithm can be viable. \$\endgroup\$ – xnor Sep 19 '15 at 9:29
  • \$\begingroup\$ @xnor built-ins are not allowed. A general converter will be shorter, so I give a bonus if you use my contrived conversion rules \$\endgroup\$ – Caridorc Sep 19 '15 at 9:32
2
\$\begingroup\$

CJam, 54 * 0.6 = 32.4 bytes

q~){_5,f{)L@{2md@+\}h(%/Wf%W%{{\2*+}*_9>{'W+}&}%S\}N}/

Test it here.

For reference, here is a shorter solution which doesn't qualify for the bonus (at 39 bytes):

q~){:X5{SLX{2I)#md_9>{'W+}&@+\}h;}fIN}/
\$\endgroup\$
  • \$\begingroup\$ I updated the challange, you may claim a 0.6* bonus if you used my method \$\endgroup\$ – Caridorc Sep 19 '15 at 9:37
1
\$\begingroup\$

Pyth, 52 * 0.6 = 31.2 bytes

L?b+%b2y/b2YVUhQjd+NmjkX|_uL++GGHZ_McyNd]ZUQ+jkUTGS5

Test it online

My non-bonus answer is 39 bytes

M?G+g/GHH@+jkUTG%GHkVUhQjd+N|R0gLN^L2S5
\$\endgroup\$
0
\$\begingroup\$

PHP, 232 230 233 217 * 0.6 = 130.2

no chance beating the golfing languages, but I liked the challenge.

for(;$d<=$n;$d++){echo'
',$d|0;for($k=$d,$b='';$k;$k>>=1)$b=($k&1).$b;for($w=1;$w<6;$w++,print" $z"|' 0')for($z='',$k=strlen($b);-$w<$k-=$w;$z=($e>9?chr($e+87):$e).$z)for($e=0,$y=1,$j=$w;$j--;$y*=2) $e+=$y*$b[$j+$k];}
  • usage: prepend $n=32; or replace $n with 32 (or any other non-negative integer); call via cli
  • If that is not accepted, replace $n with $_GET[n] (+6/+3.6) and call either in the browser
    or on cli with php-cgi -f bases.php -n=32
  • Replace the line break with <br> or prepend <pre> to test in browser
  • may throw notices for undefined variables and unintialized string offsets in newer PHP versions.
    Remove E_NOTICE from error_reporting (prepend error_reporting(0);) to suppress them.
  • tested in 5.6

break down:

for(;$d<=$n;$d++) // loop decimal $d from 0 to $n
{
    echo'
',$d|0; // print line break and decimal
    for($k=$d,$b='';$k;$k>>=1)$b=($k&1).$b; // convert $d to binary
    for($w=1;$w<6;$w++,
        print" $z"|' 0' // print number generated in inner loop (echo doesn´t work here)
    )
        for($z='',$k=strlen($b);-$w<$k-=$w; // loop from end by $w
            $z=($e>9?chr($e+87):$e).$z // prepend digit created in body
        )
            for($e=0,$y=1,$j=$w;$j--;$y*=2) $e+=$y*$b[$j+$k]; // convert chunk to 2**$w
}

major edit:

  • used some index magic to revamp the inner loop -> now works backwards on the whole string (no more padding, no more splitting or copying the binary)
  • moved parts of the loop bodies to the heads to eliminate braces
  • had to add 7 4 bytes to fix the decimal 0 results after the revamp

non-bonus version, 142 bytes

for(;$d<=$n;$d++,print'
',$d|0)for($w=1;$w<6;$w++,print" $z"|' 0')for($k=$d,$y=1,$z='';$k&&$y<<=$w;$k>>=$w)$z=(9<($e=$k%$y)?chr($e+87):$e).$z;

PHP beats Python?
Even if I added the 6 (3.6) bytes to make the snippet a program, I´d still beat Python (223*0.6=133.8 or 148 non-bonus vs. 158). Amazing.

\$\endgroup\$
  • \$\begingroup\$ I get an error 'Undefined variable: n :1' and I think that you can save 1 byte by removing a space after the for keyword in the outermost for-loop. \$\endgroup\$ – Yytsi Jul 3 '16 at 22:04
  • \$\begingroup\$ @TuukkaX: see usage: $n must be define before the snippet. I found that byte, but thanks. And one more: "\n" -> physical line break. \$\endgroup\$ – Titus Jul 4 '16 at 15:33
  • \$\begingroup\$ but I had to add 3 bytes to print the first 0. (that or 5 bytes to init the variable). \$\endgroup\$ – Titus Jul 4 '16 at 16:52
0
\$\begingroup\$

Ruby, 80 bytes (non-bonus version)

m=ARGV[0].to_i;(0..m).each{|n|puts [10,2,4,8,16,32].map{|b|n.to_s(b)}.join(' ')}
\$\endgroup\$
0
\$\begingroup\$

Python3 - 189, 167, 166 150 bytes

for i in range(int(input())+1):f=lambda b,n=i,c="0123456789abcdefghijklmnopqrstuv":n<b and c[n]or f(b,n//b)+c[n%b];print(i,f(2),f(4),f(8),f(16),f(32))

Saved 16 bytes with the help of @LeakyNun!

Bonus version - 296 * 0.6 = 177.6 279 * 0.6 = 167.4 bytes

p=lambda b,c:"".join(str(int(b[i:i+c],2))for i in range(0,len(b),c))
z=lambda s:len(s)%2 and s or "0"+s
for i in range(int(input())+1):f=lambda n,b,c="0123456789abcdefghijklmnopqrstuv":n<b and c[n]or f(n//b,b)+c[n%b];v=f(i,2);d=z(v);print(i,v,p(d,2),p(d,3),p(d,4),p(d,5),f(i,32))

Slightly more readable version of the bonus version.

p=lambda b,c:"".join(str(int(b[i:i+c],2))for i in range(0,len(b),c))
z=lambda s:len(s)%2 and s or "0"+s
for i in range(int(input())+1):
    f=lambda n,b,c="0123456789abcdefghijklmnopqrstuv":n<b and c[n] or f(n//b,b) + c[n%b]
    v=f(i,2)
    d=z(v)
    print(i,v,p(d,2),p(d,3),p(d,4),p(d,5),f(i,32))
\$\endgroup\$
  • \$\begingroup\$ I am pretty certain that the bonus does not apply. You are not using binary to produce the base 2**x numbers. \$\endgroup\$ – Titus Jul 4 '16 at 16:23
  • \$\begingroup\$ @Titus Oh, I understood the bonus wrong then. I'll edit the byte count. Thanks! \$\endgroup\$ – Yytsi Jul 4 '16 at 16:24
  • \$\begingroup\$ Pretty sure "0123456789abcdefghijklmnopqrstuv" is shorter than from string import* digits+ascii_lowercase \$\endgroup\$ – Leaky Nun Jul 4 '16 at 17:52
  • \$\begingroup\$ @LeakyNun Oops. You're right. I only thought of how short it is to write digits+ascii_lowercase :D. Thanks! \$\endgroup\$ – Yytsi Jul 4 '16 at 17:53
  • \$\begingroup\$ 150 bytes: for i in range(int(input())+1):f=lambda n=i,b,c="0123456789abcdefghijklmnopqrstuv":n<b and c[n]or f(n//b,b)+c[n%b];print(i,f(2),f(4),f(8),f(16),f(32)) (one line) \$\endgroup\$ – Leaky Nun Jul 4 '16 at 18:04

Your Answer

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

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