C, int
: 138 123 bytes, long
: 152 131 bytes
I have created two versions of this, as the challenges' limit of a working max input of 0x100000000
seemed a bit odd. One version works with 32 bit integers (which fails the limit for obvious reasons), the other version works with 64 bits (which goes way beyond the given limit, at the cost of 14 8 extra bytes).
32 bit version:
char b[22],*r=b;f(v,l)char*l;{v%3>1?*r++=*l,v++:0;v&&f(v/3,l+1);v%3?*r++=*l:0;}g(v){f(v,"139ABCDEFGHIJKLMNOPQR");*r=0;r=b;}
64 bit version:
char b[22],*r=b;f(long v,char*l){v%3>1?*r++=*l,v++:0;v&&f(v/3,l+1);v%3?*r++=*l:0;}g(long v){f(v,"139ABCDEFGHIJKLMNOPQR");*r=0;r=b;}
This is identical except that it declares the integer variable to be long
(which is 64 bits on linux).
The ungolfed long
version:
char buffer[22],*result=buffer;
f(long value,char*letter){
if(value%3>1){
*result++=*letter,value++;
}
if(value){
f(value/3,letter+1);
}
if(value%3){
*result++=*letter;
}
}
g(long value){
f(value,"139ABCDEFGHIJKLMNOPQR");
*result=0;
result=buffer;
}
As you can see, this works by recursive decent: If the remainder is 1, the respective character is appended to the output string after the recursive call. If the remainder is 2, the output is performed before the recursing. In this case, I also increment the value by one to handle the negative digit correctly. This has the added benefit of changing the remainder to zero, allowing me to use value%3
as the condition for the post-recursion if.
The result of the conversion is placed into the global buffer. The g()
wrapper has the job of zero terminating the resulting string correctly, and to reset the result
pointer to its start (which is also how g()
"returns" the result).
Test the long
version with this code:
#include <stdio.h>
char b[22],*r=b;f(long v,char*l){v%3>1?*r++=*l,v++:0;v&&f(v/3,l+1);v%3?*r++=*l:0;}g(long v){f(v,"139ABCDEFGHIJKLMNOPQR");*r=0;r=b;}
void printConversion(long value) {
g(value);
printf("%ld: %s\n", value, r);
}
int main() {
for(long i = 0; i <= 40; i++) {
printConversion(i);
}
printConversion(0x7fffffff);
printConversion(0xffffffffu);
printConversion(0x100000000);
}
Possible further, but destructive golfing:
-4 bytes: make the function a one-shot by removing the pointer reset in g()
.
-5 bytes: force the caller to perform the string termination, returning the string without termination in buffer
, and the end of the string in result
.
|
and the positives to the right of it. \$\endgroup\$