diff options
| author | tylov <[email protected]> | 2023-07-20 15:09:10 +0200 |
|---|---|---|
| committer | tylov <[email protected]> | 2023-07-20 15:12:29 +0200 |
| commit | 900295256d825fc323149cd223c49787f32a3696 (patch) | |
| tree | 6c79cf4209e3975bb6865e2940b9cb56ea469c73 /misc/examples/algorithms | |
| parent | 224a04f7fa7549ed94d2a1415eb25829e39a7cca (diff) | |
| download | STC-modified-900295256d825fc323149cd223c49787f32a3696.tar.gz STC-modified-900295256d825fc323149cd223c49787f32a3696.zip | |
Moved examples to sub-directories. Added cotask1.c cotask2.c examples.
Diffstat (limited to 'misc/examples/algorithms')
| -rw-r--r-- | misc/examples/algorithms/forfilter.c | 149 | ||||
| -rw-r--r-- | misc/examples/algorithms/forloops.c | 69 | ||||
| -rw-r--r-- | misc/examples/algorithms/random.c | 45 | ||||
| -rw-r--r-- | misc/examples/algorithms/shape.c | 158 | ||||
| -rw-r--r-- | misc/examples/algorithms/shape.cpp | 122 |
5 files changed, 543 insertions, 0 deletions
diff --git a/misc/examples/algorithms/forfilter.c b/misc/examples/algorithms/forfilter.c new file mode 100644 index 00000000..f3c008b3 --- /dev/null +++ b/misc/examples/algorithms/forfilter.c @@ -0,0 +1,149 @@ +#include <stdio.h> +#define i_import +#include <stc/cstr.h> +#define i_implement +#include <stc/csview.h> +#include <stc/algo/filter.h> +#include <stc/algo/crange.h> + +#define i_type IVec +#define i_key int +#include <stc/cstack.h> + +// filters and transforms: +#define flt_skipValue(i, x) (*i.ref != (x)) +#define flt_isEven(i) ((*i.ref & 1) == 0) +#define flt_isOdd(i) (*i.ref & 1) +#define flt_square(i) (*i.ref * *i.ref) + +void demo1(void) +{ + IVec vec = c_init(IVec, {0, 1, 2, 3, 4, 5, 80, 6, 7, 80, 8, 9, 80, + 10, 11, 12, 13, 14, 15, 80, 16, 17}); + + c_forfilter (i, IVec, vec, flt_skipValue(i, 80)) + printf(" %d", *i.ref); + puts(""); + + int sum = 0; + c_forfilter (i, IVec, vec, + c_flt_skipwhile(i, *i.ref != 80) && + c_flt_skip(i, 1) && + flt_isEven(i) && + flt_skipValue(i, 80) && + c_flt_take(i, 5) // short-circuit + ){ + sum += flt_square(i); + } + + printf("\n sum: %d\n", sum); + IVec_drop(&vec); +} + + +/* Rust: +fn main() { + let vector = (1..) // Infinite range of integers + .skip_while(|x| *x != 11) // Skip initial numbers unequal 11 + .filter(|x| x % 2 != 0) // Collect odd numbers + .take(5) // Only take five numbers + .map(|x| x * x) // Square each number + .collect::<Vec<usize>>(); // Return as a new Vec<usize> + println!("{:?}", vector); // Print result +} +*/ +void demo2(void) +{ + IVec vector = {0}; + crange r = crange_make(INT64_MAX); + c_forfilter (x, crange, r, + c_flt_skipwhile(x, *x.ref != 11) && + (*x.ref % 2) != 0 && + c_flt_take(x, 5) + ){ + IVec_push(&vector, (int)(*x.ref * *x.ref)); + } + c_foreach (x, IVec, vector) printf(" %d", *x.ref); + + puts(""); + IVec_drop(&vector); +} + +/* Rust: +fn main() { + let sentence = "This is a sentence in Rust."; + let words: Vec<&str> = sentence + .split_whitespace() + .collect(); + let words_containing_i: Vec<&str> = words + .into_iter() + .filter(|word| word.contains("i")) + .collect(); + println!("{:?}", words_containing_i); +} +*/ +#define i_type SVec +#define i_keyclass csview +#include <stc/cstack.h> + +void demo3(void) +{ + const char* sentence = "This is a sentence in C99."; + SVec words = {0}; + c_fortoken (w, sentence, " ") // split words + SVec_push(&words, *w.ref); + + SVec words_containing_i = {0}; + c_forfilter (w, SVec, words, + csview_contains(*w.ref, "i")) + SVec_push(&words_containing_i, *w.ref); + + c_foreach (w, SVec, words_containing_i) + printf(" %.*s", c_SV(*w.ref)); + + puts(""); + c_drop(SVec, &words, &words_containing_i); +} + +void demo4(void) +{ + // Keep only uppercase letters and convert them to lowercase: + csview s = c_sv("ab123cReAghNGnΩoEp"); // Ω = multi-byte + cstr out = {0}; + + c_forfilter (i, csview, s, utf8_isupper(utf8_peek(i.ref))) { + char chr[4]; + utf8_encode(chr, utf8_tolower(utf8_peek(i.ref))); + cstr_push(&out, chr); + } + + printf(" %s\n", cstr_str(&out)); + cstr_drop(&out); +} + +void demo5(void) +{ + #define flt_even(i) ((*i.ref & 1) == 0) + #define flt_mid_decade(i) ((*i.ref % 10) != 0) + crange R = crange_make(1963, INT32_MAX); + + c_forfilter (i, crange, R, + c_flt_skip(i,15) && + c_flt_skipwhile(i, flt_mid_decade(i)) && + c_flt_skip(i,30) && + flt_even(i) && + c_flt_take(i,5) + ){ + printf(" %lld", *i.ref); + } + puts(""); +} + +int main(void) +{ + puts("demo1"); demo1(); + puts("demo2"); demo2(); + puts("demo3"); demo3(); + puts("demo4"); demo4(); + puts("demo5"); demo5(); +} diff --git a/misc/examples/algorithms/forloops.c b/misc/examples/algorithms/forloops.c new file mode 100644 index 00000000..72d745f8 --- /dev/null +++ b/misc/examples/algorithms/forloops.c @@ -0,0 +1,69 @@ +#include <stdio.h> +#include <stc/algo/filter.h> + +#define i_type IVec +#define i_key int +#include <stc/cstack.h> + +#define i_type IMap +#define i_key int +#define i_val int +#include <stc/cmap.h> + + +int main(void) +{ + puts("c_forrange:"); + c_forrange (30) printf(" xx"); + puts(""); + + c_forrange (i, 30) printf(" %lld", i); + puts(""); + + c_forrange (i, 30, 60) printf(" %lld", i); + puts(""); + + c_forrange (i, 30, 90, 2) printf(" %lld", i); + + puts("\n\nc_forlist:"); + c_forlist (i, int, {12, 23, 453, 65, 676}) + printf(" %d", *i.ref); + puts(""); + + c_forlist (i, const char*, {"12", "23", "453", "65", "676"}) + printf(" %s", *i.ref); + puts(""); + + IVec vec = c_init(IVec, {12, 23, 453, 65, 113, 215, 676, 34, 67, 20, 27, 66, 189, 45, 280, 199}); + IMap map = c_init(IMap, {{12, 23}, {453, 65}, {676, 123}, {34, 67}}); + + puts("\n\nc_foreach:"); + c_foreach (i, IVec, vec) + printf(" %d", *i.ref); + + puts("\n\nc_foreach_r: reverse"); + c_foreach_rv (i, IVec, vec) + printf(" %d", *i.ref); + + puts("\n\nc_foreach in map:"); + c_foreach (i, IMap, map) + printf(" (%d %d)", i.ref->first, i.ref->second); + + puts("\n\nc_forpair:"); + c_forpair (key, val, IMap, map) + printf(" (%d %d)", *_.key, *_.val); + + #define isOdd(i) (*i.ref & 1) + + puts("\n\nc_forfilter:"); + c_forfilter (i, IVec, vec, + isOdd(i) && + c_flt_skip(i, 4) && + c_flt_take(i, 4) + ){ + printf(" %d", *i.ref); + } + + IVec_drop(&vec); + IMap_drop(&map); +} diff --git a/misc/examples/algorithms/random.c b/misc/examples/algorithms/random.c new file mode 100644 index 00000000..b7c0f277 --- /dev/null +++ b/misc/examples/algorithms/random.c @@ -0,0 +1,45 @@ +#include <stdio.h> +#include <time.h> +#include <stc/crand.h> + +int main(void) +{ + const int N = 1000000000; + const uint64_t seed = (uint64_t)time(NULL), range = 1000000; + crand_t rng = crand_init(seed); + + int64_t sum; + clock_t diff, before; + + printf("Compare speed of full and unbiased ranged random numbers...\n"); + sum = 0; + before = clock(); + c_forrange (N) { + sum += (uint32_t)crand_u64(&rng); + } + diff = clock() - before; + printf("full range\t\t: %f secs, %d, avg: %f\n", + (double)diff/CLOCKS_PER_SEC, N, (double)sum/N); + + crand_unif_t dist1 = crand_unif_init(0, range); + rng = crand_init(seed); + sum = 0; + before = clock(); + c_forrange (N) { + sum += crand_unif(&rng, &dist1); // unbiased + } + diff = clock() - before; + printf("unbiased 0-%" PRIu64 "\t: %f secs, %d, avg: %f\n", + range, (double)diff/CLOCKS_PER_SEC, N, (double)sum/N); + + sum = 0; + rng = crand_init(seed); + before = clock(); + c_forrange (N) { + sum += (int64_t)(crand_u64(&rng) % (range + 1)); // biased + } + diff = clock() - before; + printf("biased 0-%" PRIu64 " \t: %f secs, %d, avg: %f\n", + range, (double)diff/CLOCKS_PER_SEC, N, (double)sum/N); + +} diff --git a/misc/examples/algorithms/shape.c b/misc/examples/algorithms/shape.c new file mode 100644 index 00000000..bd4bdd5a --- /dev/null +++ b/misc/examples/algorithms/shape.c @@ -0,0 +1,158 @@ +// Demo of typesafe polymorphism in C99, using STC. + +#include <stdlib.h> +#include <stdio.h> +#include <stc/ccommon.h> + +#define DYN_CAST(T, s) \ + (&T##_api == (s)->api ? (T*)(s) : (T*)0) + +// Shape definition +// ============================================================ + +typedef struct { + float x, y; +} Point; + +typedef struct Shape Shape; + +struct ShapeAPI { + void (*drop)(Shape*); + void (*draw)(const Shape*); +}; + +struct Shape { + struct ShapeAPI* api; + uint32_t color; + uint16_t style; + uint8_t thickness; + uint8_t hardness; +}; + +void Shape_drop(Shape* shape) +{ + printf("shape destructed\n"); +} + +void Shape_delete(Shape* shape) +{ + if (shape) { + shape->api->drop(shape); + c_free(shape); + } +} + +// Triangle implementation +// ============================================================ + +typedef struct { + Shape shape; + Point p[3]; +} Triangle; + +extern struct ShapeAPI Triangle_api; + + +Triangle Triangle_from(Point a, Point b, Point c) { + Triangle t = {{&Triangle_api}, {a, b, c}}; + return t; +} + +static void Triangle_draw(const Shape* shape) +{ + const Triangle* self = DYN_CAST(Triangle, shape); + printf("Triangle : (%g,%g), (%g,%g), (%g,%g)\n", + (double)self->p[0].x, (double)self->p[0].y, + (double)self->p[1].x, (double)self->p[1].y, + (double)self->p[2].x, (double)self->p[2].y); +} + +struct ShapeAPI Triangle_api = { + .drop = Shape_drop, + .draw = Triangle_draw, +}; + +// Polygon implementation +// ============================================================ + +#define i_type PointVec +#define i_key Point +#include <stc/cstack.h> + +typedef struct { + Shape shape; + PointVec points; +} Polygon; + +extern struct ShapeAPI Polygon_api; + + +Polygon Polygon_init(void) { + Polygon p = {{&Polygon_api}, {0}}; + return p; +} + +void Polygon_addPoint(Polygon* self, Point p) +{ + PointVec_push(&self->points, p); +} + +static void Polygon_drop(Shape* shape) +{ + Polygon* self = DYN_CAST(Polygon, shape); + printf("poly destructed\n"); + PointVec_drop(&self->points); +} + +static void Polygon_draw(const Shape* shape) +{ + const Polygon* self = DYN_CAST(Polygon, shape); + printf("Polygon :"); + c_foreach (i, PointVec, self->points) + printf(" (%g,%g)", (double)i.ref->x, (double)i.ref->y); + puts(""); +} + +struct ShapeAPI Polygon_api = { + .drop = Polygon_drop, + .draw = Polygon_draw, +}; + +// Test +// ============================================================ + +#define i_type Shapes +#define i_key Shape* +#define i_keydrop(x) Shape_delete(*x) +#define i_no_clone +#include <stc/cstack.h> + +void testShape(const Shape* shape) +{ + shape->api->draw(shape); +} + + +int main(void) +{ + Shapes shapes = {0}; + + Triangle* tri1 = c_new(Triangle, Triangle_from(c_LITERAL(Point){5, 7}, c_LITERAL(Point){12, 7}, c_LITERAL(Point){12, 20})); + Polygon* pol1 = c_new(Polygon, Polygon_init()); + Polygon* pol2 = c_new(Polygon, Polygon_init()); + + c_forlist (i, Point, {{50, 72}, {123, 73}, {127, 201}, {828, 333}}) + Polygon_addPoint(pol1, *i.ref); + + c_forlist (i, Point, {{5, 7}, {12, 7}, {12, 20}, {82, 33}, {17, 56}}) + Polygon_addPoint(pol2, *i.ref); + + Shapes_push(&shapes, &tri1->shape); + Shapes_push(&shapes, &pol1->shape); + Shapes_push(&shapes, &pol2->shape); + + c_foreach (i, Shapes, shapes) + testShape(*i.ref); + + Shapes_drop(&shapes); +} diff --git a/misc/examples/algorithms/shape.cpp b/misc/examples/algorithms/shape.cpp new file mode 100644 index 00000000..ea1f53d2 --- /dev/null +++ b/misc/examples/algorithms/shape.cpp @@ -0,0 +1,122 @@ +// Demo of polymorphism in C++ + +#include <iostream> +#include <memory> +#include <vector> + +// Shape definition +// ============================================================ + +struct Point { + float x, y; +}; + +std::ostream& operator<<(std::ostream& os, const Point& p) { + os << " (" << p.x << "," << p.y << ")"; + return os; +} + +struct Shape { + virtual ~Shape(); + virtual void draw() const = 0; + + uint32_t color; + uint16_t style; + uint8_t thickness; + uint8_t hardness; +}; + +Shape::~Shape() +{ + std::cout << "base destructed" << std::endl; +} + +// Triangle implementation +// ============================================================ + +struct Triangle : public Shape +{ + Triangle(Point a, Point b, Point c); + void draw() const override; + + private: Point p[3]; +}; + + +Triangle::Triangle(Point a, Point b, Point c) + : p{a, b, c} {} + +void Triangle::draw() const +{ + std::cout << "Triangle :" + << p[0] << p[1] << p[2] + << std::endl; +} + + +// Polygon implementation +// ============================================================ + + +struct Polygon : public Shape +{ + ~Polygon(); + void draw() const override; + void addPoint(const Point& p); + + private: std::vector<Point> points; +}; + + +void Polygon::addPoint(const Point& p) +{ + points.push_back(p); +} + +Polygon::~Polygon() +{ + std::cout << "poly destructed" << std::endl; +} + +void Polygon::draw() const +{ + std::cout << "Polygon :"; + for (auto& p : points) + std::cout << p ; + std::cout << std::endl; +} + + +// Test +// ============================================================ + +void testShape(const Shape* shape) +{ + shape->draw(); +} + +#include <array> + +int main(void) +{ + std::vector<std::unique_ptr<Shape>> shapes; + + auto tri1 = std::make_unique<Triangle>(Point{5, 7}, Point{12, 7}, Point{12, 20}); + auto pol1 = std::make_unique<Polygon>(); + auto pol2 = std::make_unique<Polygon>(); + + for (auto& p: std::array<Point, 4> + {{{50, 72}, {123, 73}, {127, 201}, {828, 333}}}) + pol1->addPoint(p); + + for (auto& p: std::array<Point, 5> + {{{5, 7}, {12, 7}, {12, 20}, {82, 33}, {17, 56}}}) + pol2->addPoint(p); + + shapes.push_back(std::move(tri1)); + shapes.push_back(std::move(pol1)); + shapes.push_back(std::move(pol2)); + + for (auto& shape: shapes) + testShape(shape.get()); +} |
