summaryrefslogtreecommitdiffhomepage
path: root/examples
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2020-07-16 23:42:08 +0200
committerTyge Løvset <[email protected]>2020-07-16 23:42:08 +0200
commit44c2d2e9a40da9a4c10d128bbad38e3d1802d361 (patch)
treea5bbdaca6ea1fc81e2cea324974f47ade08f25b0 /examples
parent5f004f4f91b4a383005c763ea925cf655ba2d7c2 (diff)
downloadSTC-modified-44c2d2e9a40da9a4c10d128bbad38e3d1802d361.tar.gz
STC-modified-44c2d2e9a40da9a4c10d128bbad38e3d1802d361.zip
API CHANGES: CHash now splitted to CMap / CSet, still in chash.h header. Renamed cstring.h -> cstr.h, cvector.h -> cvec.h
Diffstat (limited to 'examples')
-rw-r--r--examples/README.md24
-rw-r--r--examples/advanced.c26
-rw-r--r--examples/benchmark.c18
-rw-r--r--examples/complex.c16
-rw-r--r--examples/demos.c66
-rw-r--r--examples/geek1.c185
-rw-r--r--examples/geek2.c122
-rw-r--r--examples/geek3.c50
-rw-r--r--examples/geek4.c262
-rw-r--r--examples/geek5.c140
-rw-r--r--examples/geek6.c124
-rw-r--r--examples/mapmap.c20
-rw-r--r--examples/prime.c45
13 files changed, 1023 insertions, 75 deletions
diff --git a/examples/README.md b/examples/README.md
index b77fb94e..cd6ac4ff 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -6,7 +6,7 @@ Contains various examples and benchmarks.
advanced.c Example
------------------
-This demonstrates how to customize **CHash map** with a user-defined key-type. You need to define two things:
+This demonstrates how to customize hash **CMap** with a user-defined key-type. You need to define two things:
1. A hash function; calculates the hash value given an object of the key-type.
@@ -58,28 +58,28 @@ Viking viking_fromVw(VikingVw vw) {
}
```
-With this in place, we use the full declare_CHash() macro to define {Viking -> int} hash map type:
+With this in place, we use the full declare_CMap() macro to define {Viking -> int} hash map type:
```
-declare_CHash(vk, MAP, Viking, int, c_emptyDestroy, vikingvw_hash, vikingvw_equals,
- viking_destroy, VikingVw, viking_getVw, viking_fromVw);
+declare_CMap(vk, Viking, int, c_emptyDestroy, vikingvw_hash, vikingvw_equals,
+ viking_destroy, VikingVw, viking_getVw, viking_fromVw);
```
-CHash_vk uses vikingvw_hash() for hash value calculations, and vikingvw_equals() for equality test. chash_vk_destroy() will free all memory allocated for Viking keys and the hash table values.
+CMap_vk uses vikingvw_hash() for hash value calculations, and vikingvw_equals() for equality test. cmap_vk_destroy() will free all memory allocated for Viking keys and the hash table values.
Finally, the demo:
```
int main()
{
- CHash_vk vikings = chash_init;
+ CMap_vk vikings = cmap_init;
// emplace constructs the keys
- chash_vk_put(&vikings, (VikingVw) {"Einar", "Norway"}, 20);
- chash_vk_put(&vikings, (VikingVw) {"Olaf", "Denmark"}, 24);
- chash_vk_put(&vikings, (VikingVw) {"Harald", "Iceland"}, 12);
+ cmap_vk_put(&vikings, (VikingVw) {"Einar", "Norway"}, 20);
+ cmap_vk_put(&vikings, (VikingVw) {"Olaf", "Denmark"}, 24);
+ cmap_vk_put(&vikings, (VikingVw) {"Harald", "Iceland"}, 12);
- CHashEntry_vk* e = chash_vk_get(&vikings, (VikingVw) {"Einar", "Norway"});
+ CMapEntry_vk* e = cmap_vk_get(&vikings, (VikingVw) {"Einar", "Norway"});
e->value += 5; // update
- c_foreach (k, chash_vk, vikings) {
+ c_foreach (k, cmap_vk, vikings) {
printf("%s of %s has %d hp\n", k.item->key.name.str, k.item->key.country.str, k.item->value);
}
- chash_vk_destroy(&vikings);
+ cmap_vk_destroy(&vikings);
}
```
diff --git a/examples/advanced.c b/examples/advanced.c
index e8b62fe2..c4c13f10 100644
--- a/examples/advanced.c
+++ b/examples/advanced.c
@@ -1,5 +1,5 @@
/*
- * To be able to use CHash with a user-defined key-type, you need to define two things:
+ * To be able to use CMap with a user-defined key-type, you need to define two things:
* 1. A hash function; this must be a function that calculates the hash value given
* an object of the key-type.
* 2. A comparison function for equality.
@@ -52,29 +52,29 @@ Viking viking_fromVw(VikingVw vw) {
}
-// Using the full declare_CHash() macro to define [Viking -> int] hash map type:
-declare_CHash(vk, MAP, Viking, int, c_emptyDestroy, vikingvw_hash, vikingvw_equals,
- viking_destroy, VikingVw, viking_getVw, viking_fromVw);
+// Using the full declare_CMap() macro to define [Viking -> int] hash map type:
+declare_CMap(vk, Viking, int, c_emptyDestroy, vikingvw_hash, vikingvw_equals,
+ viking_destroy, VikingVw, viking_getVw, viking_fromVw);
-// CHash_vk uses vikingvw_hash() for hash value calculations, and vikingvw_equals() for equality test.
-// chash_vk_destroy() will free all memory allocated for Viking keys and the hash table values.
+// CMap_vk uses vikingvw_hash() for hash value calculations, and vikingvw_equals() for equality test.
+// cmap_vk_destroy() will free all memory allocated for Viking keys and the hash table values.
// Main ----------------------------
int main()
{
- CHash_vk vikings = chash_init;
+ CMap_vk vikings = cmap_init;
// emplace constructs the keys
- chash_vk_put(&vikings, (VikingVw) {"Einar", "Norway"}, 20);
- chash_vk_put(&vikings, (VikingVw) {"Olaf", "Denmark"}, 24);
- chash_vk_put(&vikings, (VikingVw) {"Harald", "Iceland"}, 12);
+ cmap_vk_put(&vikings, (VikingVw) {"Einar", "Norway"}, 20);
+ cmap_vk_put(&vikings, (VikingVw) {"Olaf", "Denmark"}, 24);
+ cmap_vk_put(&vikings, (VikingVw) {"Harald", "Iceland"}, 12);
- CHashEntry_vk* e = chash_vk_get(&vikings, (VikingVw) {"Einar", "Norway"});
+ CMapEntry_vk* e = cmap_vk_get(&vikings, (VikingVw) {"Einar", "Norway"});
e->value += 5; // update
- c_foreach (k, chash_vk, vikings) {
+ c_foreach (k, cmap_vk, vikings) {
printf("%s of %s has %d hp\n", k.item->key.name.str, k.item->key.country.str, k.item->value);
}
- chash_vk_destroy(&vikings);
+ cmap_vk_destroy(&vikings);
}
diff --git a/examples/benchmark.c b/examples/benchmark.c
index 12449e27..45d16135 100644
--- a/examples/benchmark.c
+++ b/examples/benchmark.c
@@ -19,7 +19,7 @@ static inline uint32_t fibonacci_hash(const void* data, size_t len) {
const uint64_t key = *(const uint64_t *) data;
return (uint32_t) (key * 11400714819323198485llu);
}
-declare_CHash(ii, int64_t, int64_t, c_emptyDestroy, fibonacci_hash);
+declare_CMap(ii, int64_t, int64_t, c_emptyDestroy, fibonacci_hash);
KHASH_MAP_INIT_INT64(ii, uint64_t)
@@ -31,14 +31,14 @@ sfc64_random_t rng;
#define RAND(N) (sfc64_random(&rng) & ((1 << N) - 1))
-#define CMAP_SETUP(tag, Key, Value) CHash_##tag map = chash_init \
- /* ; chash_##tag##_setLoadFactors(&map, maxLoadFactor, 0.0)*/
-#define CMAP_PUT(tag, key, val) chash_##tag##_put(&map, key, val)->value
-#define CMAP_ERASE(tag, key) chash_##tag##_erase(&map, key)
-#define CMAP_FIND(tag, key) (chash_##tag##_get(map, key) != NULL)
-#define CMAP_SIZE(tag) chash_size(map)
-#define CMAP_BUCKETS(tag) chash_bucketCount(map)
-#define CMAP_CLEAR(tag) chash_##tag##_destroy(&map)
+#define CMAP_SETUP(tag, Key, Value) CMap_##tag map = cmap_init \
+ /* ; cmap_##tag##_setLoadFactors(&map, maxLoadFactor, 0.0)*/
+#define CMAP_PUT(tag, key, val) cmap_##tag##_put(&map, key, val)->value
+#define CMAP_ERASE(tag, key) cmap_##tag##_erase(&map, key)
+#define CMAP_FIND(tag, key) (cmap_##tag##_get(map, key) != NULL)
+#define CMAP_SIZE(tag) cmap_size(map)
+#define CMAP_BUCKETS(tag) cmap_bucketCount(map)
+#define CMAP_CLEAR(tag) cmap_##tag##_destroy(&map)
#define KMAP_SETUP(tag, Key, Value) khash_t(ii)* map = kh_init(ii); khiter_t ki; int ret
#define KMAP_PUT(tag, key, val) (*(ki = kh_put(ii, map, key, &ret), map->vals[ki] = val, &map->vals[ki]))
diff --git a/examples/complex.c b/examples/complex.c
index 3ecf6a1f..4434c9c9 100644
--- a/examples/complex.c
+++ b/examples/complex.c
@@ -7,31 +7,31 @@ void check_destroy(float* v) {printf("destroy %g\n", *v);}
declare_CArray(f, float, check_destroy); // normally omit the last argument - float type need no destroy.
declare_CList(t2, CArray2_f, carray2_f_destroy, c_noCompare);
-declare_CHash(il, int, CList_t2, clist_t2_destroy);
-declare_CHash_str(sm, CHash_il, chash_il_destroy);
+declare_CMap(il, int, CList_t2, clist_t2_destroy);
+declare_CMap_str(sm, CMap_il, cmap_il_destroy);
int main() {
int xdim = 4, ydim = 6;
int x = 1, y = 5, tableKey = 42;
const char* strKey = "first";
- CHash_sm theMap = chash_init;
+ CMap_sm theMap = cmap_init;
{ // Construct.
CArray2_f table = carray2_f_make(ydim, xdim, 0.f);
printf("table: (%zu, %zu)\n", carray2_ydim(table), carray2_xdim(table));
CList_t2 tableList = clist_init;
- CHash_il listMap = chash_init;
+ CMap_il listMap = cmap_init;
// Put in some data.
carray2_f_data(table, y)[x] = 3.1415927; // table[y][x]
clist_t2_pushBack(&tableList, table);
- chash_il_put(&listMap, tableKey, tableList);
- chash_sm_put(&theMap, strKey, listMap);
+ cmap_il_put(&listMap, tableKey, tableList);
+ cmap_sm_put(&theMap, strKey, listMap);
}
{ // Access the data entry
- CArray2_f table = clist_back(chash_il_get(&chash_sm_get(&theMap, strKey)->value, tableKey)->value);
+ CArray2_f table = clist_back(cmap_il_get(&cmap_sm_get(&theMap, strKey)->value, tableKey)->value);
printf("value (%d, %d) is: %f\n", y, x, carray2_f_value(table, y, x));
}
- chash_sm_destroy(&theMap); // free up the whole shebang!
+ cmap_sm_destroy(&theMap); // free up the whole shebang!
} \ No newline at end of file
diff --git a/examples/demos.c b/examples/demos.c
index 20ecd3a0..3bff2b5c 100644
--- a/examples/demos.c
+++ b/examples/demos.c
@@ -99,75 +99,75 @@ void listdemo1()
clist_ix_destroy(&nums);
}
-declare_CHash_set(i, int); // alias: declare_CHash(i, int);
+declare_CSet(i, int);
void setdemo1()
{
printf("\nSETDEMO1\n");
- CHash_i nums = chash_init;
- chash_i_put(&nums, 8);
- chash_i_put(&nums, 11);
+ CSet_i nums = cset_init;
+ cset_i_put(&nums, 8);
+ cset_i_put(&nums, 11);
- c_foreach (i, chash_i, nums)
+ c_foreach (i, cset_i, nums)
printf("set: %d\n", i.item->key);
- chash_i_destroy(&nums);
+ cset_i_destroy(&nums);
}
-declare_CHash(ii, int, int);
+declare_CMap(ii, int, int);
void mapdemo1()
{
printf("\nMAPDEMO1\n");
- CHash_ii nums = chash_init;
- chash_ii_put(&nums, 8, 64);
- chash_ii_put(&nums, 11, 121);
+ CMap_ii nums = cmap_init;
+ cmap_ii_put(&nums, 8, 64);
+ cmap_ii_put(&nums, 11, 121);
- printf("get 8: %d\n", chash_ii_get(&nums, 8)->value);
- chash_ii_destroy(&nums);
+ printf("get 8: %d\n", cmap_ii_get(&nums, 8)->value);
+ cmap_ii_destroy(&nums);
}
-declare_CHash_str(si, int); // Shorthand macro for the general declare_CHash expansion.
+declare_CMap_str(si, int); // Shorthand macro for the general declare_CMap expansion.
void mapdemo2()
{
printf("\nMAPDEMO2\n");
- CHash_si nums = chash_init;
- chash_si_put(&nums, "Hello", 64);
- chash_si_put(&nums, "Groovy", 121);
- chash_si_put(&nums, "Groovy", 200); // overwrite previous
+ CMap_si nums = cmap_init;
+ cmap_si_put(&nums, "Hello", 64);
+ cmap_si_put(&nums, "Groovy", 121);
+ cmap_si_put(&nums, "Groovy", 200); // overwrite previous
// iterate the map:
- for (chash_si_iter_t i = chash_si_begin(&nums); i.item; i = chash_si_next(i))
+ for (cmap_si_iter_t i = cmap_si_begin(&nums); i.item; i = cmap_si_next(i))
printf("long: %s: %d\n", i.item->key.str, i.item->value);
// or rather use the short form:
- c_foreach (i, chash_si, nums)
+ c_foreach (i, cmap_si, nums)
printf("short: %s: %d\n", i.item->key.str, i.item->value);
- chash_si_destroy(&nums);
+ cmap_si_destroy(&nums);
}
-declare_CHash_str(ss, CStr, cstr_destroy);
+declare_CMap_str(ss, CStr, cstr_destroy);
void mapdemo3()
{
printf("\nMAPDEMO3\n");
- CHash_ss table = chash_init;
- chash_ss_put(&table, "Map", cstr_make("test"));
- chash_ss_put(&table, "Make", cstr_make("my"));
- chash_ss_put(&table, "Sunny", cstr_make("day"));
- CHashEntry_ss *e = chash_ss_get(&table, "Make");
- printf("size %zu: remove: Make: %s\n", chash_size(table), e->value.str);
- chash_ss_erase(&table, "Make");
- //chash_ss_eraseEntry(&table, e);
-
- printf("size %zu\n", chash_size(table));
- c_foreach (i, chash_ss, table)
+ CMap_ss table = cmap_init;
+ cmap_ss_put(&table, "Map", cstr_make("test"));
+ cmap_ss_put(&table, "Make", cstr_make("my"));
+ cmap_ss_put(&table, "Sunny", cstr_make("day"));
+ CMapEntry_ss *e = cmap_ss_get(&table, "Make");
+ printf("size %zu: remove: Make: %s\n", cmap_size(table), e->value.str);
+ cmap_ss_erase(&table, "Make");
+ //cmap_ss_eraseEntry(&table, e);
+
+ printf("size %zu\n", cmap_size(table));
+ c_foreach (i, cmap_ss, table)
printf("entry: %s: %s\n", i.item->key.str, i.item->value.str);
- chash_ss_destroy(&table); // frees key and value CStrs, and hash table (CVec).
+ cmap_ss_destroy(&table); // frees key and value CStrs, and hash table (CVec).
}
diff --git a/examples/geek1.c b/examples/geek1.c
new file mode 100644
index 00000000..2aecaa8d
--- /dev/null
+++ b/examples/geek1.c
@@ -0,0 +1,185 @@
+// https://www.geeksforgeeks.org/maximize-the-number-of-sum-pairs-which-are-divisible-by-k/
+// Given an array of N integers and an integer K. The task is to print the maximum number
+// of pairs(a[i] + a[j]) possible which are divisible by K.
+
+
+int a[] = { 1, 2, 2, 3, 2, 4, 10 };
+//int a[] = { 1, 2, 2, 3, 2, 4, 10, 8, 9, 3, 2, 4 };
+
+
+#ifndef __cplusplus
+// C program to implement the above approach
+#include <stdio.h>
+#include <stc/chash.h>
+
+declare_CMap(ii, int, int);
+
+// Function to maximize the number of pairs
+int findMaximumPairs(int a[], int n, int k)
+{
+
+ // Hash-table
+ CMap_ii hash = cmap_init;
+ for (int i = 0; i < n; i++) {
+ cmap_ii_at(&hash, a[i] % k, 0)->value++;
+ }
+
+ int count = 0;
+
+ // Iterate for all numbers less than hash values
+ c_foreach (it, cmap_ii, hash) {
+
+ // If the number is 0
+ if (it.item->key == 0) {
+ // We take half since same number
+ count += it.item->value / 2;
+ cmap_ii_put(&hash, it.item->key, it.item->key & 1);
+ } else {
+ int first = it.item->key;
+ int second = k - it.item->key;
+
+ CMapEntry_ii *hf = cmap_ii_get(&hash, first),
+ *hs = cmap_ii_at(&hash, second, 0);
+ // Check for minimal occurrence
+ if (hf->value < hs->value) {
+ // Take the minimal
+ count += hf->value;
+
+ // Subtract the pairs used
+ hs->value -= hf->value;
+ hf->value = 0;
+ }
+ else if (hf->value > hs->value) {
+ // Take the minimal
+ count += hs->value;
+
+ // Subtract the pairs used
+ hf->value -= hs->value;
+ hs->value = 0;
+ }
+ else {
+ // Check if numbers are same
+ if (first == second) {
+
+ // If same then number of pairs will be half
+ count += it.item->value / 2;
+
+ // Check for remaining
+ hf->value = (it.item->key & 1);
+ }
+ else {
+ // Store the number of pairs
+ count += hf->value;
+ hf->value = 0;
+ hs->value = 0;
+ }
+ }
+ }
+ }
+
+ return count;
+}
+
+// Driver code
+int main()
+{
+ int n = sizeof(a) / sizeof(a[0]);
+ int k = 2;
+ printf("C : %d\n", findMaximumPairs(a, n, k));
+
+ return 0;
+}
+
+
+#else
+
+
+// C++ program to implement the above
+// approach
+#include <bits/stdc++.h>
+using namespace std;
+
+// Function to maximize the number of pairs
+int findMaximumPairs(int a[], int n, int k)
+{
+
+ // Hash-table
+ unordered_map<int, int> hash;
+ for (int i = 0; i < n; i++)
+ hash[a[i] % k]++;
+
+ int count = 0;
+
+ // Iterate for all numbers less than hash values
+ for (auto it : hash) {
+
+ // If the number is 0
+ if (it.first == 0) {
+
+ // We take half since same number
+ count += it.second / 2;
+ if (it.first % 2 == 0)
+ hash[it.first] = 0;
+ else
+ hash[it.first] = 1;
+ }
+ else {
+
+ int first = it.first;
+ int second = k - it.first;
+
+ // Check for minimal occurrence
+ if (hash[first] < hash[second]) {
+ // Take the minimal
+ count += hash[first];
+
+ // Subtract the pairs used
+ hash[second] -= hash[first];
+ hash[first] = 0;
+ }
+ else if (hash[first] > hash[second]) {
+ // Take the minimal
+ count += hash[second];
+
+ // Subtract the pairs used
+ hash[first] -= hash[second];
+ hash[second] = 0;
+ }
+ else {
+ // Check if numbers are same
+ if (first == second) {
+
+ // If same then number of pairs will be half
+ count += it.second / 2;
+
+ // Check for remaining
+ if (it.first % 2 == 0)
+ hash[it.first] = 0;
+ else
+ hash[it.first] = 1;
+ }
+ else {
+
+ // Store the number of pairs
+ count += hash[first];
+ hash[first] = 0;
+ hash[second] = 0;
+ }
+ }
+ }
+ }
+
+ return count;
+}
+
+// Driver code
+int main()
+{
+ int n = sizeof(a) / sizeof(a[0]);
+ int k = 2;
+ cout << "C++ : " << findMaximumPairs(a, n, k);
+
+ return 0;
+}
+
+#endif \ No newline at end of file
diff --git a/examples/geek2.c b/examples/geek2.c
new file mode 100644
index 00000000..53688dd3
--- /dev/null
+++ b/examples/geek2.c
@@ -0,0 +1,122 @@
+#ifndef __cplusplus
+
+#include <stc/chash.h>
+#include <stc/cstring.h>
+
+declare_CMap_str(ss, CStr, cstr_destroy);
+declare_CSet_str(ss);
+
+int main()
+{
+ // Lets use an explicit type signature (which would
+ // be `CMap<String, String>` in this example).
+ CMap_ss book_reviews = cmap_init;
+ CSet_ss set = cset_init;
+ cset_ss_put(&set, "Hello");
+ cset_ss_put(&set, "You");
+ cset_ss_put(&set, "Tube");
+ c_foreach (i, cset_ss, set)
+ printf("%s ", i.item->key.str); puts("");
+
+ // Review some books.
+ cmap_ss_put(&book_reviews,
+ "Adventures of Huckleberry Finn",
+ cstr_make("My favorite book.")
+ );
+ cmap_ss_put(&book_reviews,
+ "Grimms' Fairy Tales",
+ cstr_make("Masterpiece.")
+ );
+ cmap_ss_put(&book_reviews,
+ "Pride and Prejudice",
+ cstr_make("Very enjoyable.")
+ );
+ cmap_ss_put(&book_reviews,
+ "The Adventures of Sherlock Holmes",
+ cstr_make("Eye lyked it alot.")
+ );
+
+ // Check for a specific one.
+ // When collections store owned values (String), they can still be
+ // queried using references (&str).
+ if (! cmap_ss_get(&book_reviews, "Les Misérables")) {
+ printf("We've got %zu reviews, but Les Misérables ain't one.\n",
+ book_reviews.size);
+ }
+
+ // oops, this review has a lot of spelling mistakes, let's delete it.
+ cmap_ss_erase(&book_reviews, "The Adventures of Sherlock Holmes");
+
+ // Look up the values associated with some keys.
+ const char* to_find[] = {"Pride and Prejudice", "Alice's Adventure in Wonderland", NULL};
+ for (const char** book = to_find; *book; ++book) {
+ CMapEntry_ss* review = cmap_ss_get(&book_reviews, *book);
+ if (review) printf("%s: %s\n", *book, review->value.str);
+ else printf("%s is unreviewed.\n", *book);
+ }
+
+ // Look up the value for a key (will panic if the key is not found).
+ printf("Review for Jane: %s\n", cmap_ss_get(&book_reviews, "Pride and Prejudice")->value.str);
+
+ // Iterate over everything.
+ c_foreach (i, cmap_ss, book_reviews) {
+ printf("- %s: \"%s\"\n", i.item->key.str, i.item->value.str);
+ }
+ cmap_ss_destroy(&book_reviews);
+}
+
+#else // ======================================================
+
+use std::collections::HashMap;
+
+// Type inference lets us omit an explicit type signature (which
+// would be `HashMap<String, String>` in this example).
+let mut book_reviews = HashMap::new();
+
+// Review some books.
+book_reviews.insert(
+ "Adventures of Huckleberry Finn".to_str(),
+ "My favorite book.".to_str(),
+);
+book_reviews.insert(
+ "Grimms' Fairy Tales".to_str(),
+ "Masterpiece.".to_str(),
+);
+book_reviews.insert(
+ "Pride and Prejudice".to_str(),
+ "Very enjoyable.".to_str(),
+);
+book_reviews.insert(
+ "The Adventures of Sherlock Holmes".to_str(),
+ "Eye lyked it alot.".to_str(),
+);
+
+// Check for a specific one.
+// When collections store owned values (String), they can still be
+// queried using references (&str).
+if !book_reviews.contains_key("Les Misérables") {
+ println!("We've got {} reviews, but Les Misérables ain't one.",
+ book_reviews.len());
+}
+
+// oops, this review has a lot of spelling mistakes, let's delete it.
+book_reviews.remove("The Adventures of Sherlock Holmes");
+
+// Look up the values associated with some keys.
+let to_find = ["Pride and Prejudice", "Alice's Adventure in Wonderland"];
+for &book in &to_find {
+ match book_reviews.get(book) {
+ Some(review) => println!("{}: {}", book, review),
+ None => println!("{} is unreviewed.", book)
+ }
+}
+
+// Look up the value for a key (will panic if the key is not found).
+println!("Review for Jane: {}", book_reviews["Pride and Prejudice"]);
+
+// Iterate over everything.
+for (book, review) in &book_reviews {
+ println!("{}: \"{}\"", book, review);
+}
+
+#endif \ No newline at end of file
diff --git a/examples/geek3.c b/examples/geek3.c
new file mode 100644
index 00000000..ec58ccea
--- /dev/null
+++ b/examples/geek3.c
@@ -0,0 +1,50 @@
+// xx3.c
+
+#include <stc/chash.h>
+#include <stc/cstring.h>
+
+declare_CMap_str(si, int);
+declare_CMap_str(ss, CStr, cstr_destroy);
+
+int main ()
+{
+ CMap_si mymap = cmap_init;
+ cmap_si_put(&mymap, "Mars", 3000);
+ cmap_si_put(&mymap, "Saturn", 60000);
+ cmap_si_put(&mymap, "Jupiter", 70000);
+
+ // ...
+ cmap_si_put(&mymap, "Mars", 3396);
+ cmap_si_at(&mymap, "Saturn", 0)->value += 272;
+ cmap_si_put(&mymap, "Jupiter", cmap_si_at(&mymap, "Saturn", 0)->value + 9638);
+ cmap_si_at(&mymap, "Sun", 0)->value += 1000;
+ cmap_si_at(&mymap, "Sun", 0)->value += 1000;
+
+ c_foreach (x, cmap_si, mymap) {
+ printf("%s: %d\n", x.item->key.str, x.item->value);
+ }
+ cmap_si_destroy(&mymap);
+
+ puts("------------------------");
+
+ // Create an unordered_map of three strings (that map to strings)
+ CMap_ss u = cmap_init;
+ cmap_ss_put(&u, "RED", cstr_make("#FF0000"));
+ cmap_ss_put(&u, "GREEN", cstr_make("#00FF00"));
+ cmap_ss_put(&u, "BLUE", cstr_make("#0000FF"));
+
+ // Iterate and print keys and values of unordered_map
+ c_foreach (n, cmap_ss, u) {
+ printf("%s: %s\n", n.item->key.str, n.item->value.str);
+ }
+
+ // Add two new entries to the unordered_map
+ cmap_ss_put(&u, "BLACK", cstr_make("#000000"));
+ cmap_ss_put(&u, "WHITE", cstr_make("#FFFFFF"));
+
+ // Output values by key
+ printf("The HEX of color RED is:[%s]\n", cmap_ss_get(&u, "RED")->value.str);
+ printf("The HEX of color BLACK is:[%s]\n", cmap_ss_get(&u, "BLACK")->value.str);
+ cmap_ss_destroy(&u);
+ return 0;
+} \ No newline at end of file
diff --git a/examples/geek4.c b/examples/geek4.c
new file mode 100644
index 00000000..c514e601
--- /dev/null
+++ b/examples/geek4.c
@@ -0,0 +1,262 @@
+// https://www.geeksforgeeks.org/count-of-words-that-are-present-in-all-the-given-sentences/
+// https://www.geeksforgeeks.org/tag/cpp-unordered_map/
+/*
+Count of words that are present in all the given sentences
+Given n sentences. The task is to count the number of words that appear in all of these
+sentences. Note that every word consists of only lowercase English alphabets.
+
+Examples:
+
+Input: arr[] = {
+ "there is a cow",
+ "cow is our mother",
+ "cow gives us milk and milk is sweet",
+ "there is a boy who loves cow"}
+Output: 2
+Only the words "is" and "cow" appear in all of the sentences.
+
+Input: arr[] = {
+ "abc aac abcd ccc",
+ "ac aa abc cca",
+ "abca aaac abcd ccc"}
+Output: 0
+
+Naive Approach: The naive approach is to take every word of the first sentence and compare it
+ with rest of the lines if it is also present in all lines then increment the count.
+
+
+Efficient Approach: For all the words of the first sentence, we can check if it is also present in
+ all the other sentences in constant time by using a map. Store all the words
+ of the first sentence in a map and check how many of these stored words are
+ present in all of the other sentences.
+*/
+#ifndef __cplusplus
+// C implementation of the approach
+
+#include <stc/chash.h>
+#include <stc/cvector.h>
+#include <stc/cstring.h>
+
+declare_CVec_str(s);
+declare_CMap_str(sb, bool);
+declare_CVec(sb, CMapEntry_sb, cmapentry_sb_destroy, c_noCompare);
+
+// Function to return the count of common words
+// in all the sentences
+int commonWords(CVec_s S)
+{
+ int m, n, i, j;
+
+
+ // To store all the words of first string
+ CVec_sb ans = cvec_init;
+
+ // m will store number of strings in given vector
+ m = cvec_size(S);
+
+ i = 0;
+
+ // Extract all words of first string and store it in ans
+ while (i < cstr_size(S.data[0])) {
+ // To store separate words
+ CStr word = cstr_init;
+ CMapEntry_sb tmp = {cstr_init, false};
+
+ while (i < cstr_size(S.data[0]) && S.data[0].str[i] != ' ') {
+ cstr_appendC(&word, S.data[0].str[i]);
+ i++;
+ }
+
+ // Increase i to get at starting index
+ // of the next word
+ i++;
+
+ // If str is not empty store it in map
+ if (!cstr_empty(word)) {
+ tmp.key = cstr_move(&word);
+ tmp.value = true;
+ cvec_sb_pushBack(&ans, tmp);
+ }
+ }
+
+ // Start from 2nd line check if any word of
+ // the first string did not match with
+ // some word in the current line
+ for (j = 1; j < m; j++) {
+ // It will be used to check if a word is present
+ // in a particuler string
+ CMap_sb has = cmap_init;
+ i = 0;
+
+ while (i < cstr_size(S.data[j])) {
+ CStr word = cstr_init;
+ while (i < cstr_size(S.data[j]) && S.data[j].str[i] != ' ') {
+ cstr_appendC(&word, S.data[j].str[i]);
+ i++;
+ }
+ i++;
+ if (!cstr_empty(word)) {
+ cmap_sb_put(&has, word.str, true);
+ }
+ cstr_destroy(&word);
+ }
+
+ // Check all words of this vector
+ // if it is not present in current line
+ // make it false
+ for (int k = 0; k < cvec_size(ans); k++) {
+ if (ans.data[k].value != false
+ && cmap_sb_at(&has, ans.data[k].key.str, false)->value == false) {
+ ans.data[k].value = false;
+ }
+
+ // This line is used to consider only distinct words
+ else if (ans.data[k].value != false
+ && cmap_sb_at(&has, ans.data[k].key.str, false)->value == true) {
+ cmap_sb_put(&has, ans.data[k].key.str, false);
+ }
+ }
+ cmap_sb_destroy(&has);
+ }
+
+ // This function will print
+ // the count of common words
+ int cnt = 0;
+
+ // If current word appears in all the sentences
+ for (int k = 0; k < cvec_size(ans); k++) {
+ if (ans.data[k].value == true)
+ cnt++;
+ }
+
+ cvec_sb_destroy(&ans);
+ return cnt;
+}
+
+// Driver code
+int main()
+{
+ CVec_s S = cvec_init;
+ cvec_s_pushBack(&S, cstr_make("there is a cow"));
+ cvec_s_pushBack(&S, cstr_make("cow is our mother"));
+ cvec_s_pushBack(&S, cstr_make("cow gives us milk and milk is sweet"));
+ cvec_s_pushBack(&S, cstr_make("there is a boy who loves cow"));
+
+ printf("%d\n", commonWords(S));
+ cvec_s_destroy(&S);
+ return 0;
+}
+
+
+#else // ========================= c++ =======================
+
+
+// C++ implementation of the approach
+#include <bits/stdc++.h>
+using namespace std;
+
+// Function to return the count of common words
+// in all the sentences
+int commonWords(vector<string> S)
+{
+ int m, n, i, j;
+
+ // To store separate words
+ string word;
+
+ // It will be used to check if a word is present
+ // in a particuler string
+ unordered_map<string, bool> has;
+
+ // To store all the words of first string
+ vector<pair<string, bool> > ans;
+
+ pair<string, bool> tmp;
+
+ // m will store number of strings in given vector
+ m = S.size();
+
+ i = 0;
+
+ // Extract all words of first string and store it in ans
+ while (i < S[0].size()) {
+ word = "";
+ while (i < S[0].size() && S[0][i] != ' ') {
+ word += S[0][i];
+ i++;
+ }
+
+ // Increase i to get at starting index
+ // of the next word
+ i++;
+
+ // If word is not empty store it in map
+ if (word != "") {
+ tmp = make_pair(word, true);
+ ans.push_back(tmp);
+ }
+ }
+
+ // Start from 2nd line check if any word of
+ // the first string did not match with
+ // some word in the current line
+ for (j = 1; j < m; j++) {
+ has.clear();
+ i = 0;
+
+ while (i < S[j].size()) {
+ word = "";
+ while (i < S[j].size() && S[j][i] != ' ') {
+ word += S[j][i];
+ i++;
+ }
+ i++;
+ if (word != "") {
+ has[word] = true;
+ }
+ }
+
+ // Check all words of this vector
+ // if it is not present in current line
+ // make it false
+ for (int k = 0; k < ans.size(); k++) {
+ if (ans[k].second != false
+ && has[ans[k].first] == false) {
+ ans[k].second = false;
+ }
+
+ // This line is used to consider only distinct words
+ else if (ans[k].second != false
+ && has[ans[k].first] == true) {
+ has[ans[k].first] = false;
+ }
+ }
+ }
+
+ // This function will print
+ // the count of common words
+ int cnt = 0;
+
+ // If current word appears in all the sentences
+ for (int k = 0; k < ans.size(); k++) {
+ if (ans[k].second == true)
+ cnt++;
+ }
+
+ return cnt;
+}
+
+// Driver code
+int main()
+{
+ vector<string> S;
+ S.push_back("there is a cow");
+ S.push_back("cow is our mother");
+ S.push_back("cow gives us milk and milk is sweet");
+ S.push_back("there is a boy who loves cow");
+
+ cout << commonWords(S);
+
+ return 0;
+}
+#endif \ No newline at end of file
diff --git a/examples/geek5.c b/examples/geek5.c
new file mode 100644
index 00000000..759d22e3
--- /dev/null
+++ b/examples/geek5.c
@@ -0,0 +1,140 @@
+/*
+https://www.geeksforgeeks.org/number-of-times-the-given-string-occurs-in-the-array-in-the-range-l-r/
+
+Number of times the given string occurs in the array in the range [l, r]
+Given an array of strings arr[] and two integers l and r, the task is to find the number of times
+the given string str occurs in the array in the range [l, r] (1-based indexing). Note that the
+strings contain only lowercase letters.
+
+Examples:
+
+Input: arr[] = {"abc", "def", "abc"}, L = 1, R = 2, str = "abc"
+Output: 1
+
+Input: arr[] = {"abc", "def", "abc"}, L = 1, R = 3, str = "ghf"
+Output: 0
+*/
+
+#ifndef __cplusplus
+
+#include <stc/chash.h>
+#include <stc/cvector.h>
+#include <stc/cstring.h>
+
+declare_CVec(i, int);
+declare_CMap_str(sv, CVec_i, cvec_i_destroy);
+
+
+// Function to return the number of occurrences of
+int NumOccurrences(const char* arr[], int n, const char* str, int L, int R)
+{
+ // To store the indices of strings in the array
+ CMap_sv M = cmap_init;
+ for (int i = 0; i < n; i++) {
+ const char* temp = arr[i];
+ CMapEntry_sv* it = cmap_sv_get(&M, temp);
+
+ // If current string doesn't
+ // have an entry in the map
+ // then create the entry
+ if (it == NULL) {
+ CVec_i A = cvec_init;
+ cvec_i_pushBack(&A, i + 1);
+ cmap_sv_put(&M, temp, A);
+ }
+ else {
+ cvec_i_pushBack(&it->value, i + 1);
+ }
+ }
+
+ CMapEntry_sv* it = cmap_sv_get(&M, str);
+
+ // If the given string is not
+ // present in the array
+ if (it == NULL)
+ return 0;
+
+ // If the given string is present
+ // in the array
+ CVec_i A = it->value;
+ int y = 0, x = 0;
+ for (; y < cvec_size(A); ++y) if (A.data[y] > R) break;
+ for (; x < cvec_size(A); ++x) if (A.data[x] > L - 1) break;
+
+ cmap_sv_destroy(&M);
+ return (y - x);
+}
+
+// Driver code
+int main()
+{
+ const char* arr[] = { "abc", "abcabc", "abc" };
+ int n = sizeof(arr) / sizeof(*arr);
+ int L = 1;
+ int R = 3;
+ const char* str = "abc";
+
+ printf("%d\n", NumOccurrences(arr, n, str, L, R));
+
+ return 0;
+}
+
+#else // =============================== c++ ==================================
+
+// C++ implementation of the approach
+#include <bits/stdc++.h>
+using namespace std;
+
+// Function to return the number of occurrences of
+int NumOccurrences(string arr[], int n, string str, int L, int R)
+{
+ // To store the indices of strings in the array
+ unordered_map<string, vector<int> > M;
+ for (int i = 0; i < n; i++) {
+ string temp = arr[i];
+ auto it = M.find(temp);
+
+ // If current string doesn't
+ // have an entry in the map
+ // then create the entry
+ if (it == M.end()) {
+ vector<int> A;
+ A.push_back(i + 1);
+ M.insert(make_pair(temp, A));
+ }
+ else {
+ it->second.push_back(i + 1);
+ }
+ }
+
+ auto it = M.find(str);
+
+ // If the given string is not
+ // present in the array
+ if (it == M.end())
+ return 0;
+
+ // If the given string is present
+ // in the array
+ vector<int> A = it->second;
+ int y = upper_bound(A.begin(), A.end(), R) - A.begin();
+ int x = upper_bound(A.begin(), A.end(), L - 1) - A.begin();
+
+ return (y - x);
+}
+
+// Driver code
+int main()
+{
+ string arr[] = { "abc", "abcabc", "abc" };
+ int n = sizeof(arr) / sizeof(string);
+ int L = 1;
+ int R = 3;
+ string str = "abc";
+
+ cout << NumOccurrences(arr, n, str, L, R);
+
+ return 0;
+}
+
+#endif \ No newline at end of file
diff --git a/examples/geek6.c b/examples/geek6.c
new file mode 100644
index 00000000..369867e9
--- /dev/null
+++ b/examples/geek6.c
@@ -0,0 +1,124 @@
+// https://www.geeksforgeeks.org/find-the-smallest-positive-number-missing-from-an-unsorted-array-hashing-implementation/
+/*
+Find the smallest positive number missing from an unsorted array : Hashing Implementation
+Given an unsorted array with both positive and negative elements including 0. The task is
+to find the smallest positive number missing from the array in O(N) time.
+
+Examples:
+
+Input: arr[] = {-5, 2, 0, -1, -10, 15}
+Output: 1
+
+Input: arr[] = {0, 1, 2, 3, 4, 5}
+Output: 6
+
+Input: arr[] = {1, 1, 1, 0, -1, -2}
+Output: 2
+
+We can use hashing to solve this problem. The idea is to build a hash table of all positive
+elements in the given array. Once the hash table is built. We can look in the hash table for
+all positive integers, starting from 1. As soon as we find a number which is not there in the
+hash table, we return it.
+We can use the unordered_map in C++ to implement the hash which allow to perform look up
+operation in almost O(1) time complexity.
+*/
+
+#ifndef __cplusplus
+
+// C program to find the smallest
+// positive missing number
+
+#include <stdio.h>
+#include <stc/chash.h>
+declare_CSet(i, int);
+
+// Function to find the smallest positive
+// missing number
+int missingNumber(int a[], int n)
+{
+ // Declaring an unordered_map
+ CSet_i mp = cset_init;
+
+ // if array value is positive
+ // store it in map
+ for (int i = 0; i < n; i++) {
+ if (a[i] > 0)
+ cset_i_put(&mp, a[i]);
+ }
+
+ // index value set to 1
+ int index = 1;
+
+ // Return the first value starting
+ // from 1 which does not exists in map
+ while (1) {
+ if (cset_i_get(&mp, index) == NULL) {
+ return index;
+ }
+
+ index++;
+ }
+ cset_i_destroy(&mp);
+}
+
+// Driver code
+int main()
+{
+ int a[] = { 1, 1, 1, 0, -1, -2 };
+ int size = sizeof(a) / sizeof(a[0]);
+
+ printf("Smallest positive missing number is : %d\n",
+ missingNumber(a, size));
+
+ return 0;
+}
+
+#else
+
+// C++ program to find the smallest
+// positive missing number
+
+#include <bits/stdc++.h>
+using namespace std;
+
+// Function to find the smallest positive
+// missing number
+int missingNumber(int a[], int n)
+{
+ // Declaring an unordered_map
+ unordered_map<int, int> mp;
+
+ // if array value is positive
+ // store it in map
+ for (int i = 0; i < n; i++) {
+ if (a[i] > 0)
+ mp[a[i]]++;
+ }
+
+ // index value set to 1
+ int index = 1;
+
+ // Return the first value starting
+ // from 1 which does not exists in map
+ while (1) {
+ if (mp.find(index) == mp.end()) {
+ return index;
+ }
+
+ index++;
+ }
+}
+
+// Driver code
+int main()
+{
+ int a[] = { 1, 1, 1, 0, -1, -2 };
+ int size = sizeof(a) / sizeof(a[0]);
+
+ cout << "Smallest positive missing number is : "
+ << missingNumber(a, size) << endl;
+
+ return 0;
+}
+
+#endif \ No newline at end of file
diff --git a/examples/mapmap.c b/examples/mapmap.c
new file mode 100644
index 00000000..77c71fe9
--- /dev/null
+++ b/examples/mapmap.c
@@ -0,0 +1,20 @@
+
+#include <stdio.h>
+#include <stc/chash.h>
+
+static void test_destr(int* x) {
+ printf("destroy int: %d\n", *x);
+}
+
+declare_CMap(ii, int, int, test_destr);
+declare_CMap(im, int, CMap_ii, cmap_ii_destroy);
+
+int main(void) {
+ CMap_im m = cmap_init;
+ CMap_ii x = cmap_init;
+ cmap_ii_put(&cmap_im_put(&m, 100, x)->value, 200, 300);
+ cmap_ii_put(&cmap_im_get(&m, 100)->value, 200, 400); // update
+ cmap_ii_put(&cmap_im_put(&m, 110, x)->value, 200, 500);
+
+ cmap_im_destroy(&m);
+} \ No newline at end of file
diff --git a/examples/prime.c b/examples/prime.c
new file mode 100644
index 00000000..65b51057
--- /dev/null
+++ b/examples/prime.c
@@ -0,0 +1,45 @@
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "stc/cvector.h"
+
+static inline void setBit(uint32_t* a, const size_t i) { a[i >> 5] |= 1u << (i & 31); }
+static inline void clearBit(uint32_t* a, const size_t i) { a[i >> 5] &= ~(1u << (i & 31)); }
+static inline bool testBit(uint32_t* a, const size_t i) { return (a[i >> 5] & (1u << (i & 31))) != 0; }
+
+declare_CVec(i, uint32_t);
+
+static inline void sieveOfEratosthenes(size_t n)
+{
+ CVec_i prime = cvec_i_make((n >> 5) + 1, 0xffffffff);
+
+ printf("n: %zu, ints: %zu\n", n, cvec_size(prime));
+ clearBit(prime.data, 0);
+ clearBit(prime.data, 1);
+
+ for (size_t i = 2; i <= n; ++i)
+ {
+ // If prime[i] is not changed, then it is a prime
+ if (testBit(prime.data, i) && i*i <= n)
+ {
+ for (size_t j = i*i; j <= n; j += i) {
+ clearBit(prime.data, j);
+ }
+ }
+ }
+ puts("done");
+ // Print all prime numbers
+ size_t count = 0;
+ for (size_t i = 1; i <= n; ++i)
+ if (testBit(prime.data, i)) ++count; // printf("%zu\n", i);
+
+ printf("primes: %zu\n", count);
+ cvec_i_destroy(&prime);
+}
+
+int main(void)
+{
+ sieveOfEratosthenes(1000000000);
+} \ No newline at end of file