aboutsummaryrefslogtreecommitdiff
path: root/old/2021-02-06/solve.c
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano.tronto@gmail.com>2021-11-11 22:05:00 +0100
committerSebastiano Tronto <sebastiano.tronto@gmail.com>2021-11-11 22:05:00 +0100
commit4fb67201414169a2687f41c4056b2e284b4938cb (patch)
treea68246e3e21435229541f83f485ab41cfb2ba08a /old/2021-02-06/solve.c
parent3568412f8f230774d0d11d7ed1c897424f95d3ef (diff)
downloadnissy-4fb67201414169a2687f41c4056b2e284b4938cb.tar.gz
nissy-4fb67201414169a2687f41c4056b2e284b4938cb.zip
Removed old files
Diffstat (limited to 'old/2021-02-06/solve.c')
-rw-r--r--old/2021-02-06/solve.c177
1 files changed, 0 insertions, 177 deletions
diff --git a/old/2021-02-06/solve.c b/old/2021-02-06/solve.c
deleted file mode 100644
index f6274e9..0000000
--- a/old/2021-02-06/solve.c
+++ /dev/null
@@ -1,177 +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, blank_cube()))))) {
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, blank_cube())))
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 Cube rotated = apply_alg(sd->pre_rotation, blank_cube());
91 cube = apply_alg(inverse_cube(rotated), compose(cube, rotated));
92
93 uint64_t ret = 0;
94 for (int i=sd->min_moves; i<=sd->max_moves&&!(ret&&sd->optimal_only); i++) {
95 DfsData dd = { .d = i, .n = &ret };
96 solve_dfs(cube, sd, dd);
97 }
98
99 for (uint64_t i = 0; i < ret; i++) {
100 /* TODO: transform solutions with inverse of pre_rotation */
101 if (sd->cleanup)
102 cleanup(sd->solutions[i], sd->max_moves*3);
103 }
104
105 return ret;
106}
107
108void prune_dfs(Cube cube, PruneData *pd, DfsData dd) {
109 uint64_t ind = pd->index(cube);
110 if ((!ind || pd->ptable[ind]) && pd->ptable[ind] != dd.m)
111 return;
112 if (dd.m == dd.d) {
113 if (ind && !pd->ptable[ind]) {
114 pd->ptable[ind] = dd.m;
115 (*dd.n)++;
116 }
117 return;
118 }
119
120 for (int i = 0; i < NMOVES; i++) {
121 if (dd.m<20)
122 if (possible_next[dd.last2][dd.last1][i] && pd->available[i]) {
123 DfsData nn = { .m = dd.m+1, .d = dd.d, .n = dd.n,
124 .last1 = i, .last2 = dd.last1 };
125 prune_dfs(move_cube(i, cube), pd, nn);
126 }
127 }
128}
129
130void init_ptable(PruneData *pd, bool read, bool write) {
131 if (read) {
132 FILE *ptf;
133 if ((ptf = fopen(pd->fname, "rb")) != NULL) {
134 fread(pd->ptable, sizeof(uint8_t), pd->n, ptf);
135 fclose(ptf);
136 return;
137 }
138 }
139
140 /* TODO: for now it behaves always as if copressed = false */
141 for (uint64_t i = 0; i < pd->n; i++)
142 pd->ptable[i] = 0;
143
144 uint64_t s = 1;
145 for (int i = 1; i < pd->max_moves && s < pd->n; i++) {
146 DfsData dd = { .d = i, .n = &s };
147 prune_dfs(blank_cube(), pd, dd);
148 }
149
150 if (write) {
151 FILE *ptf;
152 if ((ptf = fopen(pd->fname, "wb")) != NULL) {
153 fwrite(pd->ptable, sizeof(uint8_t), pd->n, ptf);
154 fclose(ptf);
155 return;
156 }
157 }
158}
159
160/* Solving steps (and indexing functions) */
161
162uint64_t index_eofb(Cube cube) { return cube.eofb; }
163uint16_t f_eofb(Cube cube) {
164 static bool initialized_ptable;
165 static uint8_t pt_eofb[pow2to11];
166 if (!initialized_ptable) {
167 PruneData pd = {
168 .compressed = false, .available = standard_moveset, .max_moves = 13,
169 .ptable = pt_eofb, .n = pow2to11, .index = index_eofb,
170 .fname = "ptable_eofb"
171 };
172 init_ptable(&pd, false, true);
173 initialized_ptable = true;
174 }
175 return cube.eofb ? pt_eofb[cube.eofb] : 0;
176}
177

Generated with cgit - Back to sebastiano.tronto.net