h48

A prototype for an optimal Rubik's cube solver, work in progress.
git clone https://git.tronto.net/h48
Download | Log | Files | Refs | README | LICENSE

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:
Msrc/solve_h48.h | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atest/104_h48set/00_small.in | 6++++++
Atest/104_h48set/00_small.out | 3+++
Atest/104_h48set/01_large.in | 153+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atest/104_h48set/01_large.out | 83+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atest/104_h48set/h48set_tests.c | 69+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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); +}