Four is the number of letters in the ...: Difference between revisions

C - reduce memory usage
(Performance improvement)
(C - reduce memory usage)
Line 136:
}
 
typedef struct string_tagstring_buffer_tag {
#define SHORT_STRING_MAX 16
 
typedef struct string_tag {
size_t size;
size_t capacity;
unionchar* {string;
} string_buffer;
char buffer[SHORT_STRING_MAX];
char* ptr;
} str;
} string_t;
 
void string_createstring_buffer_create(string_tstring_buffer* sbuffer, constsize_t char* strcapacity) {
size_t lenbuffer->size = strlen(str)0;
size_t buffer->capacity = len + 1capacity;
ifbuffer->string = xmalloc(SHORT_STRING_MAX < capacity) {;
s->str.ptr = xmalloc(capacity);
s->capacity = capacity;
memcpy(s->str.ptr, str, len + 1);
} else {
s->capacity = SHORT_STRING_MAX;
memcpy(s->str.buffer, str, len + 1);
}
s->size = len;
}
 
void string_destroystring_buffer_destroy(string_tstring_buffer* sbuffer) {
free(sbuffer->str.ptrstring);
if (s->capacity > SHORT_STRING_MAX)
buffer->string = NULL;
free(s->str.ptr);
sbuffer->size = 0;
sbuffer->capacity = 0;
}
 
void string_buffer_clear(string_buffer* buffer) {
void string_append(string_t* s, const char* str) {
size_t lenbuffer->size = strlen(str)0;
size_t min_capacity = len + s->size + 1;
 
if (s->capacity < min_capacity) {
void string_buffer_append(string_buffer* buffer, const char* str, size_t len) {
size_t new_capacity = 2 * s->capacity;
size_t min_capacity = len + sbuffer->size + len + 1;
if s(buffer->capacity =< capacity;min_capacity) {
size_t new_capacity = 2 5* sbuffer->capacity/4;
if (new_capacity < min_capacity)
new_capacity = min_capacity;
if (sbuffer->capacitystring == SHORT_STRING_MAX)xrealloc(buffer->string, {new_capacity);
char* ptrbuffer->capacity = xmalloc(new_capacity);
memcpy(ptr, s->str.buffer, s->size);
s->str.ptr = ptr;
}
else
s->str.ptr = xrealloc(s->str.ptr, new_capacity);
s->capacity = new_capacity;
}
memcpy(sbuffer->str.string + buffer->size, str, len + 1);
char* dst = s->capacity > SHORT_STRING_MAX ? s->str.ptr : s->str.buffer;
memcpy(dst + sbuffer->size, str,+= len + 1);
s->size += len;
}
 
typedef struct word_tag {
const char* string_cstr(const string_t* s) {
size_t offset;
return s->capacity > SHORT_STRING_MAX ? s->str.ptr : s->str.buffer;
returnsize_t length;
} word;
 
size_t string_length(const string_t* s) {
return s->size;
 
typedef struct word_list_tag {
size_t size;
size_t capacity;
string_tword* words;
}string_buffer str;
} word_list;
 
Line 206 ⟶ 187:
words->size = 0;
words->capacity = capacity;
words->words = xmalloc(capacity * sizeof(string_tword));
string_buffer_create(&words->str, capacity*8);
}
 
void word_list_destroy(word_list* words) {
for string_buffer_destroy(size_t i = 0; i < &words->sizestr); ++i)
string_destroy(&words->words[i]);
free(words->words);
words->words = NULL;
Line 219 ⟶ 200:
 
void word_list_clear(word_list* words) {
for string_buffer_clear(size_t i = 0; i < &words->sizestr); ++i)
string_destroy(&words->words[i]);
words->size = 0;
}
 
string_t*void word_list_append(word_list* words, const char* str) {
size_t offset = words->str.size;
size_t len = strlen(str);
string_buffer_append(&words->str, str, len);
size_t min_capacity = words->size + 1;
if (words->capacity < min_capacity) {
size_t new_capacity = (words->capacity * 35)/24;
if (new_capacity < min_capacity)
new_capacity = min_capacity;
words->words = xrealloc(words->words, new_capacity * sizeof(string_tword));
words->capacity = new_capacity;
}
string_tword* sw = &words->words[words->size++];
sw->sizeoffset += lenoffset;
string_create(s, str);
returnw->length s= len;
 
void string_appendword_list_extend(string_tword_list* swords, const char* str) {
word* w = &words->words[words->size - 1];
size_t len = strlen(str);
sw->sizelength += len;
string_buffer_append(&words->str, str, len);
}
 
Line 247 ⟶ 237:
word_list_append(words, get_small_name(&tens[n/10 - 2], ordinal));
} else {
string_t* str = word_list_append(words, get_small_name(&tens[n/10 - 2], false));
string_appendword_list_extend(strwords, "-");
string_appendword_list_extend(strwords, get_small_name(&small[n % 10], ordinal));
}
count = 1;
Line 268 ⟶ 258:
}
 
size_t count_letters(const string_tword_list* strwords, size_t index) {
const word* w = string_destroy(&words->words[iindex]);
size_t letters = 0;
const char* s = string_cstr(words->str).string + w->offset;
for (size_t i = 0, n = string_length(str)w->length; i < n; ++i) {
if (isalpha((unsigned char)s[i]))
++letters;
Line 288 ⟶ 279:
word_list_append(result, words[i]);
for (size_t i = 1; count > n; ++i) {
n += append_number_name(result, count_letters(&result->words[, i]), false);
word_list_append(result, "in");
word_list_append(result, "the");
Line 294 ⟶ 285:
n += append_number_name(result, i + 1, true);
// Append a comma to the final word
string_appendword_list_extend(&result->words[result->size - 1], ",");
}
}
Line 302 ⟶ 293:
if (n == 0)
return 0;
size_treturn lengthwords->str.size =+ n - 1;
for (size_t i = 0; i < n; ++i)
length += string_length(&words->words[i]);
return length;
}
 
Line 318 ⟶ 306:
if (i != 0)
printf("%c", i % 25 == 0 ? '\n' : ' ');
printf("%'2lu", count_letters(&result.words[, i]));
}
printf("\nSentence length: %'lu\n", sentence_length(&result));
for (n = 1000; n <= 10000000; n *= 10) {
sentence(&result, n);
const string_tword* wordw = &result.words[n - 1];
const char* s = result.str.string + w->offset;
printf("The %'luth word is '%.*s' and has %lu letters. ", n, string_cstr(wordint)w->length, s,
count_letters(word&result, n - 1));
printf("Sentence length: %'lu\n" , sentence_length(&result));
}
1,777

edits