diff --git a/solutions/c/say/1/say.c b/solutions/c/say/1/say.c new file mode 100644 index 0000000..9bfaa96 --- /dev/null +++ b/solutions/c/say/1/say.c @@ -0,0 +1,83 @@ +#include "say.h" +#include +#include +#include +#include + +#define ONE_BILLION ((int64_t)1000000000) +#define RES_BUFFER_SIZE 1024 + +static const char *ones[] = { + "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" +}; + +static const char *teens[] = { + "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", + "seventeen", "eighteen", "nineteen" +}; + +static const char *tens[] = { + "", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety" +}; + +static const char *scales[] = { + "", "thousand", "million", "billion" +}; + +static void append_with_space(char *dest, const char *src) { + if (dest[0] != '\0') strcat(dest, " "); + strcat(dest, src); +} + +static void process_chunk(int n, char *buf) { + if (n >= 100) { + append_with_space(buf, ones[n / 100]); + append_with_space(buf, "hundred"); + n %= 100; + } + if (n >= 10 && n <= 19) { + append_with_space(buf, teens[n - 10]); + } else if (n >= 20) { + append_with_space(buf, tens[n / 10]); + if (n % 10 > 0) { + strcat(buf, "-"); + strcat(buf, ones[n % 10]); + } + } else if (n > 0) { + append_with_space(buf, ones[n]); + } +} +int say(int64_t input, char **ans){ + if (input < 0) return -1; + if (input > 999 * ONE_BILLION) return -1; + + if (input == 0) { + (*ans) = malloc(sizeof("zero")); + if (!(*ans)) return -1; + strcpy(*ans, "zero"); + return 0; + } + + char result[RES_BUFFER_SIZE] = ""; + int64_t divisor = ONE_BILLION; + int scale_idx = 3; + + while (divisor > 0) { + int chunk = (input / divisor) % 1000; + if (chunk > 0) { + char chunk_buf[256] = ""; + process_chunk(chunk, chunk_buf); + append_with_space(result, chunk_buf); + if (scale_idx > 0) { + append_with_space(result, scales[scale_idx]); + } + } + divisor /= 1000; + scale_idx--; + } + + (*ans) = malloc(strlen(result) + 1); + if (!(*ans)) return -1; + strcpy(*ans, result); + return 0; +} diff --git a/solutions/c/say/1/say.h b/solutions/c/say/1/say.h new file mode 100644 index 0000000..c186ccf --- /dev/null +++ b/solutions/c/say/1/say.h @@ -0,0 +1,8 @@ +#ifndef SAY_H +#define SAY_H + +#include + +int say(int64_t input, char **ans); + +#endif