#C89, limited-range signed int n, 64 53 bytes
C89, limited-range signed int n, 64 53 bytes
#C89, signed int, table as an implicit-length C string, 65 bytes
Stack Exchange network consists of 183 Q&A communities including Stack Overflow, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.
Visit Stack ExchangeStack Internal
Knowledge at work
Bring the best of human thought and AI automation together at your work.
Explore Stack Internal #C89, limited-range signed int n, 64 53 bytes
int n, #C89, signed int, table as an implicit-length C string, 65 bytes
int, table as an implicit-length C string, 65 bytes #C89, limited-range signed int n, 64 53 bytes
#C89, signed int, table as an implicit-length C string, 65 bytes
int n, int, table as an implicit-length C string, 65 bytes #C89, limited-range signed int n, 6464 53 bytes
char **out and modify it, instead of taking and returning a char * Takes the number as an int, the lookup table as an array + length.
Output is written into a char *outbuf. Caller passes (by reference) a pointer to the end of the buffer, function returns a. Function modifies that pointer to point to the first byte of the string on return.
char*gg(xn,I,B,O)char*I,*O;**O;{for(*O=0;x;x**O=0;n;n/=B)*--O=I[x%B];return O;*O=I[n%B];} This is valid C89, and works correctly even with optimization enabled. i.e. doesn't depend on gcc -O0 behaviour when falling off the end of a non-void function or have any other UB.
Try it online!Try it online!. Ungolfed Ungolfed version:
//* int xn = the number // * int B = size of I = base // * char *II[] = input table // * char *O**O = input/output bufferarg (passed by ref: * on entry: pointer to the last byte) of output buffer. char *g* on exit: pointer to the first byte of the 0-terminated string in output buffer */ void ungolfed_g(xn,I,B,O)char*I,*O;**O; { *O=0;char *outpos = *O; / /* terminateGolfed theversion outputuses string *O everywhere we use for(;x;xoutpos */=B) *outpos = 0; *--O = I[x%B]; // produce 1 char at a time,/* decrementingterminate the output pointerstring */ returnfor(;n;n/=B) O; *--outpos = I[n%B]; //* returnproduce 1 char at a pointertime, sodecrementing the calleroutput knowspointer where*/ in the buffer the*O result= startsoutpos; } In this explicit-length version, the input is a char table[] which does not need a terminating 0 byte, because we never treat it as a string. It could be an int table[] for all we care. C doesn't have containers that know their own length, so pointer+length is the normal way to pass an array with a size. So we choose that instead of needing to strlen.
The maximum buffer size is approximately sizeof(int)*CHAR_BIT + 1, so it's small and compile-time constant. (We use this much space with base=2 and all the bits set to 1.) e.g. 33 bytes for 32 bit integers, including the 0 terminator.
#C89, signed int, table as an implicit-length C string, 7665 bytes
B;char*fB;f(xn,I,O)char*I,*O;**O;{B=strlen(I);for(*O=0;x;x**O=0;n;n/=B)*--O=I[x%B];return O;*O=I[n%B];} #C89, limited-range signed int n, 64 bytes
Takes the number as an int, the lookup table as an array + length.
Output is written into a char *outbuf. Caller passes a pointer to the end of the buffer, function returns a pointer to the first byte of the string.
char*g(x,I,B,O)char*I,*O;{for(*O=0;x;x/=B)*--O=I[x%B];return O;} This is valid C89, and works correctly even with optimization enabled. i.e. doesn't depend on gcc -O0 behaviour when falling off the end of a non-void function.
Try it online!. Ungolfed version:
// int x = the number // int B = size of I = base // char *I = input table // char *O = output buffer (pointer to the last byte) char *g(x,I,B,O)char*I,*O; { *O=0; // terminate the output string for(;x;x/=B) *--O = I[x%B]; // produce 1 char at a time, decrementing the output pointer return O; // return a pointer so the caller knows where in the buffer the result starts } In this explicit-length version, the input is a char table[] which does not need a terminating 0 byte, because we never treat it as a string. It could be an int table[] for all we care. C doesn't have containers that know their own length, so pointer+length is the normal way to pass an array with a size.
The maximum buffer size is approximately sizeof(int)*CHAR_BIT + 1, so it's small and compile-time constant. (We use this much space with base=2 and all the bits set to 1.)
#C89, signed int, table as an implicit-length C string, 76 bytes
B;char*f(x,I,O)char*I,*O;{B=strlen(I);for(*O=0;x;x/=B)*--O=I[x%B];return O;} #C89, limited-range signed int n, 64 53 bytes
char **out and modify it, instead of taking and returning a char * Takes the number as an int, the lookup table as an array + length.
Output is written into a char *outbuf. Caller passes (by reference) a pointer to the end of the buffer. Function modifies that pointer to point to the first byte of the string on return.
g(n,I,B,O)char*I,**O;{for(**O=0;n;n/=B)*--*O=I[n%B];} This is valid C89, and works correctly even with optimization enabled. i.e. doesn't depend on gcc -O0 behaviour when falling off the end of a non-void function or have any other UB.
Try it online!. Ungolfed version:
/* int n = the number * int B = size of I = base * char I[] = input table * char **O = input/output arg passed by ref: * on entry: pointer to the last byte of output buffer. * on exit: pointer to the first byte of the 0-terminated string in output buffer */ void ungolfed_g(n,I,B,O)char*I,**O; { char *outpos = *O; /* Golfed version uses *O everywhere we use outpos */ *outpos = 0; /* terminate the output string */ for(;n;n/=B) *--outpos = I[n%B]; /* produce 1 char at a time, decrementing the output pointer */ *O = outpos; } In this explicit-length version, the input is a char table[] which does not need a terminating 0 byte, because we never treat it as a string. It could be an int table[] for all we care. C doesn't have containers that know their own length, so pointer+length is the normal way to pass an array with a size. So we choose that instead of needing to strlen.
The maximum buffer size is approximately sizeof(int)*CHAR_BIT + 1, so it's small and compile-time constant. (We use this much space with base=2 and all the bits set to 1.) e.g. 33 bytes for 32 bit integers, including the 0 terminator.
#C89, signed int, table as an implicit-length C string, 65 bytes
B;f(n,I,O)char*I,**O;{B=strlen(I);for(**O=0;n;n/=B)*--*O=I[n%B];} #C89, limited-range signed int n, 64 bytes
Takes the number as an int, the lookup table as an array + length.
Output is written into a char *outbuf. Caller passes a pointer to the end of the buffer, function returns a pointer to the first byte of the string.
char*g(x,I,B,O)char*I,*O;{for(*O=0;x;x/=B)*--O=I[x%B];return O;} This is valid C89, and works correctly even with optimization enabled. i.e. doesn't depend on gcc -O0 behaviour when falling off the end of a non-void function.
Passing a pointer to the end of a buffer is normal for an optimized int->string function, such as glibc's internal _itoa. See this answer for a detailed explanation of breaking an integer into digits with a div / mod loop like we're doing here, in C as well as x86-64 asm. If the base is a power of 2, you can shift/mask to extract digits MSD first, but otherwise the only good option is least-significant-digit first (with modulo).
Try it online!. Ungolfed version:
// int x = the number // int B = size of I = base // char *I = input table // char *O = output buffer (pointer to the last byte) char *g(x,I,B,O)char*I,*O; { *O=0; // terminate the output string for(;x;x/=B) *--O = I[x%B]; // produce 1 char at a time, decrementing the output pointer return O; // return a pointer so the caller knows where in the buffer the result starts } In this explicit-length version, the input is a char table[] which does not need a terminating 0 byte, because we never treat it as a string. It could be an int table[] for all we care. C doesn't have containers that know their own length, so pointer+length is the normal way to pass an array with a size.
The maximum buffer size is approximately sizeof(int)*CHAR_BIT + 1, so it's small and compile-time constant. (We use this much space with base=2 and all the bits set to 1.)
#C89, signed int, table as an implicit-length C string, 76 bytes
B;char*f(x,I,O)char*I,*O;{B=strlen(I);for(*O=0;x;x/=B)*--O=I[x%B];return O;} This is the same thing but the input is an implicit-length string so we have to find the length ourselves.