aboutsummaryrefslogtreecommitdiff
path: root/old/2021-02-28-transformcube-works/src/solve.c
diff options
context:
space:
mode:
Diffstat (limited to 'old/2021-02-28-transformcube-works/src/solve.c')
-rw-r--r--old/2021-02-28-transformcube-works/src/solve.c180
1 files changed, 0 insertions, 180 deletions
diff --git a/old/2021-02-28-transformcube-works/src/solve.c b/old/2021-02-28-transformcube-works/src/solve.c
deleted file mode 100644
index 07c9075..0000000
--- a/old/2021-02-28-transformcube-works/src/solve.c
+++ /dev/null
@@ -1,180 +0,0 @@
1#include "solve.h"
2
3/* Data for creating a pruning table:
4 - compressed: if set to true, each entry occupies only 4 bits, but values
5 larger than 15 cannot be stored.
6 - available[] is the list of availabel moves, as above.
7 - *ptable is the actual table to fill.
8 - n is the number of states (size of ptable).
9 - index must "linearize" the cube, i.e. return its index in ptable.
10 - fname is the name of the file where to store the table */
11typedef struct {
12 bool compressed, *available;
13 int max_moves;
14 uint8_t *ptable;
15 uint64_t n;
16 uint64_t (*index)(Cube);
17 char *fname;
18} PruneData;
19
20/* TODO: comment this */
21typedef struct {
22 bool niss;
23 int m, d;
24 uint64_t *n;
25 Move last1, last2;
26} DfsData;
27
28void solve_dfs(Cube cube, SolveData *sd, DfsData dd);
29void init_ptable(PruneData *pd, bool read, bool write);
30
31/* Search solutions of lenght exactly d */
32void solve_dfs(Cube cube, SolveData *sd, DfsData dd) {
33 if (*dd.n >= sd->max_solutions ||
34 ((!sd->can_niss || dd.niss) && dd.m + sd->f(cube) > dd.d))
35 return;
36
37 (sd->solutions[*dd.n][dd.m]).inverse = dd.niss;
38 (sd->solutions[*dd.n][dd.m]).m = NULLMOVE;
39
40 if (!sd->f(cube)) { /* Solved */
41 if (dd.m == dd.d) {
42 (*dd.n)++;
43 if (*dd.n < sd->max_solutions)
44 copy_alg(sd->solutions[*dd.n-1], sd->solutions[*dd.n]);
45 }
46 return;
47 }
48
49 for (int i = 0; i < NMOVES && sd->sorted_moves[i] != NULLMOVE; i++) {
50 Move move = sd->sorted_moves[i];
51 if (possible_next[dd.last2][dd.last1][move]) {
52 sd->solutions[*dd.n][dd.m].inverse = dd.niss;
53 sd->solutions[*dd.n][dd.m].m = move;
54 DfsData nn = { .niss = dd.niss, .m = dd.m+1, .d = dd.d, .n = dd.n,
55 .last1 = move, .last2 = dd.last1 };
56 solve_dfs(move_cube(move, cube), sd, nn);
57 }
58 }
59
60 if (sd->can_niss && !dd.niss &&
61 (!dd.m || (dd.m && sd->f(move_cube(dd.last1, (Cube){0}))))) {
62 DfsData nn = { .niss = true, .m = dd.m, .d = dd.d, .n = dd.n };
63 solve_dfs(inverse_cube(cube), sd, nn);
64 }
65}
66
67/* Iterative deepening depth-first search: for i running from the minimum
68 to the maximum number of moves allowed, looks for solutions of length i. */
69int solve(Cube cube, SolveData *sd) {
70 if (sd->precondition != NULL && !sd->precondition(cube))
71 return -1;
72
73 /* If not given, generate sorted list of moves */
74 if (sd->sorted_moves[0] == NULLMOVE) {
75 int a[NMOVES], b[NMOVES], ia = 0, ib = 0;
76 for (int i = 0; i < NMOVES; i++) {
77 if (sd->available[i]) {
78 if (sd->f(move_cube(i, (Cube){0})))
79 a[ia++] = i;
80 else
81 b[ib++] = i;
82 }
83 }
84 intarrcopy(a, (int *)sd->sorted_moves, ia);
85 intarrcopy(b, (int *)sd->sorted_moves+ia, ib);
86 sd->sorted_moves[ia+ib] = NULLMOVE;
87 }
88
89 sd->max_solutions = min(sd->max_solutions, MAXS);
90 /*TODO
91 Cube rotated = apply_alg(sd->pre_rotation, (Cube){0});
92 cube = apply_alg(inverse_cube(rotated), compose(cube, rotated));
93 */
94
95 uint64_t ret = 0;
96 for (int i=sd->min_moves; i<=sd->max_moves&&!(ret&&sd->optimal_only); i++) {
97 DfsData dd = { .d = i, .n = &ret };
98 solve_dfs(cube, sd, dd);
99 }
100
101 /* TODO: transform solutions with inverse of pre_rotation */
102 /*
103 for (uint64_t i = 0; i < ret; i++) {
104 if (sd->cleanup)
105 cleanup(sd->solutions[i], sd->max_moves*3);
106 }*/
107
108 return ret;
109}
110
111void prune_dfs(Cube cube, PruneData *pd, DfsData dd) {
112 uint64_t ind = pd->index(cube);
113 if ((!ind || pd->ptable[ind]) && pd->ptable[ind] != dd.m)
114 return;
115 if (dd.m == dd.d) {
116 if (ind && !pd->ptable[ind]) {
117 pd->ptable[ind] = dd.m;
118 (*dd.n)++;
119 }
120 return;
121 }
122
123 for (int i = 0; i < NMOVES; i++) {
124 if (dd.m<20)
125 if (possible_next[dd.last2][dd.last1][i] && pd->available[i]) {
126 DfsData nn = { .m = dd.m+1, .d = dd.d, .n = dd.n,
127 .last1 = i, .last2 = dd.last1 };
128 prune_dfs(move_cube(i, cube), pd, nn);
129 }
130 }
131}
132
133void init_ptable(PruneData *pd, bool read, bool write) {
134 if (read) {
135 FILE *ptf;
136 if ((ptf = fopen(pd->fname, "rb")) != NULL) {
137 uint64_t r = fread(pd->ptable, sizeof(uint8_t), pd->n, ptf);
138 fclose(ptf);
139 if (r == pd->n) return;
140 }
141 }
142
143 /* TODO: for now it behaves always as if copressed = false */
144 for (uint64_t i = 0; i < pd->n; i++)
145 pd->ptable[i] = 0;
146
147 uint64_t s = 1;
148 for (int i = 1; i < pd->max_moves && s < pd->n; i++) {
149 DfsData dd = { .d = i, .n = &s };
150 prune_dfs((Cube){0}, pd, dd);
151 }
152
153 if (write) {
154 FILE *ptf;
155 if ((ptf = fopen(pd->fname, "wb")) != NULL) {
156 fwrite(pd->ptable, sizeof(uint8_t), pd->n, ptf);
157 fclose(ptf);
158 return;
159 }
160 }
161}
162
163/* Solving steps (and indexing functions) */
164
165uint64_t index_eofb(Cube cube) { return cube.eofb; }
166uint16_t f_eofb(Cube cube) {
167 static bool initialized_ptable;
168 static uint8_t pt_eofb[pow2to11];
169 if (!initialized_ptable) {
170 PruneData pd = {
171 .compressed = false, .available = standard_moveset, .max_moves = 13,
172 .ptable = pt_eofb, .n = pow2to11, .index = index_eofb,
173 .fname = "ptable_eofb"
174 };
175 init_ptable(&pd, false, true);
176 initialized_ptable = true;
177 }
178 return cube.eofb ? pt_eofb[cube.eofb] : 0;
179}
180

Generated with cgit - Back to sebastiano.tronto.net