Files
poem_machine/haiku.c
Mattia Mascarello 911e1fec10 Modularized, removed prepositions
Why not the same otput? printf() implementation direcly used in the original does not guarantee order of calling the args!
2025-09-02 09:33:27 +02:00

332 lines
16 KiB
C

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/random.h>
#include <time.h>
// Function to pick a random word/phrase from an array
const char *randomWord(const char *words[], int size) {
return words[rand() % size];
}
const char *nouns[] = {
"shadows", "embers", "quiet echo", "forgotten star", "veiled mirror", "hollow bell",
"frozen dusk", "weeping willow", "fractured light", "silken thread",
"ancient tome", "solemn whisper", "flickering flame", "broken dream",
"silver tide", "nameless face", "misty veil", "fading gleam",
"fragile mask", "crystal tear", "wandering spirit", "distant cry",
"secret garden", "golden hour", "fractured sky", "crimson moon",
"hidden path", "withered rose", "trembling leaf", "silent hymn",
"endless river", "midnight bloom", "mirrored soul", "forgotten melody",
"quiet stream", "shifting shadow", "pale ghost", "wandering flame",
"starry abyss", "twilight grove", "forsaken chapel", "rusted key",
"glistening dew", "ancient cairn", "phantom sea", "spectral glow",
"velvet dusk", "burning frost", "golden spark", "hollow stone",
"silent storm", "ashen wind", "murmured promise", "ivory flame",
"desolate shore", "ivory tower", "whispering mist", "gentle sigh",
"glimmering spire", "fractured dawn", "woven thread", "sunlit dream",
"forgotten vow", "emerald tide", "shattered prism", "hidden verse",
"fleeting ember", "sapphire haze", "silent ember", "watchful eye",
"spiraling void", "gentle tide", "ashen veil", "glistening tear",
"crimson haze", "spectral shroud", "hollow winds", "frozen flame",
"forgotten shrine", "flickering lantern", "woven dream", "solemn ember",
"violet bloom", "fractured mirror", "fleeting echo", "sapphire flame",
"broken wave", "rusted lock", "verdant grove", "hollow echo",
"eternal flame", "somber gaze", "fiery dusk", "frozen hollow",
"shadowed bough", "shifting tide", "fleeting shadow", "scarlet glow",
"emerald forest", "amber mist", "faded star", "veiled moon",
"endless expanse", "fractured stone", "crystal moon", "whispering shadow",
"unseen fire", "violet flame", "hidden stream", "midnight veil",
"distant flare", "haunted echo", "woven frost", "shadowed peak",
"spectral whisper", "waning light", "trembling flame", "hollow thread",
"fractured melody", "golden grove", "forgotten flame", "silent star",
"fading tide", "opal flame", "woven mirror", "silver frost",
"restless gale", "shimmering edge", "hidden light", "ashen grove",
"fleeting tide", "crimson flare", "shadowed hymn", "radiant haze",
"sapphire edge", "fractured flare", "hidden glow", "frozen tide",
"forgotten wisp", "glistening void", "emerald haze", "amber spark",
"twilight fire", "shimmering ember", "fractured thread", "whispering gale",
"silver gleam", "fleeting prism", "faded bloom", "endless hymn",
"moonlit stream", "gentle flame", "spectral tide", "hollow peak",
"frozen dawn", "shadowed flame", "opal prism", "drifting veil",
"eternal river", "hidden echo", "distant glow", "ashen tide",
"whispering frost", "silent flame", "verdant mist", "opal grove",
"flickering thread", "scarlet thread", "shadowed hollow", "fleeting wisp",
"solemn glow", "burning horizon", "amber thread", "spectral mist",
"sapphire stream", "hidden flare", "drifting frost", "distant star",
"fractured hymn", "shadowed spire", "violet tide", "eternal bloom",
"shimmering flame", "veiled shadow", "glistening hymn", "twilight song",
"gentle ember", "frozen spire", "fleeting thread", "sapphire spire",
"whispering thread", "fractured flare", "amber frost", "eternal gale",
"shadowed flame", "veiled tide", "verdant hymn", "sapphire wisp",
"opal fire", "frozen shadow", "distant veil", "shimmering flame",
"endless spire", "veiled dawn", "spectral dawn", "woven ember"};
const char *verbs[] = {
"drift", "shatter", "linger", "dissolve", "whisper", "tremble",
"echo", "fade", "quiver", "gleam", "murmur", "wander",
"glimmer", "sigh", "dance", "scatter", "fracture", "reflect",
"hover", "flow", "dim", "crumble", "ripple", "swell",
"cascade", "flutter", "waver", "glow", "vanish", "rise",
"fall", "meld", "stir", "descend", "ascend", "yearn",
"pierce", "burst", "pulse", "weep", "wither", "ignite",
"trace", "enfold", "beckon", "cradle", "embrace", "slumber",
"breathe", "evaporate", "tangle", "hesitate", "illuminate", "refract",
"hum", "blend", "glide", "bloom", "stream", "roam",
"float", "soften", "spill", "envelop", "soar", "dream",
"resound", "call", "entwine", "shine", "wander", "surge",
"consume", "erupt", "dwell", "shiver", "mingle", "rekindle",
"tremor", "grasp", "scatter", "embrace", "gleam", "whisper",
"proclaim", "collapse", "enlighten", "trace", "encompass", "smolder",
"freeze", "unravel", "decay", "illumine", "resonate", "bask",
"entice", "withdraw", "hover", "scatter", "billow", "kindle",
"douse", "spark", "explode", "glide", "dive", "expand",
"falter", "disperse", "erode", "ignite", "scatter", "extinguish",
"evoke", "quench"};
const char *adjectives[] = {
"ephemeral", "broken", "eternal", "distant", "lost", "silent", "cold", "luminous", "fleeting", "mysterious",
"forgotten", "dark", "fragile", "secret", "timeless", "ancient", "obscure", "ethereal", "absent", "pale",
"hidden", "rare", "shattered", "fading", "untold", "transient", "worn", "noble", "dusty", "misty",
"empty", "infinite", "boundless", "quiet", "hollow", "remote", "withered", "vibrant", "fractured",
"graceful", "haunted", "fragile", "unseen", "long-lost", "vanishing", "delicate", "silent", "forgotten",
"obscured", "disappearing", "fleeting", "barren", "undisturbed", "timeless", "ghostly", "strange",
"warm", "cold", "hidden", "bright", "dull", "invisible", "majestic", "mournful", "distant", "shrouded",
"serene", "chaotic", "eternal", "unnoticed", "fragile", "faint", "secretive", "luminous", "hidden",
"unknowable", "unknown", "vanished", "broken", "fading", "remote", "relic", "ancient", "isolated",
"unheard", "divine", "alien", "sacred", "uncharted", "unseen", "hidden", "sublime", "hidden", "surreal",
"calm", "pale", "delicate", "fragile", "strange", "quiet", "archaic", "impossible", "twilight", "distorted",
"immense", "infinite", "unfathomable", "forgotten", "shattered", "fading", "distant", "undying", "faint",
"mysterious", "noble", "distant", "empty", "endless", "mournful", "forgotten", "longing", "timeless",
"paradoxical", "undisturbed", "forlorn", "shrouded", "obscured", "secluded", "hidden", "sorrowful", "ethereal",
"unseen", "faded", "silent", "ancient", "neglected", "lost", "surreal", "untold", "faint", "unfading",
"shifting", "momentary", "frozen", "wild", "transient", "frayed", "ghostly", "burned", "immortal",
"unfathomable", "unchanging", "tragic", "arcane", "mystical", "hidden", "delicate", "drowned", "solitary",
"forbidden", "blurred", "hidden", "fragile", "foreboding", "ancient", "untraceable", "suspended", "unbroken",
"forever", "unseen", "distant", "forgotten", "hazy", "pale", "unbreakable", "endless", "unreached", "forgotten",
"slow", "stilled", "veiled", "hidden", "transitory", "arcane", "abandoned", "immense", "powerful", "untold",
"elusive", "undead", "hidden", "silent", "faraway", "faded", "shattered", "imminent", "unreachable", "faint",
"mournful", "lightless", "subtle", "unchanged", "unmarked", "mysterious", "lonely", "graceful", "fragile",
"suspended", "whispering", "paradoxical", "lost", "timeless", "unreachable", "evanescent", "sparse", "celestial",
"distant", "undying", "perpetual", "unknown", "mournful", "luminous", "abandoned", "unheard", "worn", "delicate"};
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",
"whispering winds", "edge of time", "moonlit shore", "twilight realm", "silver mist",
"sunken city", "sacred grove", "crystal caves", "eternal forest", "frayed cliffs",
"windswept plains", "quiet valley", "sun-drenched meadow", "hidden shore", "frozen tundra",
"golden fields", "endless desert", "darkened abyss", "haunted castle", "violet mist",
"lonely mountain", "forgotten valley", "sacred temple", "hollowed ground", "radiant ocean",
"hidden valley", "ancient ruins", "broken sky", "rolling hills", "starry abyss",
"murmuring stream", "forgotten temple", "endless night", "shifting sands", "fading light",
"pale horizon", "golden sands", "forbidden realm", "icy peaks", "distant stars",
"deep abyss", "silver lake", "silent forest", "midnight oasis", "glassy waters",
"blackened desert", "lost city", "hidden cave", "mist-covered peaks", "ancient path",
"shattered world", "starlit path", "endless nightfall", "darkened ocean", "vast unknown",
"drifting clouds", "faraway place", "forgotten temple", "hidden garden", "rustling leaves",
"floating island", "whispering cave", "dying light", "midnight forest", "enchanted glade",
"secret garden", "ancient oak", "drowned city", "forgotten land", "deserted island",
"black forest", "wandering path", "silver stream", "endless horizon", "haunting mountains",
"darkened meadow", "lost path", "hidden sanctuary", "ethereal valley", "forgotten shore",
"empty void", "endless canyon", "glowing embers", "crimson dusk", "frost-covered plains",
"starry field", "forgotten shore", "sacred pool", "misty cliffs", "sunlit meadow",
"phantom woods", "final frontier", "golden shore", "ocean's edge", "twilight mountains",
"cloud-covered peaks", "fallen city", "magical forest", "moonlit grove", "veiled land",
"shadowy glade", "fractured land", "endless river", "gleaming city", "eternal mountain",
"quiet ocean", "lunar plains", "barren desert", "secret lake", "shattered moon",
"shimmering horizon", "silver meadow", "forgotten trail", "haunted hills", "lost world",
"deep forest", "stormy sea", "farthest reaches", "dark horizon", "desolate world",
"shining shore", "abandoned temple", "emerald forest", "golden lake", "dark valley",
"glowing forest", "ancient desert", "infinite sky", "abyssal depths", "whispering mountains",
"sunken ruins", "sun-kissed plains", "forgotten peaks", "lonely lake", "starry sky",
"distant mountains", "frozen lake", "endless sky", "misty waters", "frozen ocean",
"lost temple", "moonlit valley", "midnight city", "twilight shore", "barren hills",
"ethereal glen", "broken ruins", "hidden temple", "wandering hills", "forgotten desert",
"midnight mountain", "crystal forest", "endless plains", "pale desert", "shadowed shore",
"forgotten glade", "hidden plains", "distant shores", "shadowy valley", "sun-dappled forest",
"haunted woods", "silent cliff", "unseen world", "darkened river", "endless waterfall",
"frozen forest", "distant hill", "sun-bleached hills", "night-sky valley", "wild plains",
"silent hills", "shimmering lake", "darkened wasteland", "ancient desert", "silent sea",
"starry river", "blazing sky", "secret path", "twilight garden", "ruined city",
"empty hill", "forgotten mountain", "glowing valley", "endless plain", "desolate field",
"silver desert", "lost grove", "blackened hills", "silent garden", "ethereal river",
"wandering ocean", "pale lake", "moonlit ocean", "cursed mountain", "dreamer's land",
"ancient grove", "last frontier", "empty forest", "sky's edge", "shadowed mountain",
"forgotten gorge", "silent cavern", "misty valley", "ancient river", "haunted desert",
"endless forest", "cold expanse", "starlit mountain", "glowing river", "ethereal sea",
"ghostly shore", "abandoned plain", "lost city", "empty ocean", "silver hills",
"distant river", "broken land", "eternal sea", "glowing sky", "barren expanse",
"fleeting dream", "haunted ocean", "forgotten sky", "distant ocean", "shadowed hill"};
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",
};
#define RNDW(bank) randomWord(bank, sizeof(bank) / sizeof(bank[0]))
const char *randomNoun() { return RNDW(nouns); }
const char *randomVerb() { return RNDW(verbs); }
const char *randomAdjective() { return RNDW(adjectives); }
const char *randomLocation() { return RNDW(locations); }
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++);
}
}
}
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;
}