summaryrefslogtreecommitdiffhomepage
path: root/misc/examples/algo/triples.c
blob: 8a46d653a2c280bbc3a1ee3901df62225fae6153 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// https://quuxplusone.github.io/blog/2019/03/06/pythagorean-triples/

#include <stc/algo/coroutine.h>
#include <stdio.h>

void triples_vanilla(int n) {
    for (int i = 1, z = 1;; ++z) {
        for (int x = 1; x < z; ++x) {
            for (int y = x; y < z; ++y) {
                if (x*x + y*y == z*z) {
                    printf("{%d, %d, %d},\n", x, y, z);
                    if (++i > n) goto done;
                }
            }
        }
    }
    done:;
}

struct triples {
    int n;
    int x, y, z;
    int cco_state;
};

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) {
                for (t->y = t->x; t->y < t->z; ++t->y) {
                    if (t->x*t->x + t->y*t->y == t->z*t->z) {
                        if (t->n-- == 0) cco_return;
                        cco_yield(true);
                    }
                }
            }
        }
        cco_final:
    cco_end(false);
}


int main()
{
    puts("Vanilla triples:");
    triples_vanilla(6);

    puts("\nCoroutine triples:");
    struct triples t = {6};
    while (triples_coro(&t))
        printf("{%d, %d, %d},\n", t.x, t.y, t.z);
}