diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/solve_h48.h | 180 | ||||
| -rw-r--r-- | src/utils.h | 2 |
2 files changed, 119 insertions, 63 deletions
diff --git a/src/solve_h48.h b/src/solve_h48.h index ed63209..c7cc91c 100644 --- a/src/solve_h48.h +++ b/src/solve_h48.h | |||
| @@ -1,3 +1,7 @@ | |||
| 1 | #define MAP_UNSET UINT64_C(0xFFFFFFFFFFFFFFFF) | ||
| 2 | #define MAP_KEYMASK UINT64_C(0xFFFFFFFFFF) | ||
| 3 | #define MAP_KEYSHIFT UINT64_C(40) | ||
| 4 | |||
| 1 | #define COCSEP_CLASSES ((size_t)3393) | 5 | #define COCSEP_CLASSES ((size_t)3393) |
| 2 | #define COCSEP_TABLESIZE ((size_t)_3p7 << (size_t)7) | 6 | #define COCSEP_TABLESIZE ((size_t)_3p7 << (size_t)7) |
| 3 | #define COCSEP_VISITEDSIZE ((COCSEP_TABLESIZE + (size_t)7) / (size_t)8) | 7 | #define COCSEP_VISITEDSIZE ((COCSEP_TABLESIZE + (size_t)7) / (size_t)8) |
| @@ -24,11 +28,16 @@ | |||
| 24 | #define MAX_SOLUTION_LENGTH 20 | 28 | #define MAX_SOLUTION_LENGTH 20 |
| 25 | 29 | ||
| 26 | typedef struct { | 30 | typedef struct { |
| 27 | int64_t n; | 31 | uint64_t n; |
| 28 | int64_t capacity; | 32 | uint64_t capacity; |
| 29 | int64_t mod; | 33 | uint64_t mod; |
| 30 | int64_t *table; | 34 | uint64_t *table; |
| 31 | } h48set_t; | 35 | } h48map_t; |
| 36 | |||
| 37 | typedef struct { | ||
| 38 | uint64_t key; | ||
| 39 | uint64_t val; | ||
| 40 | } kvpair_t; | ||
| 32 | 41 | ||
| 33 | typedef struct { | 42 | typedef struct { |
| 34 | cube_t cube; | 43 | cube_t cube; |
| @@ -41,6 +50,16 @@ typedef struct { | |||
| 41 | cube_t *rep; | 50 | cube_t *rep; |
| 42 | } dfsarg_cocsep_t; | 51 | } dfsarg_cocsep_t; |
| 43 | 52 | ||
| 53 | /* TODO keep or not? */ | ||
| 54 | typedef struct { | ||
| 55 | cube_t cube; | ||
| 56 | int8_t nmoves; | ||
| 57 | int8_t depth; | ||
| 58 | uint8_t moves[MAX_SOLUTION_LENGTH]; | ||
| 59 | uint32_t *cocsepdata; | ||
| 60 | h48map_t *visited; | ||
| 61 | } dfsarg_genh48set_t; | ||
| 62 | |||
| 44 | typedef struct { | 63 | typedef struct { |
| 45 | uint8_t depth; | 64 | uint8_t depth; |
| 46 | uint32_t *cocsepdata; | 65 | uint32_t *cocsepdata; |
| @@ -74,30 +93,31 @@ typedef struct { | |||
| 74 | char *s; | 93 | char *s; |
| 75 | } dfsarg_solveh48stats_t; | 94 | } dfsarg_solveh48stats_t; |
| 76 | 95 | ||
| 77 | _static void h48set_create(h48set_t *, int64_t, int64_t); | 96 | _static void h48map_create(h48map_t *, uint64_t, uint64_t); |
| 78 | _static void h48set_clear(h48set_t *); | 97 | _static void h48map_clear(h48map_t *); |
| 79 | _static void h48set_destroy(h48set_t *); | 98 | _static void h48map_destroy(h48map_t *); |
| 80 | _static_inline int64_t h48set_lookup(h48set_t *, int64_t); | 99 | _static uint64_t h48map_lookup(h48map_t *, uint64_t); |
| 81 | _static_inline void h48set_insert(h48set_t *, int64_t); | 100 | _static void h48map_insertmin(h48map_t *, uint64_t, uint64_t); |
| 82 | _static_inline bool h48set_contains(h48set_t *, int64_t); | 101 | _static uint64_t h48map_value(h48map_t *, uint64_t); |
| 83 | _static inline int64_t h48set_save(h48set_t *, int64_t *); | 102 | _static kvpair_t h48map_nextkvpair(h48map_t *, uint64_t *); |
| 84 | 103 | ||
| 85 | _static_inline int64_t coord_h48(cube_t, const uint32_t *, uint8_t); | 104 | _static_inline int64_t coord_h48(cube_t, const uint32_t *, uint8_t); |
| 86 | _static_inline int64_t coord_h48_edges(cube_t, int64_t, uint8_t, uint8_t); | 105 | _static_inline int64_t coord_h48_edges(cube_t, int64_t, uint8_t, uint8_t); |
| 87 | _static_inline cube_t invcoord_h48(int64_t, const cube_t *, uint8_t); | 106 | _static_inline cube_t invcoord_h48(int64_t, const cube_t *, uint8_t); |
| 88 | 107 | ||
| 108 | _static_inline bool get_visited(const uint8_t *, int64_t); | ||
| 109 | _static_inline void set_visited(uint8_t *, int64_t); | ||
| 110 | _static_inline uint8_t get_esep_pval(const uint32_t *, int64_t); | ||
| 111 | _static_inline void set_esep_pval(uint32_t *, int64_t, uint8_t); | ||
| 112 | |||
| 89 | _static size_t gendata_cocsep(void *, uint64_t *, cube_t *); | 113 | _static size_t gendata_cocsep(void *, uint64_t *, cube_t *); |
| 90 | _static uint32_t gendata_cocsep_dfs(dfsarg_cocsep_t *); | 114 | _static uint32_t gendata_cocsep_dfs(dfsarg_cocsep_t *); |
| 115 | _static int64_t gen_h48map_short(uint8_t, const uint32_t *, h48map_t *); | ||
| 91 | _static size_t gendata_h48h0k4(void *, uint8_t); | 116 | _static size_t gendata_h48h0k4(void *, uint8_t); |
| 92 | _static int64_t gendata_h48h0k4_bfs(bfsarg_esep_t *); | 117 | _static int64_t gendata_h48h0k4_bfs(bfsarg_esep_t *); |
| 93 | _static int64_t gendata_h48h0k4_bfs_fromdone(bfsarg_esep_t *); | 118 | _static int64_t gendata_h48h0k4_bfs_fromdone(bfsarg_esep_t *); |
| 94 | _static int64_t gendata_h48h0k4_bfs_fromnew(bfsarg_esep_t *); | 119 | _static int64_t gendata_h48h0k4_bfs_fromnew(bfsarg_esep_t *); |
| 95 | 120 | ||
| 96 | _static_inline bool get_visited(const uint8_t *, int64_t); | ||
| 97 | _static_inline void set_visited(uint8_t *, int64_t); | ||
| 98 | _static_inline uint8_t get_esep_pval(const uint32_t *, int64_t); | ||
| 99 | _static_inline void set_esep_pval(uint32_t *, int64_t, uint8_t); | ||
| 100 | |||
| 101 | _static void solve_h48_appendsolution(dfsarg_solveh48_t *); | 121 | _static void solve_h48_appendsolution(dfsarg_solveh48_t *); |
| 102 | _static_inline int8_t get_h48_cdata(cube_t, uint32_t *, uint32_t *); | 122 | _static_inline int8_t get_h48_cdata(cube_t, uint32_t *, uint32_t *); |
| 103 | _static_inline int8_t get_h48_bound(cube_t, uint32_t, uint8_t, uint32_t *); | 123 | _static_inline int8_t get_h48_bound(cube_t, uint32_t, uint8_t, uint32_t *); |
| @@ -109,78 +129,84 @@ _static int64_t solve_h48stats_dfs(dfsarg_solveh48stats_t *); | |||
| 109 | _static int64_t solve_h48stats(cube_t, int8_t, const void *, char [static 12]); | 129 | _static int64_t solve_h48stats(cube_t, int8_t, const void *, char [static 12]); |
| 110 | 130 | ||
| 111 | _static void | 131 | _static void |
| 112 | h48set_create(h48set_t *set, int64_t capacity, int64_t mod) | 132 | h48map_create(h48map_t *map, uint64_t capacity, uint64_t mod) |
| 113 | { | 133 | { |
| 114 | set->capacity = capacity; | 134 | map->capacity = capacity; |
| 115 | set->mod = mod; | 135 | map->mod = mod; |
| 116 | 136 | ||
| 117 | set->table = malloc(set->capacity * sizeof(int64_t)); | 137 | map->table = malloc(map->capacity * sizeof(int64_t)); |
| 118 | h48set_clear(set); | 138 | h48map_clear(map); |
| 119 | } | 139 | } |
| 120 | 140 | ||
| 121 | _static void | 141 | _static void |
| 122 | h48set_clear(h48set_t *set) | 142 | h48map_clear(h48map_t *map) |
| 123 | { | 143 | { |
| 124 | int64_t i; | 144 | memset(map->table, 0xFF, map->capacity * sizeof(uint64_t)); |
| 125 | 145 | map->n = 0; | |
| 126 | for (i = 0; i < set->capacity; i++) | ||
| 127 | set->table[i] = -1; | ||
| 128 | |||
| 129 | set->n = 0; | ||
| 130 | } | 146 | } |
| 131 | 147 | ||
| 132 | _static void | 148 | _static void |
| 133 | h48set_destroy(h48set_t *set) | 149 | h48map_destroy(h48map_t *map) |
| 134 | { | 150 | { |
| 135 | free(set->table); | 151 | free(map->table); |
| 136 | } | 152 | } |
| 137 | 153 | ||
| 138 | /* Returns the index in where x should be inserted, or -1 if x is in the set */ | 154 | _static_inline uint64_t |
| 139 | _static_inline int64_t | 155 | h48map_lookup(h48map_t *map, uint64_t x) |
| 140 | h48set_lookup(h48set_t *set, int64_t x) | ||
| 141 | { | 156 | { |
| 142 | int64_t hash, i; | 157 | uint64_t hash, i; |
| 143 | 158 | ||
| 144 | hash = ((x % set->capacity) * set->mod) % set->capacity; | 159 | hash = ((x % map->capacity) * map->mod) % map->capacity; |
| 145 | for (i = hash; set->table[i] != -1; i = (i+1) % set->capacity) | 160 | for (i = hash; |
| 146 | if (set->table[i] == x) | 161 | map->table[i] != MAP_UNSET && (map->table[i] & MAP_KEYMASK) != x; |
| 147 | return -1; | 162 | i = (i+1) % map->capacity |
| 163 | ) ; | ||
| 148 | 164 | ||
| 149 | return i; | 165 | return i; |
| 150 | } | 166 | } |
| 151 | 167 | ||
| 152 | _static_inline void | 168 | _static_inline void |
| 153 | h48set_insert(h48set_t *set, int64_t x) | 169 | h48map_insertmin(h48map_t *map, uint64_t key, uint64_t val) |
| 154 | { | 170 | { |
| 155 | int64_t i; | 171 | uint64_t i, oldval, min; |
| 156 | 172 | ||
| 157 | i = h48set_lookup(set, x); | 173 | i = h48map_lookup(map, key); |
| 158 | if (i != -1) { | 174 | oldval = map->table[i] >> MAP_KEYSHIFT; |
| 159 | set->table[i] = x; | 175 | min = _min(val, oldval); |
| 160 | set->n++; | 176 | |
| 161 | } | 177 | map->n += map->table[i] == MAP_UNSET; |
| 178 | map->table[i] = (key & MAP_KEYMASK) | (min << MAP_KEYSHIFT); | ||
| 162 | } | 179 | } |
| 163 | 180 | ||
| 164 | _static_inline bool | 181 | _static_inline uint64_t |
| 165 | h48set_contains(h48set_t *set, int64_t x) | 182 | h48map_value(h48map_t *map, uint64_t key) |
| 166 | { | 183 | { |
| 167 | int64_t i; | 184 | return map->table[h48map_lookup(map, key)] >> MAP_KEYSHIFT; |
| 168 | |||
| 169 | i = h48set_lookup(set, x); | ||
| 170 | |||
| 171 | return i == -1; | ||
| 172 | } | 185 | } |
| 173 | 186 | ||
| 174 | _static int64_t | 187 | _static kvpair_t |
| 175 | h48set_save(h48set_t *set, int64_t *a) | 188 | h48map_nextkvpair(h48map_t *map, uint64_t *p) |
| 176 | { | 189 | { |
| 177 | int64_t i, j; | 190 | kvpair_t kv; |
| 191 | uint64_t pair; | ||
| 192 | |||
| 193 | kv.key = MAP_UNSET; | ||
| 194 | kv.val = MAP_UNSET; | ||
| 178 | 195 | ||
| 179 | for (i = 0, j = 0; i < set->capacity; i++) | 196 | DBG_ASSERT(*p < map->capacity, kv, |
| 180 | if (set->table[i] != -1) | 197 | "Error looping over map: given index %" PRIu64 " is out of " |
| 181 | a[j++] = set->table[i]; | 198 | "range [0,%" PRIu64 "]", *p, map->capacity); |
| 182 | 199 | ||
| 183 | return j; | 200 | for ( ; *p < map->capacity; (*p)++) { |
| 201 | if (map->table[*p] != MAP_UNSET) { | ||
| 202 | pair = map->table[(*p)++]; | ||
| 203 | kv.key = pair & MAP_KEYMASK; | ||
| 204 | kv.val = pair >> MAP_KEYSHIFT; | ||
| 205 | return kv; | ||
| 206 | } | ||
| 207 | } | ||
| 208 | |||
| 209 | return kv; | ||
| 184 | } | 210 | } |
| 185 | 211 | ||
| 186 | _static_inline int64_t | 212 | _static_inline int64_t |
| @@ -358,6 +384,34 @@ gendata_cocsep_dfs(dfsarg_cocsep_t *arg) | |||
| 358 | return cc; | 384 | return cc; |
| 359 | } | 385 | } |
| 360 | 386 | ||
| 387 | _static int64_t | ||
| 388 | gen_h48map_short(uint8_t n, const uint32_t *cocsepdata, h48map_t *map) | ||
| 389 | { | ||
| 390 | /* | ||
| 391 | uint8_t i, j, m; | ||
| 392 | int64_t coord; | ||
| 393 | cube_t cube, d; | ||
| 394 | |||
| 395 | cube = solvedcube(); | ||
| 396 | coord = coord_h48(cube, cocsepdata, 11); | ||
| 397 | for (i = 0; i < n; i++) { | ||
| 398 | for (j = 0; (coord = h48map_next(map, &j)) != -1; ) { | ||
| 399 | cube = invcoord_h48(coord, cocsepdata, 11); | ||
| 400 | for (m = 0; m < 18; m++) { | ||
| 401 | d = move(cube, m); | ||
| 402 | TODO | ||
| 403 | } | ||
| 404 | } | ||
| 405 | } | ||
| 406 | */ | ||
| 407 | } | ||
| 408 | |||
| 409 | _static int64_t | ||
| 410 | gen_h48set_short_dfs(dfsarg_genh48set_t *arg) | ||
| 411 | { | ||
| 412 | /* TODO */ | ||
| 413 | } | ||
| 414 | |||
| 361 | /* | 415 | /* |
| 362 | TODO description | 416 | TODO description |
| 363 | generating fixed table with h=0, k=4 | 417 | generating fixed table with h=0, k=4 |
| @@ -756,9 +810,9 @@ solve_h48stats( | |||
| 756 | for (i = 0; i < 12; i++) | 810 | for (i = 0; i < 12; i++) |
| 757 | solutions[i] = (char)99; | 811 | solutions[i] = (char)99; |
| 758 | 812 | ||
| 759 | for (arg.depth = 0; | 813 | for (arg.depth = 0; |
| 760 | arg.depth <= maxmoves && solutions[11] == 99; | 814 | arg.depth <= maxmoves && solutions[11] == 99; |
| 761 | arg.depth++) | 815 | arg.depth++) |
| 762 | { | 816 | { |
| 763 | arg.nmoves = 0; | 817 | arg.nmoves = 0; |
| 764 | solve_h48stats_dfs(&arg); | 818 | solve_h48stats_dfs(&arg); |
diff --git a/src/utils.h b/src/utils.h index 021ca75..87402e6 100644 --- a/src/utils.h +++ b/src/utils.h | |||
| @@ -1,4 +1,6 @@ | |||
| 1 | #define _swap(x, y) do { x ^= y; y ^= x; x ^= y; } while (0) | 1 | #define _swap(x, y) do { x ^= y; y ^= x; x ^= y; } while (0) |
| 2 | #define _min(x, y) ((x) < (y) ? (x) : (y)) | ||
| 3 | #define _max(x, y) ((x) > (y) ? (x) : (y)) | ||
| 2 | 4 | ||
| 3 | _static int64_t factorial(int64_t); | 5 | _static int64_t factorial(int64_t); |
| 4 | _static bool isperm(uint8_t *, int64_t); | 6 | _static bool isperm(uint8_t *, int64_t); |
