6
\$\begingroup\$

Possible Duplicate:
Integer to string with given radix

This question is inspired by Pythons builtin int function. int is used to convert other numbers or strings into integers. If you are converting a string you can provide the additional parameter base, that contains the base that your number is represented in within the string:

>>> int('137')
137
>>> int('137',base=8)
95
>>> int('ff',base=16)
255
>>> int('1AZ',base=36)
1691

Unfortunately Python doesn't provide a function for the reverse case, where you want to convert a number into a string in a specific base.

Your task is to write such a function.

  • the function may return the value or print it
  • you must provide support for all bases between 2 and 36
  • digits to use are 0123456789abcdefghijklmnopqrstuvwxyz
  • all languages are allowed
  • built in functions for this purpose are boring and thus forbidden
  • shortest code wins
\$\endgroup\$
  • 4
    \$\begingroup\$ "built in functions for this purpose are boring" - and the problem itself isn't? \$\endgroup\$ – Peter Taylor Oct 4 '12 at 12:39
  • \$\begingroup\$ huh. i didnt think it was such a bad question :( \$\endgroup\$ – quasimodo Oct 4 '12 at 14:22
  • 1
    \$\begingroup\$ I thought it's a bit boring but it's a good exercise for golf beginners... +1 to even out that unfair -1! \$\endgroup\$ – milo5b Oct 4 '12 at 14:51
  • 4
    \$\begingroup\$ In fact, it's a trivial variant on some existing questions, most notably codegolf.stackexchange.com/questions/536/…, \$\endgroup\$ – Peter Taylor Oct 4 '12 at 15:08

10 Answers 10

2
\$\begingroup\$

APL (25)

{(⎕D,⎕A)[1+⍵⊤⍨⍺⍴⍨⌈⍺⍟⍵+1]}

The left argument is the base, and the right argument is the number.

i.e.

    16{(⎕D,⎕A)[1+⍵⊤⍨⍺⍴⍨⌈⍺⍟⍵+1]}1234
4D2
| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

C, 68

c(n,b,r){char*p=1+&r;for(r=0;n;n/=b)*--p=n%b+48+(n%b>9)*39;puts(p);}

testing:

main(){
  c(65,2);
  c(100,30);
  c(57005, 16);
}

output:

1000001
3a
dead

issues:

  • 0 is printed as empty string.
  • potential buffer overflows due to abuse of 'int' as a char array...
  • works with Apple clang v4.0 - your milage may vary with other compilers.
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Just to tease you a bit, i've got a working c function in 48 characters, i will release it after i choose a winner :) \$\endgroup\$ – quasimodo Oct 5 '12 at 18:12
  • \$\begingroup\$ Also, it's architecture specific (depends on endianness of system). \$\endgroup\$ – Wug Oct 5 '12 at 20:43
  • \$\begingroup\$ Furthermore, puts appends a newline, so your outputs are vertical. \$\endgroup\$ – Wug Oct 5 '12 at 21:15
  • \$\begingroup\$ The 48 char version is out now, thanks to Wug, but its far less interesting/dangerous than yours. The code that gcc produces is remarkably safe, since r is the last value on the stack and the stack isnt used after that, all you are overwriting is uninitialized stack space. you could even get rid of the 1+, so you would ensure there is always a 0 byte at the end of the string. @Wug: he doesn't print character-wise, so the output is fine. \$\endgroup\$ – quasimodo Oct 6 '12 at 10:20
3
\$\begingroup\$

Befunge, 17x4 = 68 characters

1-&00p&>:!#v_:00v
v-10<  ^/g00\%g <
< >:^@_.# #$v#:!`
"_^#`9::$  <<,+"W

Online interpreter: http://www.bedroomlan.org/tools/befunge-93-playground

First input is base, second is number.

Similar to other solutions here this does not output anything when the number is 0. I may look at fixing this at some point.

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

PHP, 92 Bytes

Quite new to code-golf, so probably can do better than this (suggestions would be very welcome!)

function b($n,$b){while($n>0){$r=$n%$b;$n=floor($n/$b);$s=($r>9?chr(87+$r):$r).$s;}echo$s;}

With (some) whitespaces:

function b($n,$b)
{
  while ($n>0)
  {
    $r=$n%$b;
    $n=floor($n/$b);
    $s=($r>9?chr(87+$r):$r).$s;
  }
  echo $s;
}
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Next time somebody has to -1 my answer, could you please explain why? I am trying to learn here :) No hard feelings! \$\endgroup\$ – milo5b Oct 5 '12 at 8:16
  • \$\begingroup\$ You could probably shorten it by making the function recursive. Remember, you don't need to print the string, returning it is enough. \$\endgroup\$ – quasimodo Oct 6 '12 at 10:35
2
\$\begingroup\$

Python, 81 58 bytes

x=lambda n,b:(n/b and x(n/b,b)or'')+chr(48+n%b+39*(n%b>9))

Usage: x(100,30) returns '3a', which is 100 in base 30.

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ some output characters are not from the required alphabet: x(30,36)='~' \$\endgroup\$ – quasimodo Oct 4 '12 at 13:49
  • \$\begingroup\$ 3a is 100 in base 30 (3*30+10) \$\endgroup\$ – SeanC Oct 4 '12 at 16:11
  • \$\begingroup\$ quasimido and @SeanCheshire - both right, a stupid mistake by me (same bug caused both symptoms). Fixed. \$\endgroup\$ – ugoren Oct 4 '12 at 19:52
2
\$\begingroup\$

C, 48 chars

i(n,b){n?i(n/b,b),putchar(n%b+48+(n%b>9)*39):0;}
  • input of 0 produces empty string

C, 77 49 chars, prints 0 for zero

I(n,b){putchar(n?i(n/b,b),48+n%b+(n%b>9)*39:48);}

To run, call i for first version, I for second.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ @quazimodo: I got this by hax0ring your computer. It was hard because you had norton, but you'll never catch me because im behind 7 proxies. \$\endgroup\$ – Wug Oct 5 '12 at 21:25
  • \$\begingroup\$ youre so 1337! But i need just one more char to print zero as 0 :D \$\endgroup\$ – quasimodo Oct 6 '12 at 9:29
  • \$\begingroup\$ @quasimodo: like this? :D \$\endgroup\$ – Wug Oct 8 '12 at 7:55
  • \$\begingroup\$ more like this: c(n,b){n/b&&c(n/b,b);putchar((n%b>9)*39+48+n%b);}. But yours is also nice! \$\endgroup\$ – quasimodo Oct 8 '12 at 12:10
1
\$\begingroup\$

C# – 85 characters

string F(int n,int b){var s="";for(;n>0;n/=b)s=(char)(n%b+(n%b>9?87:48))+s;return s;}
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

VBA, 99

(70 if you take out the function/endfunction lines)

Function F(a,b)
F="":q=a:Do:c=q Mod b:F=Chr(c+48-39*(c>9))&F:q=Int(q/b):Loop Until q=0
End Function

fixed for case when a=0

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Ocaml, 98 or 120

It prints out a leading zero, though. Usage: 16-0xBEEF

let rec(-)b=function|0->"0"|n->b-n/b^String.make 1(Char.chr(n mod b+if n mod b>9 then 55 else 48))

Unfortunately a lot of characters are spent on converting to char then to string :/

This one is correct.

let rec(-)b=function|0->"0"|n->(if 0=n/b then""else b-n/b)^String.make 1(Char.chr(n mod b+if n mod b>9 then 55 else 48))

The strong typing in ocaml is sometimes unfortunate when golfing. Partial application and such somewhat make up for it, though.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

CoffeeScript (98 92)

z=(i,b)->a=parseInt(i)%b;return''if 1>i;(z i/b,b)+if a>9then String.fromCharCode(a+87)else a

The compiled (and readable) javascript for the interested:

z = function(i, b) {
  var a;
  a = parseInt(i) % b;
  if (1 > i) {
    return '';
  }
  return (z(i / b, b)) + (a > 9 ? String.fromCharCode(a + 87) : a);
};

What can I say? Unnecessary recursion gets me hot.

This could have been far shorter if I knew a shorter way to floor or convert from ASCII in Coffee-/Javascript. Tips would be greatly appreciated.

Edited to include "parseInt" to save a couple of characters on "Math.floor" and with some rearranging to reduce the "if ... then ..."s. Unfortunately, I don't think there even is a shorthand if in CoffeeScript ( "... ? ... : ..." doesn't work).

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ parseInt() would be 2 char shorter of Math.floor, and I believe would have the same effect \$\endgroup\$ – milo5b Oct 5 '12 at 15:58
  • \$\begingroup\$ you don't need Math.floor if you are using String.fromCharCode to print the numbers, also you can probably shorten the code a bit by using shortcut operators instead of ifs. \$\endgroup\$ – quasimodo Oct 5 '12 at 18:39

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