summaryrefslogtreecommitdiffhomepage
path: root/misc/examples/mixed
diff options
context:
space:
mode:
author_Tradam <[email protected]>2023-09-08 01:29:47 +0000
committerGitHub <[email protected]>2023-09-08 01:29:47 +0000
commit3c76c7f3d5db3f9586a90d03f8fbb02d79de9acd (patch)
treeafbe4b540967223911f7c5de36559b82154f02f3 /misc/examples/mixed
parent0841165881871ee01b782129be681209aeed2423 (diff)
parent1a72205fe05c2375cfd380dd8381a8460d9ed8d1 (diff)
downloadSTC-modified-modified.tar.gz
STC-modified-modified.zip
Merge branch 'stclib:master' into modifiedHEADmodified
Diffstat (limited to 'misc/examples/mixed')
-rw-r--r--misc/examples/mixed/astar.c173
-rw-r--r--misc/examples/mixed/complex.c48
-rw-r--r--misc/examples/mixed/convert.c57
-rw-r--r--misc/examples/mixed/demos.c195
-rw-r--r--misc/examples/mixed/inits.c108
-rw-r--r--misc/examples/mixed/read.c27
6 files changed, 608 insertions, 0 deletions
diff --git a/misc/examples/mixed/astar.c b/misc/examples/mixed/astar.c
new file mode 100644
index 00000000..d15a9ed7
--- /dev/null
+++ b/misc/examples/mixed/astar.c
@@ -0,0 +1,173 @@
+//
+// -- An A* pathfinder inspired by the excellent tutorial at Red Blob Games --
+//
+// This is a reimplementation of the CTL example to STC:
+// https://github.com/glouw/ctl/blob/master/examples/astar.c
+// https://www.redblobgames.com/pathfinding/a-star/introduction.html
+#define i_implement
+#include <stc/cstr.h>
+#include <stdio.h>
+
+typedef struct
+{
+ int x;
+ int y;
+ int priorty;
+ int width;
+}
+point;
+
+point
+point_init(int x, int y, int width)
+{
+ return c_LITERAL(point){ x, y, 0, width };
+}
+
+int
+point_cmp_priority(const point* a, const point* b)
+{
+ return c_default_cmp(&a->priorty, &b->priorty);
+}
+
+int
+point_equal(const point* a, const point* b)
+{
+ return a->x == b->x && a->y == b->y;
+}
+
+point
+point_from(const cstr* maze, const char* c, int width)
+{
+ int index = (int)cstr_find(maze, c);
+ return point_init(index % width, index / width, width);
+}
+
+int
+point_index(const point* p)
+{
+ return p->x + p->width * p->y;
+}
+
+int
+point_key_cmp(const point* a, const point* b)
+{
+ int i = point_index(a);
+ int j = point_index(b);
+ return (i == j) ? 0 : (i < j) ? -1 : 1;
+}
+
+#define i_key point
+#define i_cmp point_cmp_priority
+#include <stc/cpque.h>
+
+#define i_key point
+#include <stc/cdeq.h>
+
+#define i_key point
+#define i_val int
+#define i_cmp point_key_cmp
+#define i_tag pcost
+#include <stc/csmap.h>
+
+#define i_key point
+#define i_val point
+#define i_cmp point_key_cmp
+#define i_tag pstep
+#include <stc/csmap.h>
+
+cdeq_point
+astar(cstr* maze, int width)
+{
+ cdeq_point ret_path = {0};
+
+ cpque_point front = {0};
+ csmap_pstep from = {0};
+ csmap_pcost costs = {0};
+ c_defer(
+ cpque_point_drop(&front),
+ csmap_pstep_drop(&from),
+ csmap_pcost_drop(&costs)
+ ){
+ point start = point_from(maze, "@", width);
+ point goal = point_from(maze, "!", width);
+ csmap_pcost_insert(&costs, start, 0);
+ cpque_point_push(&front, start);
+ while (!cpque_point_empty(&front))
+ {
+ point current = *cpque_point_top(&front);
+ cpque_point_pop(&front);
+ if (point_equal(&current, &goal))
+ break;
+ point deltas[] = {
+ { -1, +1, 0, width }, { 0, +1, 0, width }, { 1, +1, 0, width },
+ { -1, 0, 0, width }, /* ~ ~ ~ ~ ~ ~ ~ */ { 1, 0, 0, width },
+ { -1, -1, 0, width }, { 0, -1, 0, width }, { 1, -1, 0, width },
+ };
+ for (size_t i = 0; i < c_arraylen(deltas); i++)
+ {
+ point delta = deltas[i];
+ point next = point_init(current.x + delta.x, current.y + delta.y, width);
+ int new_cost = *csmap_pcost_at(&costs, current);
+ if (cstr_str(maze)[point_index(&next)] != '#')
+ {
+ const csmap_pcost_value *cost = csmap_pcost_get(&costs, next);
+ if (cost == NULL || new_cost < cost->second)
+ {
+ csmap_pcost_insert(&costs, next, new_cost);
+ next.priorty = new_cost + abs(goal.x - next.x) + abs(goal.y - next.y);
+ cpque_point_push(&front, next);
+ csmap_pstep_insert(&from, next, current);
+ }
+ }
+ }
+ }
+ point current = goal;
+ while (!point_equal(&current, &start))
+ {
+ cdeq_point_push_front(&ret_path, current);
+ current = *csmap_pstep_at(&from, current);
+ }
+ cdeq_point_push_front(&ret_path, start);
+ }
+ return ret_path;
+}
+
+int
+main(void)
+{
+ cstr maze = cstr_lit(
+ "#########################################################################\n"
+ "# # # # # # #\n"
+ "# # ######### # ##### ######### ##### ##### ##### # ! #\n"
+ "# # # # # # # # # #\n"
+ "######### # ######### ######### ##### # # # ######### #\n"
+ "# # # # # # # # # # #\n"
+ "# # ############# # # ######### ##### # ######### # #\n"
+ "# # # # # # # # # #\n"
+ "# ############# ##### ##### # ##### ######### # ##### #\n"
+ "# # # # # # # # # #\n"
+ "# ##### ##### # ##### # ######### # # # #############\n"
+ "# # # # # # # # # # # #\n"
+ "############# # # # ######### # ##### # ##### ##### #\n"
+ "# # # # # # # # # #\n"
+ "# ##### # ######### ##### # ##### ##### ############# #\n"
+ "# # # # # # # # # #\n"
+ "# # ######### # ##### ######### # # ############# # #\n"
+ "# # # # # # # # # # #\n"
+ "# ######### # # # ##### ######### ######### # #########\n"
+ "# # # # # # # # # #\n"
+ "# @ # ##### ##### ##### ######### ##### # ######### # #\n"
+ "# # # # # # #\n"
+ "#########################################################################\n"
+ );
+ int width = (int)cstr_find(&maze, "\n") + 1;
+ cdeq_point ret_path = astar(&maze, width);
+
+ c_foreach (it, cdeq_point, ret_path)
+ cstr_data(&maze)[point_index(it.ref)] = 'x';
+
+ printf("%s", cstr_str(&maze));
+
+ cdeq_point_drop(&ret_path);
+ cstr_drop(&maze);
+}
diff --git a/misc/examples/mixed/complex.c b/misc/examples/mixed/complex.c
new file mode 100644
index 00000000..9fcbc417
--- /dev/null
+++ b/misc/examples/mixed/complex.c
@@ -0,0 +1,48 @@
+
+// Define similar c++ data types:
+//
+// using FloatStack = std::stack<float>;
+// using StackList = std::stack<FloatStack>;
+// using ListMap = std::unordered_map<int, std::forward_list<StackList>>;
+// using MapMap = std::unordered_map<std::string, ListMap>;
+#define i_implement
+#include <stc/cstr.h>
+
+#define i_type FloatStack
+#define i_key float
+#include <stc/cstack.h>
+
+#define i_type StackList
+#define i_keyclass FloatStack // "class" picks up _clone, _drop, _cmp
+#include <stc/clist.h>
+
+#define i_type ListMap
+#define i_key int
+#define i_valclass StackList // "class" picks up _clone, _drop
+#include <stc/cmap.h>
+
+#define i_type MapMap
+#define i_key_str
+#define i_valclass ListMap
+#include <stc/cmap.h>
+
+
+int main(void)
+{
+ MapMap mmap = {0};
+
+ // Put in some data in the structures
+ ListMap* lmap = &MapMap_emplace(&mmap, "first", ListMap_init()).ref->second;
+ StackList* list = &ListMap_insert(lmap, 42, StackList_init()).ref->second;
+ FloatStack* stack = StackList_push_back(list, FloatStack_with_size(10, 0));
+ stack->data[3] = 3.1415927f;
+ printf("stack size: %" c_ZI "\n", FloatStack_size(stack));
+
+ // Access the data entry
+ const ListMap* lmap_p = MapMap_at(&mmap, "first");
+ const StackList* list_p = ListMap_at(lmap_p, 42);
+ const FloatStack* stack_p = StackList_back(list_p);
+ printf("value is: %f\n", (double)*FloatStack_at(stack_p, 3)); // pi
+
+ MapMap_drop(&mmap);
+}
diff --git a/misc/examples/mixed/convert.c b/misc/examples/mixed/convert.c
new file mode 100644
index 00000000..fa64560e
--- /dev/null
+++ b/misc/examples/mixed/convert.c
@@ -0,0 +1,57 @@
+#define i_implement
+#include <stc/cstr.h>
+
+#define i_key_str
+#define i_val_str
+#include <stc/cmap.h>
+
+#define i_key_str
+#include <stc/cvec.h>
+
+#define i_key_str
+#include <stc/clist.h>
+
+int main(void)
+{
+ cmap_str map, mclone;
+ cvec_str keys = {0}, values = {0};
+ clist_str list = {0};
+
+ c_defer(
+ cmap_str_drop(&map),
+ cmap_str_drop(&mclone),
+ cvec_str_drop(&keys),
+ cvec_str_drop(&values),
+ clist_str_drop(&list)
+ ){
+ map = c_init(cmap_str, {
+ {"green", "#00ff00"},
+ {"blue", "#0000ff"},
+ {"yellow", "#ffff00"},
+ });
+
+ puts("MAP:");
+ c_foreach (i, cmap_str, map)
+ printf(" %s: %s\n", cstr_str(&i.ref->first), cstr_str(&i.ref->second));
+
+ puts("\nCLONE MAP:");
+ mclone = cmap_str_clone(map);
+ c_foreach (i, cmap_str, mclone)
+ printf(" %s: %s\n", cstr_str(&i.ref->first), cstr_str(&i.ref->second));
+
+ puts("\nCOPY MAP TO VECS:");
+ c_foreach (i, cmap_str, mclone) {
+ cvec_str_emplace_back(&keys, cstr_str(&i.ref->first));
+ cvec_str_emplace_back(&values, cstr_str(&i.ref->second));
+ }
+ c_forrange (i, cvec_str_size(&keys))
+ printf(" %s: %s\n", cstr_str(keys.data + i), cstr_str(values.data + i));
+
+ puts("\nCOPY VEC TO LIST:");
+ c_foreach (i, cvec_str, keys)
+ clist_str_emplace_back(&list, cstr_str(i.ref));
+
+ c_foreach (i, clist_str, list)
+ printf(" %s\n", cstr_str(i.ref));
+ }
+}
diff --git a/misc/examples/mixed/demos.c b/misc/examples/mixed/demos.c
new file mode 100644
index 00000000..43c9a7ae
--- /dev/null
+++ b/misc/examples/mixed/demos.c
@@ -0,0 +1,195 @@
+#define i_implement
+#include <stc/cstr.h>
+
+void stringdemo1(void)
+{
+ cstr cs = cstr_lit("one-nine-three-seven-five");
+ printf("%s.\n", cstr_str(&cs));
+
+ cstr_insert(&cs, 3, "-two");
+ printf("%s.\n", cstr_str(&cs));
+
+ cstr_erase(&cs, 7, 5); // -nine
+ printf("%s.\n", cstr_str(&cs));
+
+ cstr_replace(&cs, "seven", "four", 1);
+ printf("%s.\n", cstr_str(&cs));
+
+ cstr_take(&cs, cstr_from_fmt("%s *** %s", cstr_str(&cs), cstr_str(&cs)));
+ printf("%s.\n", cstr_str(&cs));
+
+ printf("find \"four\": %s\n", cstr_str(&cs) + cstr_find(&cs, "four"));
+
+ // reassign:
+ cstr_assign(&cs, "one two three four five six seven");
+ cstr_append(&cs, " eight");
+ printf("append: %s\n", cstr_str(&cs));
+
+ cstr_drop(&cs);
+}
+
+#define i_key long long
+#define i_tag ix
+#include <stc/cvec.h>
+
+void vectordemo1(void)
+{
+ cvec_ix bignums = cvec_ix_with_capacity(100);
+ cvec_ix_reserve(&bignums, 100);
+ for (int i = 10; i <= 100; i += 10)
+ cvec_ix_push(&bignums, i * i);
+
+ printf("erase - %d: %lld\n", 3, bignums.data[3]);
+ cvec_ix_erase_n(&bignums, 3, 1); // erase index 3
+
+ cvec_ix_pop(&bignums); // erase the last
+ cvec_ix_erase_n(&bignums, 0, 1); // erase the first
+
+ for (int i = 0; i < cvec_ix_size(&bignums); ++i) {
+ printf("%d: %lld\n", i, bignums.data[i]);
+ }
+
+ cvec_ix_drop(&bignums);
+}
+
+#define i_key_str
+#define i_use_cmp
+#include <stc/cvec.h>
+
+void vectordemo2(void)
+{
+ cvec_str names = {0};
+ cvec_str_emplace_back(&names, "Mary");
+ cvec_str_emplace_back(&names, "Joe");
+ cvec_str_emplace_back(&names, "Chris");
+ cstr_assign(&names.data[1], "Jane"); // replace Joe
+ printf("names[1]: %s\n", cstr_str(&names.data[1]));
+
+ cvec_str_sort(&names); // Sort the array
+
+ c_foreach (i, cvec_str, names)
+ printf("sorted: %s\n", cstr_str(i.ref));
+
+ cvec_str_drop(&names);
+}
+
+#define i_key int
+#define i_tag ix
+#define i_use_cmp
+#include <stc/clist.h>
+
+void listdemo1(void)
+{
+ clist_ix nums = {0}, nums2 = {0};
+ for (int i = 0; i < 10; ++i)
+ clist_ix_push_back(&nums, i);
+ for (int i = 100; i < 110; ++i)
+ clist_ix_push_back(&nums2, i);
+
+ /* splice nums2 to front of nums */
+ clist_ix_splice(&nums, clist_ix_begin(&nums), &nums2);
+ c_foreach (i, clist_ix, nums)
+ printf("spliced: %d\n", *i.ref);
+ puts("");
+
+ *clist_ix_find(&nums, 104).ref += 50;
+ clist_ix_remove(&nums, 103);
+ clist_ix_iter it = clist_ix_begin(&nums);
+ clist_ix_erase_range(&nums, clist_ix_advance(it, 5), clist_ix_advance(it, 15));
+ clist_ix_pop_front(&nums);
+ clist_ix_push_back(&nums, -99);
+ clist_ix_sort(&nums);
+
+ c_foreach (i, clist_ix, nums)
+ printf("sorted: %d\n", *i.ref);
+
+ c_drop(clist_ix, &nums, &nums2);
+}
+
+#define i_key int
+#define i_tag i
+#include <stc/cset.h>
+
+void setdemo1(void)
+{
+ cset_i nums = {0};
+ cset_i_insert(&nums, 8);
+ cset_i_insert(&nums, 11);
+
+ c_foreach (i, cset_i, nums)
+ printf("set: %d\n", *i.ref);
+ cset_i_drop(&nums);
+}
+
+#define i_key int
+#define i_val int
+#define i_tag ii
+#include <stc/cmap.h>
+
+void mapdemo1(void)
+{
+ cmap_ii nums = {0};
+ cmap_ii_insert(&nums, 8, 64);
+ cmap_ii_insert(&nums, 11, 121);
+ printf("val 8: %d\n", *cmap_ii_at(&nums, 8));
+ cmap_ii_drop(&nums);
+}
+
+#define i_key_str
+#define i_val int
+#define i_tag si
+#include <stc/cmap.h>
+
+void mapdemo2(void)
+{
+ cmap_si nums = {0};
+ cmap_si_emplace_or_assign(&nums, "Hello", 64);
+ cmap_si_emplace_or_assign(&nums, "Groovy", 121);
+ cmap_si_emplace_or_assign(&nums, "Groovy", 200); // overwrite previous
+
+ // iterate the map:
+ for (cmap_si_iter i = cmap_si_begin(&nums); i.ref; cmap_si_next(&i))
+ printf("long: %s: %d\n", cstr_str(&i.ref->first), i.ref->second);
+
+ // or rather use the short form:
+ c_foreach (i, cmap_si, nums)
+ printf("short: %s: %d\n", cstr_str(&i.ref->first), i.ref->second);
+
+ cmap_si_drop(&nums);
+}
+
+#define i_key_str
+#define i_val_str
+#include <stc/cmap.h>
+
+void mapdemo3(void)
+{
+ cmap_str table = {0};
+ cmap_str_emplace(&table, "Map", "test");
+ cmap_str_emplace(&table, "Make", "my");
+ cmap_str_emplace(&table, "Sunny", "day");
+ cmap_str_iter it = cmap_str_find(&table, "Make");
+ c_foreach (i, cmap_str, table)
+ printf("entry: %s: %s\n", cstr_str(&i.ref->first), cstr_str(&i.ref->second));
+ printf("size %" c_ZI ": remove: Make: %s\n", cmap_str_size(&table), cstr_str(&it.ref->second));
+ //cmap_str_erase(&table, "Make");
+ cmap_str_erase_at(&table, it);
+
+ printf("size %" c_ZI "\n", cmap_str_size(&table));
+ c_foreach (i, cmap_str, table)
+ printf("entry: %s: %s\n", cstr_str(&i.ref->first), cstr_str(&i.ref->second));
+
+ cmap_str_drop(&table); // frees key and value cstrs, and hash table.
+}
+
+int main(void)
+{
+ printf("\nSTRINGDEMO1\n"); stringdemo1();
+ printf("\nVECTORDEMO1\n"); vectordemo1();
+ printf("\nVECTORDEMO2\n"); vectordemo2();
+ printf("\nLISTDEMO1\n"); listdemo1();
+ printf("\nSETDEMO1\n"); setdemo1();
+ printf("\nMAPDEMO1\n"); mapdemo1();
+ printf("\nMAPDEMO2\n"); mapdemo2();
+ printf("\nMAPDEMO3\n"); mapdemo3();
+}
diff --git a/misc/examples/mixed/inits.c b/misc/examples/mixed/inits.c
new file mode 100644
index 00000000..53a49f1f
--- /dev/null
+++ b/misc/examples/mixed/inits.c
@@ -0,0 +1,108 @@
+#define i_implement
+#include <stc/cstr.h>
+
+#define i_key int
+#define i_val_str
+#define i_tag id // Map of int => cstr
+#include <stc/cmap.h>
+
+#define i_key_str
+#define i_val int
+#define i_tag cnt // Map of cstr => int
+#include <stc/cmap.h>
+
+typedef struct {int x, y;} ipair_t;
+inline static int ipair_cmp(const ipair_t* a, const ipair_t* b) {
+ int c = c_default_cmp(&a->x, &b->x);
+ return c ? c : c_default_cmp(&a->y, &b->y);
+}
+
+
+#define i_key ipair_t
+#define i_cmp ipair_cmp
+#define i_tag ip
+#include <stc/cvec.h>
+
+#define i_key ipair_t
+#define i_cmp ipair_cmp
+#define i_tag ip
+#include <stc/clist.h>
+
+#define i_key float
+#define i_tag f
+#include <stc/cpque.h>
+
+int main(void)
+{
+ // CVEC FLOAT / PRIORITY QUEUE
+
+ cpque_f floats = {0};
+ const float nums[] = {4.0f, 2.0f, 5.0f, 3.0f, 1.0f};
+
+ // PRIORITY QUEUE
+ c_forrange (i, c_arraylen(nums))
+ cpque_f_push(&floats, nums[i]);
+
+ puts("\npop and show high priorites first:");
+ while (! cpque_f_empty(&floats)) {
+ printf("%.1f ", (double)*cpque_f_top(&floats));
+ cpque_f_pop(&floats);
+ }
+ puts("\n");
+ cpque_f_drop(&floats);
+
+ // CMAP ID
+
+ int year = 2020;
+ cmap_id idnames = {0};
+ cmap_id_emplace(&idnames, 100, "Hello");
+ cmap_id_insert(&idnames, 110, cstr_lit("World"));
+ cmap_id_insert(&idnames, 120, cstr_from_fmt("Howdy, -%d-", year));
+
+ c_foreach (i, cmap_id, idnames)
+ printf("%d: %s\n", i.ref->first, cstr_str(&i.ref->second));
+ puts("");
+ cmap_id_drop(&idnames);
+
+ // CMAP CNT
+
+ cmap_cnt countries = c_init(cmap_cnt, {
+ {"Norway", 100},
+ {"Denmark", 50},
+ {"Iceland", 10},
+ {"Belgium", 10},
+ {"Italy", 10},
+ {"Germany", 10},
+ {"Spain", 10},
+ {"France", 10},
+ });
+ cmap_cnt_emplace(&countries, "Greenland", 0).ref->second += 20;
+ cmap_cnt_emplace(&countries, "Sweden", 0).ref->second += 20;
+ cmap_cnt_emplace(&countries, "Norway", 0).ref->second += 20;
+ cmap_cnt_emplace(&countries, "Finland", 0).ref->second += 20;
+
+ c_forpair (country, health, cmap_cnt, countries)
+ printf("%s: %d\n", cstr_str(_.country), *_.health);
+ puts("");
+ cmap_cnt_drop(&countries);
+
+ // CVEC PAIR
+
+ cvec_ip pairs1 = c_init(cvec_ip, {{5, 6}, {3, 4}, {1, 2}, {7, 8}});
+ cvec_ip_sort(&pairs1);
+
+ c_foreach (i, cvec_ip, pairs1)
+ printf("(%d %d) ", i.ref->x, i.ref->y);
+ puts("");
+ cvec_ip_drop(&pairs1);
+
+ // CLIST PAIR
+
+ clist_ip pairs2 = c_init(clist_ip, {{5, 6}, {3, 4}, {1, 2}, {7, 8}});
+ clist_ip_sort(&pairs2);
+
+ c_foreach (i, clist_ip, pairs2)
+ printf("(%d %d) ", i.ref->x, i.ref->y);
+ puts("");
+ clist_ip_drop(&pairs2);
+}
diff --git a/misc/examples/mixed/read.c b/misc/examples/mixed/read.c
new file mode 100644
index 00000000..de04fd31
--- /dev/null
+++ b/misc/examples/mixed/read.c
@@ -0,0 +1,27 @@
+#define i_implement
+#include <stc/cstr.h>
+#include <stc/algo/raii.h>
+#define i_key_str
+#include <stc/cvec.h>
+#include <errno.h>
+
+cvec_str read_file(const char* name)
+{
+ cvec_str vec = {0};
+ c_with (FILE* f = fopen(name, "r"), fclose(f))
+ c_with (cstr line = {0}, cstr_drop(&line))
+ while (cstr_getline(&line, f))
+ cvec_str_push(&vec, cstr_clone(line));
+ return vec;
+}
+
+int main(void)
+{
+ int n = 0;
+ c_with (cvec_str vec = read_file(__FILE__), cvec_str_drop(&vec))
+ c_foreach (i, cvec_str, vec)
+ printf("%5d: %s\n", ++n, cstr_str(i.ref));
+
+ if (errno)
+ printf("error: read_file(" __FILE__ "). errno: %d\n", errno);
+}