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
79 changes: 79 additions & 0 deletions solutions/c/pig-latin/1/pig_latin.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#include "pig_latin.h"
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

static size_t capacity;
static inline bool expand(char **p);
static inline bool is_vowel(unsigned char c);
static size_t consonant_cluster(const char *s);

char *translate(const char *phrase){
if (!phrase) return NULL;

size_t len = strlen(phrase);
capacity = len << 1;
char *res = calloc(capacity, 1);
if (!res) return NULL;

size_t out = 0;

for (size_t i = 0; i < len; ){
size_t start = i;
while (i < len && phrase[i] != ' ') i++;
size_t wlen = i - start;

const char *w = phrase + start;
size_t cut = 0;

char f = tolower(w[0]);
char s = wlen > 1 ? tolower(w[1]) : 0;

if (!(is_vowel(f) || (f=='x'&&s=='r') || (f=='y'&&s=='t')))
cut = consonant_cluster(w);

if (out + wlen + 2 + 1 >= capacity)
if (!expand(&res)) { free(res); return NULL; }

memcpy(res + out, w + cut, wlen - cut);
out += wlen - cut;
memcpy(res + out, w, cut);
out += cut;
res[out++] = 'a';
res[out++] = 'y';

if (i < len) res[out++] = ' ';
i++;
}

res[out] = 0;
return res;
}

static inline bool expand(char **p){
capacity <<= 1;
char *t = realloc(*p, capacity);
if (!t) return false;
*p = t;
return true;
}

static inline bool is_vowel(unsigned char c){
c = tolower(c);
return c=='a'||c=='e'||c=='i'||c=='o'||c=='u';
}

static size_t consonant_cluster(const char *s){
size_t i = 0;
while (s[i]){
if (is_vowel(s[i])) break;
if (i > 0 && tolower(s[i]) == 'y') break;
if (tolower(s[i]) == 'q' && tolower(s[i+1]) == 'u'){
i += 2;
continue;
}
i++;
}
return i;
}
6 changes: 6 additions & 0 deletions solutions/c/pig-latin/1/pig_latin.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef PIG_LATIN_H
#define PIG_LATIN_H

char *translate(const char *phrase);

#endif