Skip to main content
Commonmark migration
Source Link

#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

C89, signed 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

C89, limited-range signed int n, 64 53 bytes

C89, signed int, table as an implicit-length C string, 65 bytes

save bytes by passing a pointer by reference.
Source Link
Peter Cordes
  • 5.1k
  • 1
  • 24
  • 35

#C89, limited-range signed int n, 6464 53 bytes

  • changelog: take a 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

  • changelog: take a 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];} 
Source Link
Peter Cordes
  • 5.1k
  • 1
  • 24
  • 35

#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.