Finish c_impl of problem solution
This commit is contained in:
parent
449ad303f1
commit
1fdf5e14b7
|
@ -14,7 +14,6 @@ void printHelp() {
|
|||
}
|
||||
|
||||
typedef struct Sequence {
|
||||
unsigned long long idx;
|
||||
unsigned char *buf;
|
||||
size_t buf_size;
|
||||
size_t buf_end;
|
||||
|
@ -39,35 +38,48 @@ void doubleIndBuf(Sequence *seq) {
|
|||
seq->indices_size *= 2;
|
||||
}
|
||||
|
||||
void nextSeqItem(Sequence *seq) {
|
||||
if(seq->buf_end > seq->buf_size) {
|
||||
puts("ERROR: Sequence in invalid state!");
|
||||
return;
|
||||
} else if(seq->buf_end == seq->buf_size) {
|
||||
doubleSeqBuf(seq);
|
||||
int nextSeqItem(Sequence *seq) {
|
||||
if(seq->indices[seq->indices_end] == 0) {
|
||||
size_t idx = seq->indices[seq->indices_end - 1] + 1;
|
||||
for(; idx < seq->buf_size && seq->buf[idx] != 0; ++idx) {
|
||||
if(seq->buf[idx] == 't' || seq->buf[idx] == 'T') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(seq->buf[idx] != 't' && seq->buf[idx] != 'T') {
|
||||
puts("ERROR: Invalid state!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
seq->indices[seq->indices_end++] = idx;
|
||||
const char *next_str = numberToString(idx + 1);
|
||||
size_t next_str_size = strlen(next_str);
|
||||
while(seq->buf_end + next_str_size + 1 >= seq->buf_size) {
|
||||
doubleSeqBuf(seq);
|
||||
}
|
||||
memcpy(seq->buf + seq->buf_end, next_str, next_str_size);
|
||||
seq->buf_end += next_str_size;
|
||||
free((void*)next_str);
|
||||
}
|
||||
|
||||
if(seq->buf_end == 0 || seq->indices_end == 0) {
|
||||
puts("ERROR: Sequence is zero sized, this should not be possible!");
|
||||
return;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Sequence initSequence() {
|
||||
Sequence seq;
|
||||
seq.idx = 0;
|
||||
seq.buf = calloc(INIT_SEQ_BUF_SIZE, 1);
|
||||
seq.buf_size = INIT_SEQ_BUF_SIZE;
|
||||
seq.buf_end = 0;
|
||||
seq.indices = malloc(sizeof(unsigned long long) * INIT_SEQ_IND_SIZE);
|
||||
seq.indices = calloc(sizeof(unsigned long long), INIT_SEQ_IND_SIZE);
|
||||
seq.indices_size = INIT_SEQ_IND_SIZE;
|
||||
// seq.indices_end = 0; initialized later on
|
||||
|
||||
while(seq.indices_size < 3) {
|
||||
doubleIndBuf(&seq);
|
||||
}
|
||||
seq.indices[0] = 1;
|
||||
seq.indices[1] = 4;
|
||||
seq.indices[2] = 11;
|
||||
seq.indices[0] = 0;
|
||||
seq.indices[1] = 3;
|
||||
seq.indices[2] = 10;
|
||||
seq.indices_end = 3;
|
||||
|
||||
size_t startingLength = strlen(STARTING_SEQ);
|
||||
|
@ -119,5 +131,22 @@ int main(int argc, char **argv) {
|
|||
|
||||
printf("Got input count == %llu\n", count);
|
||||
|
||||
// const char *nString = numberToString(count);
|
||||
// printf("Test string of number is %s\n", nString);
|
||||
// free((void*)nString);
|
||||
|
||||
Sequence seq = initSequence();
|
||||
while(seq.indices_end < count) {
|
||||
nextSeqItem(&seq);
|
||||
}
|
||||
|
||||
printf("String is %s\n", seq.buf);
|
||||
|
||||
for(size_t i = 0; i < seq.indices_end; ++i) {
|
||||
printf("%llu ", seq.indices[i] + 1);
|
||||
}
|
||||
puts("");
|
||||
|
||||
cleanupSequence(&seq);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "numberToString.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void doubleBufSize(char **buf, size_t *buf_size) {
|
||||
char *newBuf = calloc(2, *buf_size);
|
||||
memcpy(newBuf, *buf, *buf_size);
|
||||
|
@ -8,249 +10,394 @@ void doubleBufSize(char **buf, size_t *buf_size) {
|
|||
*buf_size *= 2;
|
||||
}
|
||||
|
||||
// TODO logic is convoluted here
|
||||
void thousandToString(char **buf, size_t *buf_idx, size_t *buf_size, unsigned long long t, int last) {
|
||||
t = t % 1000;
|
||||
if(t == 0) {
|
||||
return;
|
||||
NumToken * doubleTokensBuf(NumToken *tokens, size_t *tokens_size) {
|
||||
NumToken *newTokens = calloc(sizeof(NumToken), *tokens_size * 2);
|
||||
memcpy(newTokens + *tokens_size, tokens, sizeof(NumToken) * *tokens_size);
|
||||
free(tokens);
|
||||
*tokens_size *= 2;
|
||||
return newTokens;
|
||||
}
|
||||
|
||||
NumToken * numberToTokens(unsigned long long n, size_t *tokens_size_out) {
|
||||
size_t tokens_size = INIT_SEQ_NUM_TOKENS_SIZE;
|
||||
*tokens_size_out = tokens_size;
|
||||
NumToken *tokens = calloc(sizeof(NumToken), tokens_size);
|
||||
size_t ridx = tokens_size - 1;
|
||||
if(ridx >= tokens_size) {
|
||||
puts("ERROR: Should not be in invalid state");
|
||||
free(tokens);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t size;
|
||||
if(t >= 100) {
|
||||
switch(t / 100) {
|
||||
case 1:
|
||||
size = strlen(ONE HUNDRED);
|
||||
if(size >= *buf_idx + *buf_size) {
|
||||
doubleBufSize(buf, buf_size);
|
||||
unsigned long long temp;
|
||||
unsigned long long temp_suffix = 0;
|
||||
char is_first = 1;
|
||||
while(n > 0) {
|
||||
temp = n % 1000;
|
||||
if(temp % 10 > 0) {
|
||||
tokens[ridx].suffix = temp_suffix;
|
||||
tokens[ridx].value = temp % 10;
|
||||
if(is_first) {
|
||||
tokens[ridx].flags |= 1;
|
||||
is_first = 0;
|
||||
}
|
||||
memcpy((*buf) + *buf_idx, ONE HUNDRED, size);
|
||||
*buf_idx += size;
|
||||
break;
|
||||
case 2:
|
||||
size = strlen(TWO HUNDRED);
|
||||
if(size >= *buf_idx + *buf_size) {
|
||||
doubleBufSize(buf, buf_size);
|
||||
if(ridx > 0) {
|
||||
--ridx;
|
||||
} else {
|
||||
tokens = doubleTokensBuf(tokens, &tokens_size);
|
||||
ridx = tokens_size / 2 - 1;
|
||||
*tokens_size_out = tokens_size;
|
||||
}
|
||||
memcpy((*buf) + *buf_idx, TWO HUNDRED, size);
|
||||
*buf_idx += size;
|
||||
break;
|
||||
case 3:
|
||||
size = strlen(THREE HUNDRED);
|
||||
if(size >= *buf_idx + *buf_size) {
|
||||
doubleBufSize(buf, buf_size);
|
||||
}
|
||||
if((temp / 10) % 10 > 0) {
|
||||
if(ridx + 1 < tokens_size
|
||||
&& (temp / 10) % 10 == 1
|
||||
&& tokens[ridx + 1].value > 0
|
||||
&& tokens[ridx + 1].value <= 9) {
|
||||
tokens[ridx + 1].value += 10;
|
||||
} else {
|
||||
tokens[ridx].suffix = temp_suffix;
|
||||
tokens[ridx].value = ((temp / 10) % 10) * 10;
|
||||
if(is_first) {
|
||||
tokens[ridx].flags |= 1;
|
||||
is_first = 0;
|
||||
}
|
||||
if(ridx > 0) {
|
||||
--ridx;
|
||||
} else {
|
||||
tokens = doubleTokensBuf(tokens, &tokens_size);
|
||||
ridx = tokens_size / 2 - 1;
|
||||
*tokens_size_out = tokens_size;
|
||||
}
|
||||
}
|
||||
memcpy((*buf) + *buf_idx, THREE HUNDRED, size);
|
||||
*buf_idx += size;
|
||||
break;
|
||||
case 4:
|
||||
size = strlen(FOUR HUNDRED);
|
||||
if(size >= *buf_idx + *buf_size) {
|
||||
doubleBufSize(buf, buf_size);
|
||||
}
|
||||
if((temp / 100) % 10 > 0) {
|
||||
tokens[ridx].suffix = temp_suffix;
|
||||
tokens[ridx].value = ((temp / 100) % 10) * 100;
|
||||
if(is_first) {
|
||||
tokens[ridx].flags |= 1;
|
||||
is_first = 0;
|
||||
}
|
||||
memcpy((*buf) + *buf_idx, FOUR HUNDRED, size);
|
||||
*buf_idx += size;
|
||||
break;
|
||||
case 5:
|
||||
size = strlen(FIVE HUNDRED);
|
||||
if(size >= *buf_idx + *buf_size) {
|
||||
doubleBufSize(buf, buf_size);
|
||||
if(ridx > 0) {
|
||||
--ridx;
|
||||
} else {
|
||||
tokens = doubleTokensBuf(tokens, &tokens_size);
|
||||
ridx = tokens_size / 2 - 1;
|
||||
*tokens_size_out = tokens_size;
|
||||
}
|
||||
memcpy((*buf) + *buf_idx, FIVE HUNDRED, size);
|
||||
*buf_idx += size;
|
||||
break;
|
||||
case 6:
|
||||
size = strlen(SIX HUNDRED);
|
||||
if(size >= *buf_idx + *buf_size) {
|
||||
doubleBufSize(buf, buf_size);
|
||||
}
|
||||
if(temp_suffix == 0) {
|
||||
temp_suffix = 1000;
|
||||
} else {
|
||||
temp_suffix *= 1000;
|
||||
}
|
||||
n /= 1000;
|
||||
}
|
||||
|
||||
return tokens;
|
||||
}
|
||||
|
||||
void appendStringToBuf(char **buf, size_t *buf_idx, size_t *buf_size, const char *str) {
|
||||
size_t str_size = strlen(str);
|
||||
while(*buf_idx + str_size + 1 >= *buf_size) {
|
||||
doubleBufSize(buf, buf_size);
|
||||
}
|
||||
|
||||
memcpy((*buf) + *buf_idx, str, str_size);
|
||||
*buf_idx += str_size;
|
||||
}
|
||||
|
||||
const char * tokensToString(NumToken *tokens, size_t tokens_size) {
|
||||
char *buf = calloc(1, INIT_SEQ_BUF_SIZE);
|
||||
size_t buf_size = INIT_SEQ_BUF_SIZE;
|
||||
size_t buf_idx = 0;
|
||||
for(size_t i = 0; i < tokens_size; ++i) {
|
||||
if(tokens[i].value == 0 && tokens[i].suffix == 0) {
|
||||
continue;
|
||||
}
|
||||
if(i > 0 && tokens[i].suffix != tokens[i - 1].suffix) {
|
||||
if(tokens[i - 1].suffix != 0) {
|
||||
switch(tokens[i - 1].suffix) {
|
||||
case 1000000000000:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, TRILLION);
|
||||
break;
|
||||
case 1000000000:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, BILLION);
|
||||
break;
|
||||
case 1000000:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, MILLION);
|
||||
break;
|
||||
case 1000:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, THOUSAND);
|
||||
break;
|
||||
default:
|
||||
puts("ERROR: Unreachable");
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
memcpy((*buf) + *buf_idx, SIX HUNDRED, size);
|
||||
*buf_idx += size;
|
||||
break;
|
||||
case 7:
|
||||
size = strlen(SEVEN HUNDRED);
|
||||
if(size >= *buf_idx + *buf_size) {
|
||||
doubleBufSize(buf, buf_size);
|
||||
}
|
||||
if(i + 1 == tokens_size && (tokens[i].flags & 1)) {
|
||||
switch(tokens[i].value) {
|
||||
case 1:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, FIRST);
|
||||
break;
|
||||
case 2:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, SECOND);
|
||||
break;
|
||||
case 3:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, THIRD);
|
||||
break;
|
||||
case 4:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, FOURTH);
|
||||
break;
|
||||
case 5:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, FIFTH);
|
||||
break;
|
||||
case 6:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, SIXTH);
|
||||
break;
|
||||
case 7:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, SEVENTH);
|
||||
break;
|
||||
case 8:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, EIGHTH);
|
||||
break;
|
||||
case 9:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, NINTH);
|
||||
break;
|
||||
case 10:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, TENTH);
|
||||
break;
|
||||
case 11:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, ELEVENTH);
|
||||
break;
|
||||
case 12:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, TWELFTH);
|
||||
break;
|
||||
case 13:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, THIRTEENTH);
|
||||
break;
|
||||
case 14:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, FOURTEENTH);
|
||||
break;
|
||||
case 15:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, FIFTEENTH);
|
||||
break;
|
||||
case 16:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, SIXTEENTH);
|
||||
break;
|
||||
case 17:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, SEVENTEENTH);
|
||||
break;
|
||||
case 18:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, EIGHTEENTH);
|
||||
break;
|
||||
case 19:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, NINETEENTH);
|
||||
break;
|
||||
case 20:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, TWENTIETH);
|
||||
break;
|
||||
case 30:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, THIRTIETH);
|
||||
break;
|
||||
case 40:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, FOURTIETH);
|
||||
break;
|
||||
case 50:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, FIFTIETH);
|
||||
break;
|
||||
case 60:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, SIXTIETH);
|
||||
break;
|
||||
case 70:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, SEVENTIETH);
|
||||
break;
|
||||
case 80:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, EIGHTIETH);
|
||||
break;
|
||||
case 90:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, NINETIETH);
|
||||
break;
|
||||
case 100:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, ONE HUNDREDTH);
|
||||
break;
|
||||
case 200:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, TWO HUNDREDTH);
|
||||
break;
|
||||
case 300:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, THREE HUNDREDTH);
|
||||
break;
|
||||
case 400:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, FOUR HUNDREDTH);
|
||||
break;
|
||||
case 500:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, FIVE HUNDREDTH);
|
||||
break;
|
||||
case 600:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, SIX HUNDREDTH);
|
||||
break;
|
||||
case 700:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, SEVEN HUNDREDTH);
|
||||
break;
|
||||
case 800:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, EIGHT HUNDREDTH);
|
||||
break;
|
||||
case 900:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, NINE HUNDREDTH);
|
||||
break;
|
||||
default:
|
||||
puts("ERROR: Unreachable");
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
memcpy((*buf) + *buf_idx, SEVEN HUNDRED, size);
|
||||
*buf_idx += size;
|
||||
break;
|
||||
case 8:
|
||||
size = strlen(EIGHT HUNDRED);
|
||||
if(size >= *buf_idx + *buf_size) {
|
||||
doubleBufSize(buf, buf_size);
|
||||
} else {
|
||||
switch(tokens[i].value) {
|
||||
case 1:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, ONE);
|
||||
break;
|
||||
case 2:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, TWO);
|
||||
break;
|
||||
case 3:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, THREE);
|
||||
break;
|
||||
case 4:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, FOUR);
|
||||
break;
|
||||
case 5:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, FIVE);
|
||||
break;
|
||||
case 6:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, SIX);
|
||||
break;
|
||||
case 7:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, SEVEN);
|
||||
break;
|
||||
case 8:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, EIGHT);
|
||||
break;
|
||||
case 9:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, NINE);
|
||||
break;
|
||||
case 10:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, TEN);
|
||||
break;
|
||||
case 11:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, ELEVEN);
|
||||
break;
|
||||
case 12:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, TWELVE);
|
||||
break;
|
||||
case 13:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, THIRTEEN);
|
||||
break;
|
||||
case 14:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, FOURTEEN);
|
||||
break;
|
||||
case 15:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, FIFTEEN);
|
||||
break;
|
||||
case 16:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, SIXTEEN);
|
||||
break;
|
||||
case 17:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, SEVENTEEN);
|
||||
break;
|
||||
case 18:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, EIGHTEEN);
|
||||
break;
|
||||
case 19:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, NINETEEN);
|
||||
break;
|
||||
case 20:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, TWENTY);
|
||||
break;
|
||||
case 30:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, THIRTY);
|
||||
break;
|
||||
case 40:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, FOURTY);
|
||||
break;
|
||||
case 50:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, FIFTY);
|
||||
break;
|
||||
case 60:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, SIXTY);
|
||||
break;
|
||||
case 70:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, SEVENTY);
|
||||
break;
|
||||
case 80:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, EIGHTY);
|
||||
break;
|
||||
case 90:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, NINETY);
|
||||
break;
|
||||
case 100:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, ONE HUNDRED);
|
||||
break;
|
||||
case 200:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, TWO HUNDRED);
|
||||
break;
|
||||
case 300:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, THREE HUNDRED);
|
||||
break;
|
||||
case 400:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, FOUR HUNDRED);
|
||||
break;
|
||||
case 500:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, FIVE HUNDRED);
|
||||
break;
|
||||
case 600:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, SIX HUNDRED);
|
||||
break;
|
||||
case 700:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, SEVEN HUNDRED);
|
||||
break;
|
||||
case 800:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, EIGHT HUNDRED);
|
||||
break;
|
||||
case 900:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, NINE HUNDRED);
|
||||
break;
|
||||
default:
|
||||
puts("ERROR: Unreachable");
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
memcpy((*buf) + *buf_idx, EIGHT HUNDRED, size);
|
||||
*buf_idx += size;
|
||||
break;
|
||||
case 9:
|
||||
size = strlen(NINE HUNDRED);
|
||||
if(size >= *buf_idx + *buf_size) {
|
||||
doubleBufSize(buf, buf_size);
|
||||
}
|
||||
memcpy((*buf) + *buf_idx, NINE HUNDRED, size);
|
||||
*buf_idx += size;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if((t % 100) >= 10) {
|
||||
switch((t % 100) / 10) {
|
||||
case 1:
|
||||
if(t % 10 > 0) {
|
||||
if((t % 10) > 0) {
|
||||
switch(t % 10) {
|
||||
case 1:
|
||||
size = strlen(ELEVENTH);
|
||||
if(size >= *buf_idx + *buf_size) {
|
||||
doubleBufSize(buf, buf_size);
|
||||
}
|
||||
memcpy((*buf) + *buf_idx, ELEVENTH, size);
|
||||
*buf_idx += size;
|
||||
break;
|
||||
case 2:
|
||||
size = strlen(TWELFTH);
|
||||
if(size >= *buf_idx + *buf_size) {
|
||||
doubleBufSize(buf, buf_size);
|
||||
}
|
||||
memcpy((*buf) + *buf_idx, TWELFTH, size);
|
||||
*buf_idx += size;
|
||||
break;
|
||||
case 3:
|
||||
size = strlen(THIRTEENTH);
|
||||
if(size >= *buf_idx + *buf_size) {
|
||||
doubleBufSize(buf, buf_size);
|
||||
}
|
||||
memcpy((*buf) + *buf_idx, THIRTEENTH, size);
|
||||
*buf_idx += size;
|
||||
break;
|
||||
case 4:
|
||||
size = strlen(FOURTEENTH);
|
||||
if(size >= *buf_idx + *buf_size) {
|
||||
doubleBufSize(buf, buf_size);
|
||||
}
|
||||
memcpy((*buf) + *buf_idx, FOURTEENTH, size);
|
||||
*buf_idx += size;
|
||||
break;
|
||||
case 5:
|
||||
size = strlen(FIFTEENTH);
|
||||
if(size >= *buf_idx + *buf_size) {
|
||||
doubleBufSize(buf, buf_size);
|
||||
}
|
||||
memcpy((*buf) + *buf_idx, FIFTEENTH, size);
|
||||
*buf_idx += size;
|
||||
break;
|
||||
case 6:
|
||||
size = strlen(SIXTEENTH);
|
||||
if(size >= *buf_idx + *buf_size) {
|
||||
doubleBufSize(buf, buf_size);
|
||||
}
|
||||
memcpy((*buf) + *buf_idx, SIXTEENTH, size);
|
||||
*buf_idx += size;
|
||||
break;
|
||||
case 7:
|
||||
size = strlen(SEVENTEENTH);
|
||||
if(size >= *buf_idx + *buf_size) {
|
||||
doubleBufSize(buf, buf_size);
|
||||
}
|
||||
memcpy((*buf) + *buf_idx, SEVENTEENTH, size);
|
||||
*buf_idx += size;
|
||||
break;
|
||||
case 8:
|
||||
size = strlen(EIGHTEENTH);
|
||||
if(size >= *buf_idx + *buf_size) {
|
||||
doubleBufSize(buf, buf_size);
|
||||
}
|
||||
memcpy((*buf) + *buf_idx, EIGHTEENTH, size);
|
||||
*buf_idx += size;
|
||||
break;
|
||||
case 9:
|
||||
size = strlen(NINETEENTH);
|
||||
if(size >= *buf_idx + *buf_size) {
|
||||
doubleBufSize(buf, buf_size);
|
||||
}
|
||||
memcpy((*buf) + *buf_idx, NINETEENTH, size);
|
||||
*buf_idx += size;
|
||||
break;
|
||||
default:
|
||||
puts("ERROR: Unreachable");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
size = strlen(TEN);
|
||||
if(size >= *buf_idx + *buf_size) {
|
||||
doubleBufSize(buf, buf_size);
|
||||
}
|
||||
memcpy((*buf) + *buf_idx, TEN, size);
|
||||
*buf_idx += size;
|
||||
}
|
||||
|
||||
if(tokens[tokens_size - 1].suffix > 0) {
|
||||
switch(tokens[tokens_size - 1].suffix) {
|
||||
case 1000000000000:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, TRILLIONTH);
|
||||
break;
|
||||
case 2:
|
||||
case 1000000000:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, BILLIONTH);
|
||||
break;
|
||||
case 3:
|
||||
case 1000000:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, MILLIONTH);
|
||||
break;
|
||||
case 4:
|
||||
break;
|
||||
case 5:
|
||||
break;
|
||||
case 6:
|
||||
break;
|
||||
case 7:
|
||||
break;
|
||||
case 8:
|
||||
break;
|
||||
case 9:
|
||||
case 1000:
|
||||
appendStringToBuf(&buf, &buf_idx, &buf_size, THOUSANDTH);
|
||||
break;
|
||||
default:
|
||||
puts("ERROR: Unreachable");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if((t % 10) > 0) {
|
||||
switch(t % 10) {
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
break;
|
||||
case 3:
|
||||
break;
|
||||
case 4:
|
||||
break;
|
||||
case 5:
|
||||
break;
|
||||
case 6:
|
||||
break;
|
||||
case 7:
|
||||
break;
|
||||
case 8:
|
||||
break;
|
||||
case 9:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
const char * numberToString(unsigned long long n) {
|
||||
char *buf = calloc(1, INIT_SEQ_NUM_TO_STR_SIZE);
|
||||
size_t buf_idx = 0;
|
||||
size_t buf_size = INIT_SEQ_NUM_TO_STR_SIZE;
|
||||
|
||||
if(n / 1000000000000 > 0) {
|
||||
}
|
||||
if((n % 1000000000000) / 1000000000 > 0) {
|
||||
}
|
||||
if((n % 1000000000) / 1000000 > 0) {
|
||||
}
|
||||
if((n % 1000000) / 1000 > 0) {
|
||||
}
|
||||
if((n % 1000) / 100 > 0) {
|
||||
}
|
||||
if((n % 100) / 10 > 0) {
|
||||
}
|
||||
if(n % 10) {
|
||||
}
|
||||
size_t tokens_size;
|
||||
NumToken *tokens = numberToTokens(n, &tokens_size);
|
||||
const char *str = tokensToString(tokens, tokens_size);
|
||||
free(tokens);
|
||||
return str;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define INIT_SEQ_BUF_SIZE 1024
|
||||
#define INIT_SEQ_NUM_TO_STR_SIZE 128
|
||||
#define INIT_SEQ_NUM_TOKENS_SIZE 8
|
||||
|
||||
#define FIRST "first"
|
||||
#define SECOND "second"
|
||||
|
@ -14,7 +16,7 @@
|
|||
#define SIXTH "sixth"
|
||||
#define SEVENTH "seventh"
|
||||
#define EIGHTH "eighth"
|
||||
#define NINTH "ningth"
|
||||
#define NINTH "ninth"
|
||||
#define TENTH "tenth"
|
||||
|
||||
#define ELEVENTH "eleventh"
|
||||
|
@ -39,6 +41,16 @@
|
|||
#define NINE "nine"
|
||||
#define TEN "ten"
|
||||
|
||||
#define ELEVEN "eleven"
|
||||
#define TWELVE "twelve"
|
||||
#define THIRTEEN "thirteen"
|
||||
#define FOURTEEN "fourteen"
|
||||
#define FIFTEEN "fifteen"
|
||||
#define SIXTEEN "sixteen"
|
||||
#define SEVENTEEN "seventeen"
|
||||
#define EIGHTEEN "eighteen"
|
||||
#define NINETEEN "nineteen"
|
||||
|
||||
#define TWENTY "twenty"
|
||||
#define THIRTY "thirty"
|
||||
#define FOURTY "fourty"
|
||||
|
@ -49,7 +61,7 @@
|
|||
#define NINETY "ninety"
|
||||
|
||||
#define TWENTIETH "twentieth"
|
||||
#define THRITIETH "thirtieth"
|
||||
#define THIRTIETH "thirtieth"
|
||||
#define FOURTIETH "fourtieth"
|
||||
#define FIFTIETH "fiftieth"
|
||||
#define SIXTIETH "sixtieth"
|
||||
|
@ -69,14 +81,30 @@
|
|||
#define BILLIONTH "billionth"
|
||||
#define TRILLIONTH "trillionth"
|
||||
|
||||
void doubleBufSize(char **buf, size_t *buf_size);
|
||||
|
||||
void thousandToString(char **buf, size_t *buf_idx, size_t *buf_size, unsigned long long t, int last);
|
||||
typedef struct NumToken {
|
||||
unsigned long long value;
|
||||
unsigned long long suffix;
|
||||
char flags; // 0b0001 - last value
|
||||
} NumToken;
|
||||
|
||||
/*!
|
||||
* \brief Returns a word-based number string from the input number.
|
||||
* \brief Convert a number to tokens
|
||||
*
|
||||
* \warning The returned pointer must be free'd eventually.
|
||||
* \warning The returned pointer must be eventually free'd
|
||||
*/
|
||||
NumToken * numberToTokens(unsigned long long n, size_t *tokens_size);
|
||||
|
||||
/*!
|
||||
* \brief Convert tokens to a string
|
||||
*
|
||||
* \warning The returned pointer must be eventually free'd
|
||||
*/
|
||||
const char * tokensToString(NumToken *tokens, size_t tokens_size);
|
||||
|
||||
/*!
|
||||
* \brief Convert a number to a string
|
||||
*
|
||||
* \warning The returned pointer must be eventually free'd
|
||||
*/
|
||||
const char * numberToString(unsigned long long n);
|
||||
|
||||
|
|
Loading…
Reference in a new issue