summaryrefslogtreecommitdiffhomepage
path: root/misc/examples/algorithms
diff options
context:
space:
mode:
Diffstat (limited to 'misc/examples/algorithms')
-rw-r--r--misc/examples/algorithms/forfilter.c148
-rw-r--r--misc/examples/algorithms/forloops.c65
-rw-r--r--misc/examples/algorithms/random.c42
-rw-r--r--misc/examples/algorithms/shape.c158
-rw-r--r--misc/examples/algorithms/shape.cpp122
5 files changed, 535 insertions, 0 deletions
diff --git a/misc/examples/algorithms/forfilter.c b/misc/examples/algorithms/forfilter.c
new file mode 100644
index 00000000..c1426045
--- /dev/null
+++ b/misc/examples/algorithms/forfilter.c
@@ -0,0 +1,148 @@
+#include <stdio.h>
+#define i_import
+#include <stc/cstr.h>
+#define i_implement
+#include <stc/csview.h>
+#include <stc/algorithm.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_init(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_init(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..a83d4a53
--- /dev/null
+++ b/misc/examples/algorithms/forloops.c
@@ -0,0 +1,65 @@
+#include <stdio.h>
+#include <stc/algorithm.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 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..e457d329
--- /dev/null
+++ b/misc/examples/algorithms/random.c
@@ -0,0 +1,42 @@
+#include <stdio.h>
+#include <time.h>
+#include <stc/crand.h>
+
+int main(void)
+{
+ const long long N = 10000000, range = 1000000;
+ const uint64_t seed = (uint64_t)time(NULL);
+ crand_t rng = crand_init(seed);
+ clock_t t;
+
+ printf("Compare speed of full and unbiased ranged random numbers...\n");
+ long long sum = 0;
+ t = clock();
+ c_forrange (N) {
+ sum += (int32_t)crand_u64(&rng);
+ }
+ t = clock() - t;
+ printf("full range\t\t: %f secs, %lld, avg: %f\n",
+ (double)t/CLOCKS_PER_SEC, N, (double)(sum/N));
+
+ crand_uniform_t dist1 = crand_uniform_init(0, range);
+ rng = crand_init(seed);
+ sum = 0;
+ t = clock();
+ c_forrange (N) {
+ sum += crand_uniform(&rng, &dist1); // unbiased
+ }
+ t = clock() - t;
+ printf("unbiased 0-%lld\t: %f secs, %lld, avg: %f\n",
+ range, (double)t/CLOCKS_PER_SEC, N, (double)(sum/N));
+
+ sum = 0;
+ rng = crand_init(seed);
+ t = clock();
+ c_forrange (N) {
+ sum += (int32_t)crand_u64(&rng) % (range + 1); // biased
+ }
+ t = clock() - t;
+ printf("biased 0-%lld \t: %f secs, %lld, avg: %f\n",
+ range, (double)t/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());
+}