Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions solutions/c/say/1/say.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#include "say.h"
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#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;
}
8 changes: 8 additions & 0 deletions solutions/c/say/1/say.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef SAY_H
#define SAY_H

#include <stdint.h>

int say(int64_t input, char **ans);

#endif