diff options
| -rw-r--r-- | CMakeLists.txt | 4 | ||||
| -rw-r--r-- | include/stc/algo/coroutine.h | 5 | ||||
| -rw-r--r-- | misc/examples/algo/coread.c (renamed from misc/examples/coread.c) | 0 | ||||
| -rw-r--r-- | misc/examples/algo/coroutines.c (renamed from misc/examples/coroutines.c) | 0 | ||||
| -rw-r--r-- | misc/examples/algo/forfilter.c (renamed from misc/examples/forfilter.c) | 0 | ||||
| -rw-r--r-- | misc/examples/algo/generator.c | 53 | ||||
| -rw-r--r-- | misc/examples/algo/prime.c (renamed from misc/examples/prime.c) | 0 | ||||
| -rw-r--r-- | misc/examples/algo/triples.c (renamed from misc/examples/triples.c) | 10 |
8 files changed, 61 insertions, 11 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index a4659ff6..b86c1879 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,8 +13,8 @@ endif() include(CTest) if(BUILD_TESTING) - file(GLOB misc/examples misc/examples/*.c) - foreach(file IN LISTS misc/examples) + file(GLOB_RECURSE examples misc/examples/*.c) + foreach(file IN LISTS examples) get_filename_component(name "${file}" NAME_WE) add_executable(${name} ${file}) #target_compile_options(${name} PRIVATE "-pthread") diff --git a/include/stc/algo/coroutine.h b/include/stc/algo/coroutine.h index f3e42165..84be4a4e 100644 --- a/include/stc/algo/coroutine.h +++ b/include/stc/algo/coroutine.h @@ -24,7 +24,6 @@ #define STC_COROUTINE_INCLUDED /* #include <stdio.h> -#include <stdbool.h> #include <stc/algo/coroutine.h> struct iterate { @@ -61,7 +60,6 @@ int main(void) { enum { cco_state_final = -1, cco_state_expired = -2, - cco_state_illegal = -3, }; #define cco_alive(ctx) ((ctx)->cco_state > 0) @@ -74,8 +72,7 @@ enum { #define cco_end(retval) \ *_state = cco_state_expired; break; \ - default: assert(!"illegal coroutine state"); \ - goto _cco_final_; /* avoid unused-warning */ \ + default: goto _cco_final_; /* avoid unused-warning */ \ } \ return retval diff --git a/misc/examples/coread.c b/misc/examples/algo/coread.c index c5f85e08..c5f85e08 100644 --- a/misc/examples/coread.c +++ b/misc/examples/algo/coread.c diff --git a/misc/examples/coroutines.c b/misc/examples/algo/coroutines.c index 2c9e6d5c..2c9e6d5c 100644 --- a/misc/examples/coroutines.c +++ b/misc/examples/algo/coroutines.c diff --git a/misc/examples/forfilter.c b/misc/examples/algo/forfilter.c index 5e1cf15e..5e1cf15e 100644 --- a/misc/examples/forfilter.c +++ b/misc/examples/algo/forfilter.c diff --git a/misc/examples/algo/generator.c b/misc/examples/algo/generator.c new file mode 100644 index 00000000..fce44a52 --- /dev/null +++ b/misc/examples/algo/generator.c @@ -0,0 +1,53 @@ +// https://quuxplusone.github.io/blog/2019/03/06/pythagorean-triples/ + +#include <stc/algo/coroutine.h> +#include <stdio.h> + +typedef struct { + int n; + int a, b, c; +} Triple_value, Triple; + +typedef struct { + Triple_value* ref; + int cco_state; +} Triple_iter; + +bool Triple_next(Triple_iter* it) { + Triple_value* t = it->ref; + cco_begin(it); + for (t->c = 1;; ++t->c) { + for (t->a = 1; t->a < t->c; ++t->a) { + for (t->b = t->a; t->b < t->c; ++t->b) { + if (t->a*t->a + t->b*t->b == t->c*t->c) { + cco_yield(true); + if (t->n-- == 1) cco_return; + } + } + } + } + cco_final: + it->ref = NULL; + cco_end(false); +} + +Triple_iter Triple_begin(Triple* t) { + Triple_iter it = {t}; + if (t->n > 0) Triple_next(&it); + else it.ref = NULL; + return it; +} + + +int main() +{ + puts("Pythagorean triples with c < 100:"); + Triple t = {INT32_MAX}; + c_foreach (i, Triple, t) + { + if (i.ref->c < 100) + printf("%u: (%d, %d, %d)\n", INT32_MAX - i.ref->n + 1, i.ref->a, i.ref->b, i.ref->c); + else + (void)cco_stop(&i); + } +} diff --git a/misc/examples/prime.c b/misc/examples/algo/prime.c index e705dcb7..e705dcb7 100644 --- a/misc/examples/prime.c +++ b/misc/examples/algo/prime.c diff --git a/misc/examples/triples.c b/misc/examples/algo/triples.c index 0ce0eb37..8a46d653 100644 --- a/misc/examples/triples.c +++ b/misc/examples/algo/triples.c @@ -17,13 +17,13 @@ void triples_vanilla(int n) { done:; } -struct tricoro { +struct triples { int n; - int cco_state; int x, y, z; + int cco_state; }; -bool triples_coro(struct tricoro* t) { +bool triples_coro(struct triples* t) { cco_begin(t); for (t->z = 1;; ++t->z) { for (t->x = 1; t->x < t->z; ++t->x) { @@ -46,7 +46,7 @@ int main() triples_vanilla(6); puts("\nCoroutine triples:"); - struct tricoro t = {6}; + struct triples t = {6}; while (triples_coro(&t)) printf("{%d, %d, %d},\n", t.x, t.y, t.z); -}
\ No newline at end of file +} |
