diff options
| author | _Tradam <[email protected]> | 2023-09-08 01:29:47 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-09-08 01:29:47 +0000 |
| commit | 3c76c7f3d5db3f9586a90d03f8fbb02d79de9acd (patch) | |
| tree | afbe4b540967223911f7c5de36559b82154f02f3 /misc/examples/coroutines/triples.c | |
| parent | 0841165881871ee01b782129be681209aeed2423 (diff) | |
| parent | 1a72205fe05c2375cfd380dd8381a8460d9ed8d1 (diff) | |
| download | STC-modified-modified.tar.gz STC-modified-modified.zip | |
Diffstat (limited to 'misc/examples/coroutines/triples.c')
| -rw-r--r-- | misc/examples/coroutines/triples.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/misc/examples/coroutines/triples.c b/misc/examples/coroutines/triples.c new file mode 100644 index 00000000..d6ce2791 --- /dev/null +++ b/misc/examples/coroutines/triples.c @@ -0,0 +1,75 @@ +// https://quuxplusone.github.io/blog/2019/03/06/pythagorean-triples/ + +#include <stdio.h> +#include <stc/coroutine.h> + +void triples_vanilla(int max_c) { + for (int c = 5, i = 0;; ++c) { + for (int a = 1; a < c; ++a) { + for (int b = a + 1; b < c; ++b) { + if ((int64_t)a*a + (int64_t)b*b == (int64_t)c*c) { + if (c > max_c) + goto done; + printf("%d: {%d, %d, %d}\n", ++i, a, b, c); + } + } + } + } + done:; +} + +struct triples { + int max_c; + int a, b, c; + int cco_state; +}; + +int triples_coro(struct triples* t) { + cco_routine(t) { + for (t->c = 5;; ++t->c) { + for (t->a = 1; t->a < t->c; ++t->a) { + for (t->b = t->a + 1; t->b < t->c; ++t->b) { + if ((int64_t)t->a * t->a + + (int64_t)t->b * t->b == + (int64_t)t->c * t->c) + { + if (t->c > t->max_c) + cco_return; + cco_yield(); + } + } + } + } + cco_final: + puts("done"); + } + return 0; +} + +int gcd(int a, int b) { + while (b) { + int t = a % b; + a = b; + b = t; + } + return a; +} + +int main(void) +{ + puts("Vanilla triples:"); + triples_vanilla(20); + + puts("\nCoroutine triples with GCD = 1:"); + struct triples t = {.max_c = 100}; + int n = 0; + + cco_blocking_call(triples_coro(&t)) { + if (gcd(t.a, t.b) > 1) + continue; + if (++n <= 20) + printf("%d: {%d, %d, %d}\n", n, t.a, t.b, t.c); + else + cco_stop(&t); + } +} |
