Four is the number of letters in the ...: Difference between revisions
Content added Content deleted
(C - reduce memory usage) |
(C - use GLib) |
||
Line 51: | Line 51: | ||
=={{header|C}}== |
=={{header|C}}== |
||
{{libheader|GLib}} |
|||
<lang c>#include <ctype.h> |
<lang c>#include <ctype.h> |
||
#include <locale.h> |
#include <locale.h> |
||
Line 56: | Line 57: | ||
#include <stdio.h> |
#include <stdio.h> |
||
#include <stdint.h> |
#include <stdint.h> |
||
#include < |
#include <glib.h> |
||
#include <string.h> |
|||
typedef uint64_t integer; |
typedef uint64_t integer; |
||
Line 115: | Line 115: | ||
} |
} |
||
return &named_numbers[names_len - 1]; |
return &named_numbers[names_len - 1]; |
||
⚫ | |||
void fatal(const char* message) { |
|||
fprintf(stderr, "%s\n", message); |
|||
exit(1); |
|||
} |
|||
void* xmalloc(size_t n) { |
|||
void* ptr = malloc(n); |
|||
if (ptr == NULL) |
|||
fatal("Out of memory"); |
|||
return ptr; |
|||
} |
|||
void* xrealloc(void* p, size_t n) { |
|||
void* ptr = realloc(p, n); |
|||
if (ptr == NULL) |
|||
fatal("Out of memory"); |
|||
return ptr; |
|||
} |
|||
typedef struct string_buffer_tag { |
|||
size_t size; |
|||
size_t capacity; |
|||
char* string; |
|||
} string_buffer; |
|||
void string_buffer_create(string_buffer* buffer, size_t capacity) { |
|||
buffer->size = 0; |
|||
buffer->capacity = capacity; |
|||
buffer->string = xmalloc(capacity); |
|||
} |
|||
void string_buffer_destroy(string_buffer* buffer) { |
|||
free(buffer->string); |
|||
buffer->string = NULL; |
|||
buffer->size = 0; |
|||
buffer->capacity = 0; |
|||
} |
|||
void string_buffer_clear(string_buffer* buffer) { |
|||
buffer->size = 0; |
|||
} |
|||
void string_buffer_append(string_buffer* buffer, const char* str, size_t len) { |
|||
size_t min_capacity = buffer->size + len + 1; |
|||
if (buffer->capacity < min_capacity) { |
|||
size_t new_capacity = 5*buffer->capacity/4; |
|||
if (new_capacity < min_capacity) |
|||
new_capacity = min_capacity; |
|||
buffer->string = xrealloc(buffer->string, new_capacity); |
|||
buffer->capacity = new_capacity; |
|||
} |
|||
memcpy(buffer->string + buffer->size, str, len + 1); |
|||
⚫ | |||
} |
} |
||
Line 175: | Line 120: | ||
size_t offset; |
size_t offset; |
||
size_t length; |
size_t length; |
||
} |
} word_t; |
||
typedef struct word_list_tag { |
typedef struct word_list_tag { |
||
GArray* words; |
|||
GString* str; |
|||
word* words; |
|||
string_buffer str; |
|||
} word_list; |
} word_list; |
||
void word_list_create(word_list* words |
void word_list_create(word_list* words) { |
||
words-> |
words->words = g_array_new(FALSE, FALSE, sizeof(word_t)); |
||
words-> |
words->str = g_string_new(NULL); |
||
words->words = xmalloc(capacity * sizeof(word)); |
|||
string_buffer_create(&words->str, capacity*8); |
|||
} |
} |
||
void word_list_destroy(word_list* words) { |
void word_list_destroy(word_list* words) { |
||
g_string_free(words->str, TRUE); |
|||
g_array_free(words->words, TRUE); |
|||
⚫ | |||
words->size = 0; |
|||
words->capacity = 0; |
|||
} |
} |
||
void word_list_clear(word_list* words) { |
void word_list_clear(word_list* words) { |
||
g_string_truncate(words->str, 0); |
|||
words-> |
g_array_set_size(words->words, 0); |
||
} |
} |
||
void word_list_append(word_list* words, const char* str) { |
void word_list_append(word_list* words, const char* str) { |
||
size_t offset = words->str |
size_t offset = words->str->len; |
||
size_t len = strlen(str); |
size_t len = strlen(str); |
||
g_string_append_len(words->str, str, len); |
|||
word_t word; |
|||
size_t min_capacity = words->size + 1; |
|||
⚫ | |||
if (words->capacity < min_capacity) { |
|||
⚫ | |||
size_t new_capacity = (words->capacity * 5)/4; |
|||
⚫ | |||
if (new_capacity < min_capacity) |
|||
⚫ | |||
new_capacity = min_capacity; |
|||
words->words = xrealloc(words->words, new_capacity * sizeof(word)); |
|||
word_t* word_list_get(word_list* words, size_t index) { |
|||
words->capacity = new_capacity; |
|||
return &g_array_index(words->words, word_t, index); |
|||
} |
|||
word* w = &words->words[words->size++]; |
|||
⚫ | |||
w->length = len; |
|||
} |
} |
||
void word_list_extend(word_list* words, const char* str) { |
void word_list_extend(word_list* words, const char* str) { |
||
word_t* word = word_list_get(words, words->words->len - 1); |
|||
size_t len = strlen(str); |
size_t len = strlen(str); |
||
word->length += len; |
|||
g_string_append_len(words->str, str, len); |
|||
} |
} |
||
Line 258: | Line 193: | ||
} |
} |
||
size_t count_letters( |
size_t count_letters(word_list* words, size_t index) { |
||
const |
const word_t* word = word_list_get(words, index); |
||
size_t letters = 0; |
size_t letters = 0; |
||
const char* s = words->str |
const char* s = words->str->str + word->offset; |
||
for (size_t i = 0, n = |
for (size_t i = 0, n = word->length; i < n; ++i) { |
||
if (isalpha((unsigned char)s[i])) |
if (isalpha((unsigned char)s[i])) |
||
++letters; |
++letters; |
||
Line 290: | Line 225: | ||
size_t sentence_length(const word_list* words) { |
size_t sentence_length(const word_list* words) { |
||
size_t n = words-> |
size_t n = words->words->len; |
||
if (n == 0) |
if (n == 0) |
||
return 0; |
return 0; |
||
return words->str |
return words->str->len + n - 1; |
||
} |
} |
||
Line 300: | Line 235: | ||
size_t n = 201; |
size_t n = 201; |
||
word_list result = { 0 }; |
word_list result = { 0 }; |
||
word_list_create(&result |
word_list_create(&result); |
||
sentence(&result, n); |
sentence(&result, n); |
||
printf("Number of letters in first %'lu words in the sequence:\n", n); |
printf("Number of letters in first %'lu words in the sequence:\n", n); |
||
Line 311: | Line 246: | ||
for (n = 1000; n <= 10000000; n *= 10) { |
for (n = 1000; n <= 10000000; n *= 10) { |
||
sentence(&result, n); |
sentence(&result, n); |
||
const |
const word_t* word = word_list_get(&result, n - 1); |
||
const char* s = result.str |
const char* s = result.str->str + word->offset; |
||
printf("The %'luth word is '%.*s' and has %lu letters. ", n |
printf("The %'luth word is '%.*s' and has %lu letters. ", n, |
||
count_letters(&result, n - 1)); |
(int)word->length, s, count_letters(&result, n - 1)); |
||
printf("Sentence length: %'lu\n" , sentence_length(&result)); |
printf("Sentence length: %'lu\n" , sentence_length(&result)); |
||
} |
} |