#include <assert.h>
#include <stdlib.h>
#include <string.h>
static char* remove_non_letters(const char* src) {
size_t src_len = strlen(src);
char* res = malloc((src_len + 1) * sizeof(char));
const char* src_it;
char* res_it = res;
for (size_t idx = 0; idx < src_len; idx++) {
src_it = src + idx;
if (*src_it < 97 || *src_it > 122) {
continue;
}
*res_it = *src_it;
res_it++;
}
*res_it = '\0';
return res;
}
static char* replace_start(const char* src, const char* old, const char* new) {
size_t src_len = strlen(src);
size_t old_len = strlen(old);
size_t new_len = strlen(new);
assert(new_len <= old_len);
char* res = malloc((src_len + 1) * sizeof(char));
if (src_len < old_len) {
strcpy(res, src);
return res;
}
if (strncmp(src, old, old_len) == 0) {
strncpy(res, new, new_len);
strncpy(res + new_len, src + old_len, src_len - old_len);
*(res + src_len - old_len + new_len) = '\0';
} else {
strcpy(res, src);
}
return res;
}
static char* replace_end(const char* src, const char* old, const char* new) {
size_t src_len = strlen(src);
size_t old_len = strlen(old);
size_t new_len = strlen(new);
assert(new_len <= old_len);
char* res = malloc((src_len + 1) * sizeof(char));
if (src_len < old_len) {
strcpy(res, src);
return res;
}
strncpy(res, src, src_len - old_len);
if (strncmp(src + src_len - old_len, old, old_len) == 0) {
strncpy(res + src_len - old_len, new, new_len);
*(res + src_len - old_len + new_len) = '\0';
} else {
strncpy(res + src_len - old_len, src + src_len - old_len, old_len);
*(res + src_len) = '\0';
}
return res;
}
static char* replace(const char* src, const char* old, const char* new) {
size_t src_len = strlen(src);
size_t old_len = strlen(old);
size_t new_len = strlen(new);
assert(new_len <= old_len);
char* res = malloc((src_len + 1) * sizeof(char));
if (src_len < old_len) {
strcpy(res, src);
return res;
}
const char* src_it;
char* res_it = res;
for (size_t idx = 0; idx < src_len;) {
src_it = src + idx;
if (strncmp(src_it, old, old_len) == 0) {
strncpy(res_it, new, new_len);
res_it += new_len;
idx += old_len;
} else {
*res_it = *src_it;
res_it++;
idx++;
}
}
*res_it = '\0';
return res;
}
static char* replace_seq(const char* src, const char old, const char* new) {
size_t src_len = strlen(src);
size_t new_len = strlen(new);
char* res = malloc((src_len + 1) * sizeof(char));
const char* src_it;
char* res_it = res;
size_t match_len = 0;
for (size_t idx = 0; idx < src_len;) {
src_it = src + idx;
if (*src_it == old) {
match_len++;
idx++;
} else {
if (match_len > 0) {
strncpy(res_it, new, new_len);
res_it += new_len;
match_len = 0;
}
*res_it = *src_it;
res_it++;
idx++;
}
}
if (match_len > 0) {
strncpy(res_it, new, new_len);
res_it += new_len;
}
*res_it = '\0';
return res;
}
static char* pad(const char* src) {
size_t src_len = strlen(src);
size_t max_len = 10;
char* res = malloc((max_len + 1) * sizeof(char));
strncpy(res, src, max_len);
if (src_len < max_len) {
for (size_t idx = src_len; idx < max_len; idx++) {
*(res + idx) = '1';
}
}
*(res + max_len) = '\0';
return res;
}
static char* step(char* res, char* src) {
free(src);
return res;
}
char* caverphone(const char* src) {
assert(src != NULL);
char* res = malloc((strlen(src) + 1) * sizeof(char));
if (src == 0 || *src == '\0') {
res[0] = '\0';
return res;
}
strcpy(res, src);
res = step(remove_non_letters((const char*)res), res);
res = step(replace_end((const char*)res, "e", ""), res);
res = step(replace_start((const char*)res, "cough", "cou2f"), res);
res = step(replace_start((const char*)res, "rough", "rou2f"), res);
res = step(replace_start((const char*)res, "tough", "tou2f"), res);
res = step(replace_start((const char*)res, "enough", "enou2f"), res);
res = step(replace_start((const char*)res, "trough", "trou2f"), res);
res = step(replace_start((const char*)res, "gn", "2n"), res);
res = step(replace_end((const char*)res, "mb", "m2"), res);
res = step(replace((const char*)res, "cq", "2q"), res);
res = step(replace((const char*)res, "ci", "si"), res);
res = step(replace((const char*)res, "ce", "se"), res);
res = step(replace((const char*)res, "cy", "sy"), res);
res = step(replace((const char*)res, "tch", "2ch"), res);
res = step(replace((const char*)res, "c", "k"), res);
res = step(replace((const char*)res, "q", "k"), res);
res = step(replace((const char*)res, "x", "k"), res);
res = step(replace((const char*)res, "v", "f"), res);
res = step(replace((const char*)res, "dg", "2g"), res);
res = step(replace((const char*)res, "tio", "sio"), res);
res = step(replace((const char*)res, "tia", "sia"), res);
res = step(replace((const char*)res, "d", "t"), res);
res = step(replace((const char*)res, "ph", "fh"), res);
res = step(replace((const char*)res, "b", "p"), res);
res = step(replace((const char*)res, "sh", "s2"), res);
res = step(replace((const char*)res, "z", "s"), res);
res = step(replace_start((const char*)res, "a", "A"), res);
res = step(replace_start((const char*)res, "e", "A"), res);
res = step(replace_start((const char*)res, "i", "A"), res);
res = step(replace_start((const char*)res, "o", "A"), res);
res = step(replace_start((const char*)res, "u", "A"), res);
res = step(replace((const char*)res, "a", "3"), res);
res = step(replace((const char*)res, "e", "3"), res);
res = step(replace((const char*)res, "i", "3"), res);
res = step(replace((const char*)res, "o", "3"), res);
res = step(replace((const char*)res, "u", "3"), res);
res = step(replace((const char*)res, "j", "y"), res);
res = step(replace_start((const char*)res, "y3", "Y3"), res);
res = step(replace_start((const char*)res, "y", "A"), res);
res = step(replace((const char*)res, "y", "3"), res);
res = step(replace((const char*)res, "3gh3", "3kh3"), res);
res = step(replace((const char*)res, "gh", "22"), res);
res = step(replace((const char*)res, "g", "k"), res);
res = step(replace_seq((const char*)res, 's', "S"), res);
res = step(replace_seq((const char*)res, 't', "T"), res);
res = step(replace_seq((const char*)res, 'p', "P"), res);
res = step(replace_seq((const char*)res, 'k', "K"), res);
res = step(replace_seq((const char*)res, 'f', "F"), res);
res = step(replace_seq((const char*)res, 'm', "M"), res);
res = step(replace_seq((const char*)res, 'n', "N"), res);
res = step(replace((const char*)res, "w3", "W3"), res);
res = step(replace((const char*)res, "wh3", "Wh3"), res);
res = step(replace_end((const char*)res, "w", "3"), res);
res = step(replace((const char*)res, "w", "2"), res);
res = step(replace_start((const char*)res, "h", "A"), res);
res = step(replace((const char*)res, "h", "2"), res);
res = step(replace((const char*)res, "r3", "R3"), res);
res = step(replace_end((const char*)res, "r", "3"), res);
res = step(replace((const char*)res, "r", "2"), res);
res = step(replace((const char*)res, "l3", "L3"), res);
res = step(replace_end((const char*)res, "l", "3"), res);
res = step(replace((const char*)res, "l", "2"), res);
res = step(replace((const char*)res, "2", ""), res);
res = step(replace_end((const char*)res, "3", "A"), res);
res = step(replace((const char*)res, "3", ""), res);
res = step(pad((const char*)res), res);
return res;
}