commit 3b313daec1614d8a3288b8e20a06dc912a59bda8
parent 4abb81c230bfcd599ccceb2b1bcbdcadbd859537
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date: Sat, 13 Jul 2024 08:03:20 +0200
Added a set implementation for h48 table generation
Diffstat:
6 files changed, 391 insertions(+), 0 deletions(-)
diff --git a/src/solve_h48.h b/src/solve_h48.h
@@ -24,6 +24,13 @@
#define MAX_SOLUTION_LENGTH 20
typedef struct {
+ int64_t n;
+ int64_t capacity;
+ int64_t mod;
+ int64_t *table;
+} h48set_t;
+
+typedef struct {
cube_t cube;
uint8_t depth;
uint8_t maxdepth;
@@ -66,6 +73,13 @@ typedef struct {
char *s;
} dfsarg_solveh48stats_t;
+_static void h48set_create(h48set_t *, int64_t, int64_t);
+_static void h48set_clear(h48set_t *);
+_static void h48set_destroy(h48set_t *);
+_static_inline int64_t h48set_lookup(h48set_t *, int64_t);
+_static_inline void h48set_insert(h48set_t *, int64_t);
+_static_inline bool h48set_contains(h48set_t *, int64_t);
+
_static_inline int64_t coord_h48(cube_t, const uint32_t *, uint8_t);
_static_inline int64_t coord_h48_edges(cube_t, int64_t, uint8_t, uint8_t);
_static_inline cube_t invcoord_h48(int64_t, const cube_t *, uint8_t);
@@ -90,6 +104,69 @@ _static int64_t solve_h48(cube_t, int8_t, int8_t, int8_t, uint8_t, const void *,
_static int64_t solve_h48stats_dfs(dfsarg_solveh48stats_t *);
_static int64_t solve_h48stats(cube_t, int8_t, const void *, char [static 12]);
+_static void
+h48set_create(h48set_t *set, int64_t capacity, int64_t mod)
+{
+ set->capacity = capacity;
+ set->mod = mod;
+
+ set->table = malloc(set->capacity * sizeof(int64_t));
+ h48set_clear(set);
+}
+
+_static void
+h48set_clear(h48set_t *set)
+{
+ int64_t i;
+
+ for (i = 0; i < set->capacity; i++)
+ set->table[i] = -1;
+
+ set->n = 0;
+}
+
+_static void
+h48set_destroy(h48set_t *set)
+{
+ free(set->table);
+}
+
+/* Returns the index in where x should be inserted, or -1 if x is in the set */
+_static_inline int64_t
+h48set_lookup(h48set_t *set, int64_t x)
+{
+ int64_t hash, i;
+
+ hash = ((x % set->capacity) * set->mod) % set->capacity;
+ for (i = hash; set->table[i] != -1; i = (i+1) % set->capacity)
+ if (set->table[i] == x)
+ return -1;
+
+ return i;
+}
+
+_static_inline void
+h48set_insert(h48set_t *set, int64_t x)
+{
+ int64_t i;
+
+ i = h48set_lookup(set, x);
+ if (i != -1) {
+ set->table[i] = x;
+ set->n++;
+ }
+}
+
+_static_inline bool
+h48set_contains(h48set_t *set, int64_t x)
+{
+ int64_t i;
+
+ i = h48set_lookup(set, x);
+
+ return i == -1;
+}
+
_static_inline int64_t
coord_h48(cube_t c, const uint32_t *cocsepdata, uint8_t h)
{
diff --git a/test/104_h48set/00_small.in b/test/104_h48set/00_small.in
@@ -0,0 +1,6 @@
+11
+7
+3
+34
+45
+34
diff --git a/test/104_h48set/00_small.out b/test/104_h48set/00_small.out
@@ -0,0 +1,3 @@
+2
+34
+45
diff --git a/test/104_h48set/01_large.in b/test/104_h48set/01_large.in
@@ -0,0 +1,153 @@
+307
+293
+150
+100053
+100045
+100007
+100007
+100011
+100072
+100033
+100015
+100013
+100068
+100047
+100046
+100000
+100076
+100021
+100019
+100015
+100049
+100052
+100071
+100058
+100009
+100060
+100030
+100051
+100069
+100011
+100051
+100014
+100031
+100017
+100076
+100016
+100030
+100037
+100011
+100002
+100029
+100022
+100038
+100075
+100066
+100051
+100020
+100039
+100029
+100087
+100099
+100041
+100042
+100026
+100060
+100006
+100010
+100079
+100046
+100086
+100010
+100036
+100047
+100069
+100041
+100074
+100090
+100092
+100020
+100096
+100046
+100028
+100072
+100096
+100025
+100001
+100067
+100044
+100063
+100026
+100062
+100091
+100012
+100073
+100051
+100010
+100096
+100043
+100025
+100077
+100089
+100005
+100024
+100091
+100046
+100053
+100058
+100065
+100051
+100056
+100025
+100093
+100088
+100033
+100073
+100048
+100059
+100027
+100045
+100012
+100059
+100084
+100017
+100048
+100004
+100051
+100016
+100088
+100033
+100064
+100060
+100043
+100084
+100026
+100051
+100060
+100069
+100015
+100014
+100038
+100068
+100038
+100097
+100017
+100013
+100053
+100019
+100018
+100081
+100071
+100025
+100014
+100016
+100011
+100069
+100079
+100063
+100070
+100072
+100095
+100042
+100008
+100022
diff --git a/test/104_h48set/01_large.out b/test/104_h48set/01_large.out
@@ -0,0 +1,83 @@
+82
+100000
+100001
+100002
+100004
+100005
+100006
+100007
+100008
+100009
+100010
+100011
+100012
+100013
+100014
+100015
+100016
+100017
+100018
+100019
+100020
+100021
+100022
+100024
+100025
+100026
+100027
+100028
+100029
+100030
+100031
+100033
+100036
+100037
+100038
+100039
+100041
+100042
+100043
+100044
+100045
+100046
+100047
+100048
+100049
+100051
+100052
+100053
+100056
+100058
+100059
+100060
+100062
+100063
+100064
+100065
+100066
+100067
+100068
+100069
+100070
+100071
+100072
+100073
+100074
+100075
+100076
+100077
+100079
+100081
+100084
+100086
+100087
+100088
+100089
+100090
+100091
+100092
+100093
+100095
+100096
+100097
+100099
diff --git a/test/104_h48set/h48set_tests.c b/test/104_h48set/h48set_tests.c
@@ -0,0 +1,69 @@
+#include "../test.h"
+
+char str[STRLENMAX];
+
+typedef struct {
+ int64_t n;
+ int64_t capacity;
+ int64_t mod;
+ int64_t *table;
+} h48set_t;
+
+void h48set_create(h48set_t *, int64_t, int64_t);
+void h48set_clear(h48set_t *);
+void h48set_destroy(h48set_t *);
+int64_t h48set_lookup(h48set_t *, int64_t);
+void h48set_insert(h48set_t *, int64_t);
+bool h48set_contains(h48set_t *, int64_t);
+
+int compare(const void *x, const void *y) {
+ int64_t a = *(int64_t *)x;
+ int64_t b = *(int64_t *)y;
+
+ if (a > b) return 1;
+ if (a == b) return 0;
+ return -1;
+}
+
+int64_t readl(void) {
+ fgets(str, STRLENMAX, stdin);
+ return atoll(str);
+}
+
+void run(void) {
+ bool f;
+ h48set_t set;
+ int64_t n, i, j, capacity, mod, *a, u;
+
+ capacity = readl();
+ mod = readl();
+ n = readl();
+
+ a = malloc(n * sizeof(int64_t));
+ for (i = 0; i < n; i++)
+ a[i] = readl();
+
+ /* Count unique elements */
+ u = 0;
+ for (i = 0; i < n; i++) {
+ for (j = 0, f = true; j < i; j++)
+ f = f && a[i] != a[j];
+ u += f;
+ }
+
+ h48set_create(&set, capacity, mod);
+ for (i = 0; i < n; i++)
+ h48set_insert(&set, a[i]);
+
+ for (i = 0, j = 0; i < set.capacity; i++)
+ if (set.table[i] != -1)
+ a[j++] = set.table[i];
+ qsort(a, j, sizeof(int64_t), compare);
+
+ printf("%" PRId64 "\n", set.n);
+ for (i = 0; i < j; i++)
+ printf("%" PRId64 "\n", a[i]);
+
+ h48set_destroy(&set);
+ free(a);
+}