From 911e1fec10a1cb37646128197c520a8ac0379d7d Mon Sep 17 00:00:00 2001 From: Mattia Mascarello Date: Tue, 2 Sep 2025 09:33:27 +0200 Subject: [PATCH] Modularized, removed prepositions Why not the same otput? printf() implementation direcly used in the original does not guarantee order of calling the args! --- haiku.c | 549 +++++++++++++++++--------------------------------------- 1 file changed, 166 insertions(+), 383 deletions(-) diff --git a/haiku.c b/haiku.c index abdb7f7..3447286 100644 --- a/haiku.c +++ b/haiku.c @@ -1,13 +1,12 @@ +#include #include #include -#include #include -#include +#include // Function to pick a random word/phrase from an array -const char *randomWord(const char *words[], int size) -{ - return words[rand() % size]; +const char *randomWord(const char *words[], int size) { + return words[rand() % size]; } const char *nouns[] = { @@ -111,26 +110,6 @@ const char *adjectives[] = { "suspended", "whispering", "paradoxical", "lost", "timeless", "unreachable", "evanescent", "sparse", "celestial", "distant", "undying", "perpetual", "unknown", "mournful", "luminous", "abandoned", "unheard", "worn", "delicate"}; -const char *prepositions[] = { - "beneath", "within", "above", "across", "through", "beyond", "among", "before", "after", "around", - "throughout", "within", "behind", "underneath", "amongst", "upon", "along", "in", "upon", "against", - "within reach of", "out of", "through the midst of", "into the heart of", "beside", "near", "between", - "beyond the horizon", "beneath the stars", "amidst", "beyond the veil", "within the depths", "through the shadows", - "out of sight", "in the wake of", "within reach", "on the edge of", "by the side of", "under the moon", "upon the winds", - "against the tide", "beyond the bounds", "through the storm", "across the sea", "among the clouds", "beneath the waves", - "in the light of", "in the quiet of", "among the whispers", "between the lines", "within the silence", "under the gaze of", - "in the shadow of", "through the veil", "at the edge of", "against the night", "beneath the canopy", "within the embrace of", - "through the passages of", "across the wilderness", "beyond the distance", "within the embrace", "under the sky", - "atop the world", "in the company of", "across the ages", "within the heart of", "through the echoes", "under the spell of", - "on the brink of", "in the glow of", "beneath the surface", "through the mist", "against the storm", "beyond the horizon", - "within the arms of", "by the grace of", "through the darkness", "beneath the stars", "within the soul of", "on the shores of", - "in the wake of", "under the weight of", "among the dreams", "against the current", "through the passage of time", "at the crossroads of", - "beyond the shadow", "beneath the earth", "in the quietude of", "under the heavens", "across the dawn", "within the whispers of", - "through the labyrinth", "beneath the heavens", "in the presence of", "among the echoes", "beyond the silence", "within the mystery", - "in the shade of", "through the distance", "under the stars", "upon the wings of", "within the pulse of", "among the ruins", - "beneath the sky", "under the veil of", "in the shadow of", "through the cracks of", "across the expanse", "in the stillness of", - "beyond the edge", "within the wilds", "beneath the twilight", "against the light", "through the corridor", "in the heart of"}; - const char *locations[] = { "horizon", "silence", "a distant dream", "burning sea", "endless void", "amber haze", "forgotten woods", "starlit sky", "edge of the world", "velvet night", "shadow's edge", @@ -180,369 +159,173 @@ const char *locations[] = { "distant river", "broken land", "eternal sea", "glowing sky", "barren expanse", "fleeting dream", "haunted ocean", "forgotten sky", "distant ocean", "shadowed hill"}; -const char *randomNoun() -{ - return randomWord(nouns, sizeof(nouns) / sizeof(nouns[0])); -} +const char *phrases[] = { + "%A %N %V", + "%A %N %V %L", + "Beneath the %N, the %A %V", + "Through the %L, %A %V %N", + "%N %V, %A %N", + "%A %V %N, lost in the %L", + "A %A %N under the %N sky", + "In the %L of the %N, we %V", + "%N whispers %V", + "With the %A %N, a %N %V", + "%A %V in the %L", + "%A %V, across the %L", + "A %A %N beyond the %L", + "At the %L's edge, %V %A", + "Among the %N, the %A %V", + "Through the %N %V %L", + "%N calls %V, under the %A sky", + "%V in the %L, %N echoes", + "A %A %N %V through the %L", + "%V the %N, %A %V", + "%V %A, by the %L's edge", + "Beneath the %L, a %N %V", + "%A of the %N %V", + "With the %N, a %A %V", + "Among the %L, we %V %A", + "A %A %N beneath the %L", + "%A %V within the %L", + "%N %V, beneath the %L", + "Through the %L, a %A %N", + "Within the %L, the %A %V", + "%A %V, under the %L sky", + "By the %L, the %N %V", + "A %A %N through the %L", + "We %V beneath the %A %N", + "%N %V across the %L", + "%L, a %A %V", + "Amidst the %L, a %A %N", + "By the %L's edge, the %N %V", + "%A %V by the %L", + "%A %V, across the %L", + "Within the %L, a %A %N", + "%N of the %A %V", + "Through the %L, the %V %A", + "%A in the %L, we %V", + "Among the %L, the %A %V", + "%A %V across the %L", + "%V %N through the %L", + "In the %L, the %N %V", + "A %A %V by the %L", + "%N whispers %V through the %L", + "Through the %L, the %N %V", + "%N beyond the %L %V", + "%A %V amidst the %L", + "%L's %V echoes in the %A", + "%A falls across the %L", + "Beneath the %L, the %N %V", + "A %A %N in the %L", + "In the %L, the %A %V", + "At the %L's edge, we %V", + "%A, fading through the %L", + "With the %A, we %V through the %L", + "A %A %N beneath the %L", + "%A calls beneath the %L", + "We %V through the %L", + "%N stands by the %L", + "%V beneath the %L, a %A %N", + "In the %L, we %V the %A", + "With the %A, we %V the %L", + "Through the %L, a %A %N", + "%N %V through the %L", + "Across the %L, the %V %A", + "%V the %A %N", + "We %V across the %L", + "%L's %V resounds in the %A", + "%N whispers across the %L", + "%V the %N, a %A %V", + "%A fades into the %L", + "In the %L, the %A %V", + "We %V beyond the %L", + "%N echoes in the %L", + "%N %V under the %L", + "Through the %L %V %N", + "In the %L, the %V %A", + "With the %A, a %N %V", + "In the %L, we %V %N", + "Through the %L, a %A %N", + "A %A %N across the %L", + "%N calls, fading into the %L", + "By the %L's edge, the %N %V", + "A %A stands in the %L", + "With the %A, the %N %V", + "In the %L, we %V the %A", + "Among the %L, the %N %V", + "By the %L's edge, a %A %V", + "%A %V beneath the %L", + "Across the %L, a %A %V", + "Through the %L, the %A %V", + "In the %L, a %A %V", + "%A %V across the %L", + "In the %L, the %V %N", +}; -const char *randomVerb() -{ - return randomWord(verbs, sizeof(verbs) / sizeof(verbs[0])); -} +#define RNDW(bank) randomWord(bank, sizeof(bank) / sizeof(bank[0])) -const char *randomAdjective() -{ - return randomWord(adjectives, sizeof(adjectives) / sizeof(adjectives[0])); -} +const char *randomNoun() { return RNDW(nouns); } -const char *randomPreposition() -{ - return randomWord(prepositions, sizeof(prepositions) / sizeof(prepositions[0])); -} +const char *randomVerb() { return RNDW(verbs); } -const char *randomLocation() -{ - return randomWord(locations, sizeof(locations) / sizeof(locations[0])); -} +const char *randomAdjective() { return RNDW(adjectives); } -int main(int argc, char *argv[]) -{ - int days = 1; +const char *randomLocation() { return RNDW(locations); } - if (argc > 1) - { - // error check strtol - char *endptr; - errno = 0; - days = strtol(argv[1], &endptr, 10); - if (errno != 0 || endptr == argv[1] || *endptr != '\0' || days <= 0) - { - fprintf(stderr, "Could not convert argument to integer\n"); - printf("Usage: %s [days]\n", argv[0]); - return 1; - } +void printPhrase(const char *fmt) { + while (*fmt) { + if (*fmt == '%' && *(fmt + 1)) { + switch (*(fmt + 1)) { + case 'A': + printf("%s", randomAdjective()); + break; + case 'N': + printf("%s", randomNoun()); + break; + case 'V': + printf("%s", randomVerb()); + break; + case 'L': + printf("%s", randomLocation()); + break; + default: + putchar('%'); + putchar(*(fmt + 1)); + break; + } + fmt += 2; + } else { + putchar(*fmt++); } - - for (int day = 0; day < days; day++) - { - - if (days != 1) - { - time_t t = time(NULL); - t += day * 86400; - struct tm tm = *localtime(&t); - printf("%d-%02d-%02d ", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); - } - srand(time(NULL) / 86400 + day); - - int verseCount = 1; // haiku - for (int i = 0; i < verseCount; i++) - { - - switch (rand() % 100) - { - case 0: - printf("%s %s %s.\n", randomAdjective(), randomNoun(), randomVerb()); - break; - case 1: - printf("%s %s %s %s.\n", randomAdjective(), randomNoun(), randomVerb(), randomLocation()); - break; - case 2: - printf("Beneath the %s, the %s %s.\n", randomNoun(), randomAdjective(), randomVerb()); - break; - case 3: - printf("Through the %s, %s %s %s.\n", randomLocation(), randomAdjective(), randomVerb(), randomNoun()); - break; - case 4: - printf("%s %s, %s %s.\n", randomNoun(), randomVerb(), randomAdjective(), randomNoun()); - break; - case 5: - printf("%s %s %s, lost in the %s.\n", randomAdjective(), randomVerb(), randomNoun(), randomLocation()); - break; - case 6: - printf("A %s %s under the %s sky.\n", randomAdjective(), randomNoun(), randomNoun()); - break; - case 7: - printf("In the %s of the %s, we %s.\n", randomLocation(), randomNoun(), randomVerb()); - break; - case 8: - printf("%s whispers %s.\n", randomNoun(), randomVerb()); - break; - case 9: - printf("With the %s %s, a %s %s.\n", randomAdjective(), randomNoun(), randomNoun(), randomVerb()); - break; - case 10: - printf("%s %s in the %s.\n", randomAdjective(), randomVerb(), randomLocation()); - break; - case 11: - printf("%s %s, across the %s.\n", randomAdjective(), randomVerb(), randomLocation()); - break; - case 12: - printf("A %s %s beyond the %s.\n", randomAdjective(), randomNoun(), randomLocation()); - break; - case 13: - printf("At the %s's edge, %s %s.\n", randomLocation(), randomVerb(), randomAdjective()); - break; - case 14: - printf("Among the %s, the %s %s.\n", randomNoun(), randomAdjective(), randomVerb()); - break; - case 15: - printf("Through the %s %s %s.\n", randomNoun(), randomVerb(), randomLocation()); - break; - case 16: - printf("%s calls %s, under the %s sky.\n", randomNoun(), randomVerb(), randomAdjective()); - break; - case 17: - printf("%s in the %s, %s echoes.\n", randomVerb(), randomLocation(), randomNoun()); - break; - case 18: - printf("A %s %s %s through the %s.\n", randomAdjective(), randomNoun(), randomVerb(), randomLocation()); - break; - case 19: - printf("%s the %s, %s %s.\n", randomVerb(), randomNoun(), randomAdjective(), randomVerb()); - break; - case 20: - printf("%s %s, by the %s's edge.\n", randomVerb(), randomAdjective(), randomLocation()); - break; - case 21: - printf("Beneath the %s, a %s %s.\n", randomLocation(), randomNoun(), randomVerb()); - break; - case 22: - printf("%s of the %s %s.\n", randomAdjective(), randomNoun(), randomVerb()); - break; - case 23: - printf("With the %s, a %s %s.\n", randomNoun(), randomAdjective(), randomVerb()); - break; - case 24: - printf("Among the %s, we %s %s.\n", randomLocation(), randomVerb(), randomAdjective()); - break; - case 25: - printf("A %s %s beneath the %s.\n", randomAdjective(), randomNoun(), randomLocation()); - break; - case 26: - printf("%s %s within the %s.\n", randomAdjective(), randomVerb(), randomLocation()); - break; - case 27: - printf("%s %s, beneath the %s.\n", randomNoun(), randomVerb(), randomLocation()); - break; - case 28: - printf("Through the %s, a %s %s.\n", randomLocation(), randomAdjective(), randomNoun()); - break; - case 29: - printf("Within the %s, the %s %s.\n", randomLocation(), randomAdjective(), randomVerb()); - break; - case 30: - printf("%s %s, under the %s sky.\n", randomAdjective(), randomVerb(), randomLocation()); - break; - case 31: - printf("By the %s, the %s %s.\n", randomLocation(), randomNoun(), randomVerb()); - break; - case 32: - printf("A %s %s through the %s.\n", randomAdjective(), randomNoun(), randomLocation()); - break; - case 33: - printf("We %s beneath the %s %s.\n", randomVerb(), randomAdjective(), randomNoun()); - break; - case 34: - printf("%s %s across the %s.\n", randomNoun(), randomVerb(), randomLocation()); - break; - case 35: - printf("%s, a %s %s.\n", randomLocation(), randomAdjective(), randomVerb()); - break; - case 36: - printf("Amidst the %s, a %s %s.\n", randomLocation(), randomAdjective(), randomNoun()); - break; - case 37: - printf("By the %s's edge, the %s %s.\n", randomLocation(), randomNoun(), randomVerb()); - break; - case 38: - printf("%s %s by the %s.\n", randomAdjective(), randomVerb(), randomLocation()); - break; - case 39: - printf("%s %s, across the %s.\n", randomAdjective(), randomVerb(), randomLocation()); - break; - case 40: - printf("Within the %s, a %s %s.\n", randomLocation(), randomAdjective(), randomNoun()); - break; - case 41: - printf("%s of the %s %s.\n", randomNoun(), randomAdjective(), randomVerb()); - break; - case 42: - printf("Through the %s, the %s %s.\n", randomLocation(), randomVerb(), randomAdjective()); - break; - case 43: - printf("%s in the %s, we %s.\n", randomAdjective(), randomLocation(), randomVerb()); - break; - case 44: - printf("Among the %s, the %s %s.\n", randomLocation(), randomAdjective(), randomVerb()); - break; - case 45: - printf("%s %s across the %s.\n", randomAdjective(), randomVerb(), randomLocation()); - break; - case 46: - printf("%s %s through the %s.\n", randomVerb(), randomNoun(), randomLocation()); - break; - case 47: - printf("In the %s, the %s %s.\n", randomLocation(), randomNoun(), randomVerb()); - break; - case 48: - printf("A %s %s by the %s.\n", randomAdjective(), randomVerb(), randomLocation()); - break; - case 49: - printf("%s whispers %s through the %s.\n", randomNoun(), randomVerb(), randomLocation()); - break; - case 50: - printf("Through the %s, the %s %s.\n", randomLocation(), randomNoun(), randomVerb()); - break; - case 51: - printf("%s beyond the %s %s.\n", randomNoun(), randomLocation(), randomVerb()); - break; - case 52: - printf("%s %s amidst the %s.\n", randomAdjective(), randomVerb(), randomLocation()); - break; - case 53: - printf("%s's %s echoes in the %s.\n", randomLocation(), randomVerb(), randomAdjective()); - break; - case 54: - printf("%s falls across the %s.\n", randomAdjective(), randomLocation()); - break; - case 55: - printf("Beneath the %s, the %s %s.\n", randomLocation(), randomNoun(), randomVerb()); - break; - case 56: - printf("A %s %s in the %s.\n", randomAdjective(), randomNoun(), randomLocation()); - break; - case 57: - printf("In the %s, the %s %s.\n", randomLocation(), randomAdjective(), randomVerb()); - break; - case 58: - printf("At the %s's edge, we %s.\n", randomLocation(), randomVerb()); - break; - case 59: - printf("%s, fading through the %s.\n", randomAdjective(), randomLocation()); - break; - case 60: - printf("With the %s, we %s through the %s.\n", randomAdjective(), randomVerb(), randomLocation()); - break; - case 61: - printf("A %s %s beneath the %s.\n", randomAdjective(), randomNoun(), randomLocation()); - break; - case 62: - printf("%s calls beneath the %s.\n", randomAdjective(), randomLocation()); - break; - case 63: - printf("We %s through the %s.\n", randomVerb(), randomLocation()); - break; - case 64: - printf("%s stands by the %s.\n", randomNoun(), randomLocation()); - break; - case 65: - printf("%s beneath the %s, a %s %s.\n", randomVerb(), randomLocation(), randomAdjective(), randomNoun()); - break; - case 66: - printf("In the %s, we %s the %s.\n", randomLocation(), randomVerb(), randomAdjective()); - break; - case 67: - printf("With the %s, we %s the %s.\n", randomAdjective(), randomVerb(), randomLocation()); - break; - case 68: - printf("Through the %s, a %s %s.\n", randomLocation(), randomAdjective(), randomNoun()); - break; - case 69: - printf("%s %s through the %s.\n", randomNoun(), randomVerb(), randomLocation()); - break; - case 70: - printf("Across the %s, the %s %s.\n", randomLocation(), randomVerb(), randomAdjective()); - break; - case 71: - printf("%s the %s %s.\n", randomVerb(), randomAdjective(), randomNoun()); - break; - case 72: - printf("We %s across the %s.\n", randomVerb(), randomLocation()); - break; - case 73: - printf("%s's %s resounds in the %s.\n", randomLocation(), randomVerb(), randomAdjective()); - break; - case 74: - printf("%s whispers across the %s.\n", randomNoun(), randomLocation()); - break; - case 75: - printf("%s the %s, a %s %s.\n", randomVerb(), randomNoun(), randomAdjective(), randomVerb()); - break; - case 76: - printf("%s fades into the %s.\n", randomAdjective(), randomLocation()); - break; - case 77: - printf("In the %s, the %s %s.\n", randomLocation(), randomAdjective(), randomVerb()); - break; - case 78: - printf("We %s beyond the %s.\n", randomVerb(), randomLocation()); - break; - case 79: - printf("%s echoes in the %s.\n", randomNoun(), randomLocation()); - break; - case 80: - printf("%s %s under the %s.\n", randomNoun(), randomVerb(), randomLocation()); - break; - case 81: - printf("Through the %s %s %s.\n", randomLocation(), randomVerb(), randomNoun()); - break; - case 82: - printf("In the %s, the %s %s.\n", randomLocation(), randomVerb(), randomAdjective()); - break; - case 83: - printf("With the %s, a %s %s.\n", randomAdjective(), randomNoun(), randomVerb()); - break; - case 84: - printf("In the %s, we %s %s.\n", randomLocation(), randomVerb(), randomNoun()); - break; - case 85: - printf("Through the %s, a %s %s.\n", randomLocation(), randomAdjective(), randomNoun()); - break; - case 86: - printf("A %s %s across the %s.\n", randomAdjective(), randomNoun(), randomLocation()); - break; - case 87: - printf("%s calls, fading into the %s.\n", randomNoun(), randomLocation()); - break; - case 88: - printf("By the %s's edge, the %s %s.\n", randomLocation(), randomNoun(), randomVerb()); - break; - case 89: - printf("A %s stands in the %s.\n", randomAdjective(), randomLocation()); - break; - case 90: - printf("With the %s, the %s %s.\n", randomAdjective(), randomNoun(), randomVerb()); - break; - case 91: - printf("In the %s, we %s the %s.\n", randomLocation(), randomVerb(), randomAdjective()); - break; - case 92: - printf("Among the %s, the %s %s.\n", randomLocation(), randomNoun(), randomVerb()); - break; - case 93: - printf("By the %s's edge, a %s %s.\n", randomLocation(), randomAdjective(), randomVerb()); - break; - case 94: - printf("%s %s beneath the %s.\n", randomAdjective(), randomVerb(), randomLocation()); - break; - case 95: - printf("Across the %s, a %s %s.\n", randomLocation(), randomAdjective(), randomVerb()); - break; - case 96: - printf("Through the %s, the %s %s.\n", randomLocation(), randomAdjective(), randomVerb()); - break; - case 97: - printf("In the %s, a %s %s.\n", randomLocation(), randomAdjective(), randomVerb()); - break; - case 98: - printf("%s %s across the %s.\n", randomAdjective(), randomVerb(), randomLocation()); - break; - case 99: - printf("In the %s, the %s %s.\n", randomLocation(), randomVerb(), randomNoun()); - break; - } - } - } - return 0; + } +} + +int main(int argc, char *argv[]) { + int days = 1; + + if (argc > 1) { + // error check strtol + char *endptr; + errno = 0; + days = strtol(argv[1], &endptr, 10); + if (errno != 0 || endptr == argv[1] || *endptr != '\0' || days <= 0) { + fprintf(stderr, "Could not convert argument to integer\n"); + printf("Usage: %s [days]\n", argv[0]); + return 1; + } + } + + for (int day = 0; day < days; day++) { + + if (days != 1) { + time_t t = time(NULL); + t += day * 86400; + struct tm tm = *localtime(&t); + printf("%d-%02d-%02d ", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); + } + srand(time(NULL) / 86400 + day); + printPhrase(phrases[rand() % (sizeof(phrases) / sizeof(phrases[0]))]); + printf(".\n"); + } + return 0; }