aboutsummaryrefslogtreecommitdiff
path: root/old/2021-02-28-transformcube-works/src/cube.c
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano.tronto@gmail.com>2021-11-11 21:37:34 +0100
committerSebastiano Tronto <sebastiano.tronto@gmail.com>2021-11-11 21:37:34 +0100
commit3568412f8f230774d0d11d7ed1c897424f95d3ef (patch)
tree77223792d8c925a9b1fc32b3f4341e943b5f8209 /old/2021-02-28-transformcube-works/src/cube.c
parent67e1b5e6e6a2c917a2fe58a37a1382c982b1e5c5 (diff)
downloadnissy-3568412f8f230774d0d11d7ed1c897424f95d3ef.tar.gz
nissy-3568412f8f230774d0d11d7ed1c897424f95d3ef.zip
Rewritten from scratch. Welocme nissy 2.0!
Diffstat (limited to 'old/2021-02-28-transformcube-works/src/cube.c')
-rw-r--r--old/2021-02-28-transformcube-works/src/cube.c271
1 files changed, 271 insertions, 0 deletions
diff --git a/old/2021-02-28-transformcube-works/src/cube.c b/old/2021-02-28-transformcube-works/src/cube.c
new file mode 100644
index 0000000..649a4de
--- /dev/null
+++ b/old/2021-02-28-transformcube-works/src/cube.c
@@ -0,0 +1,271 @@
1#include "cube.h"
2
3typedef struct {
4 int ep[12],eofb[12],eorl[12],eoud[12],cp[8],coud[8],corl[8],cofb[8],cpos[6];
5} CubeArrayAllocated;
6
7void allocate_cubearray(CubeArray *arr, CubeArrayAllocated *all);
8
9char edge_string[12][5] =
10 { "UF", "UL", "UB", "UR", "DF", "DL", "DB", "DR", "FR", "FL", "BL", "BR" };
11char corner_string[8][5] = { "UFR","UFL","UBL","UBR","DFR","DFL","DBL","DBR" };
12char center_string[6][5] = { "U", "D", "R", "L", "F", "B" };
13
14int epe_solved[4] = {FR, FL, BL, BR};
15int eps_solved[4] = {UL, UR, DL, DR};
16int epm_solved[4] = {UF, UB, DF, DB};
17
18PieceFilter pf_all = {true,true,true,true,true,true,true,true,true,true,true},
19 pf_cpos = { .cpos = true }, pf_cp = { .cp = true },
20 pf_ep = { .epose = true, .eposs = true, .eposm = true },
21 pf_e = {.epose=true}, pf_s={.eposs=true}, pf_m={.eposm=true},
22 pf_eo = { .eofb = true, .eorl = true, .eoud = true },
23 pf_co = { .coud = true, .cofb = true, .corl = true };
24
25void allocate_cubearray(CubeArray *arr, CubeArrayAllocated *all) {
26 arr->ep = all->ep;
27 arr->eofb = all->eofb;
28 arr->eorl = all->eorl;
29 arr->eoud = all->eoud;
30 arr->cp = all->cp;
31 arr->coud = all->coud;
32 arr->corl = all->corl;
33 arr->cofb = all->cofb;
34 arr->cpos = all->cpos;
35}
36
37void cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f) {
38 /* ep is the hardest */
39 if (f.epose || f.eposs || f.eposm)
40 for (int i = 0; i < 12; i++) arr->ep[i] = -1;
41 if (f.epose) {
42 int epe[4], epose[12];
43 index_to_perm(cube.epose % factorial(4), 4, epe);
44 index_to_subset(cube.epose / factorial(4), 12, 4, epose);
45 for (int i = 0, ie = 0; i < 12; i++)
46 if (epose[i]) arr->ep[i] = epe_solved[epe[ie++]];
47 }
48 if (f.eposs) {
49 int eps[4], eposs[12];
50 index_to_perm(cube.eposs % factorial(4), 4, eps);
51 index_to_subset(cube.eposs / factorial(4), 12, 4, eposs);
52 for (int i = 0; i < 4; i++) swap(&eposs[eps_solved[i]], &eposs[i+8]);
53 for (int i = 0, is = 0; i < 12; i++)
54 if (eposs[i]) arr->ep[i] = eps_solved[eps[is++]];
55 }
56 if (f.eposm) {
57 int epm[4], eposm[12];
58 index_to_perm(cube.eposm % factorial(4), 4, epm);
59 index_to_subset(cube.eposm / factorial(4), 12, 4, eposm);
60 for (int i = 0; i < 4; i++) swap(&eposm[epm_solved[i]], &eposm[i+8]);
61 for (int i = 0, im = 0; i < 12; i++)
62 if (eposm[i]) arr->ep[i] = epm_solved[epm[im++]];
63 }
64
65 /* All the others */
66 if (f.eofb) int_to_sum_zero_array(cube.eofb, 2, 12, arr->eofb);
67 if (f.eorl) int_to_sum_zero_array(cube.eorl, 2, 12, arr->eorl);
68 if (f.eoud) int_to_sum_zero_array(cube.eoud, 2, 12, arr->eoud);
69 if (f.cp) index_to_perm( cube.cp, 8, arr->cp);
70 if (f.coud) int_to_sum_zero_array(cube.coud, 3, 8, arr->coud);
71 if (f.corl) int_to_sum_zero_array(cube.corl, 3, 8, arr->corl);
72 if (f.cofb) int_to_sum_zero_array(cube.cofb, 3, 8, arr->cofb);
73 if (f.cpos) index_to_perm( cube.cpos, 6, arr->cpos);
74}
75
76Cube arrays_to_cube(CubeArray arr, PieceFilter f) {
77 Cube ret = {0};
78
79 /* Again, ep is the hardest part */
80 if (f.epose) {
81 int epe[4], epose[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
82 for (int i = 0, ie = 0; i < 12; i++)
83 for (int j = 0; j < 4; j++)
84 if (arr.ep[i] == epe_solved[j])
85 { epe[ie++] = j; epose[i] = 1; }
86 ret.epose = factorial(4)*subset_to_index(epose,12,4)+perm_to_index(epe,4);
87 }
88 if (f.eposs) {
89 int eps[4], eposs[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
90 for (int i = 0, is = 0; i < 12; i++)
91 for (int j = 0; j < 4; j++)
92 if (arr.ep[i] == eps_solved[j])
93 { eps[is++] = j; eposs[i] = 1; }
94 for (int i = 0; i < 4; i++) swap(&eposs[eps_solved[i]], &eposs[i+8]);
95 ret.eposs = factorial(4)*subset_to_index(eposs,12,4)+perm_to_index(eps,4);
96 }
97 if (f.eposm) {
98 int epm[4], eposm[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
99 for (int i = 0, im = 0; i < 12; i++)
100 for (int j = 0; j < 4; j++)
101 if (arr.ep[i] == epm_solved[j])
102 { epm[im++] = j; eposm[i] = 1; }
103 for (int i = 0; i < 4; i++) swap(&eposm[epm_solved[i]], &eposm[i+8]);
104 ret.eposm = factorial(4)*subset_to_index(eposm,12,4)+perm_to_index(epm,4);
105 }
106 if (f.eofb) ret.eofb = digit_array_to_int(arr.eofb, 11, 2);
107 if (f.eorl) ret.eorl = digit_array_to_int(arr.eorl, 11, 2);
108 if (f.eoud) ret.eoud = digit_array_to_int(arr.eoud, 11, 2);
109 if (f.cp) ret.cp = perm_to_index( arr.cp, 8 );
110 if (f.coud) ret.coud = digit_array_to_int(arr.coud, 7, 3);
111 if (f.corl) ret.corl = digit_array_to_int(arr.corl, 7, 3);
112 if (f.cofb) ret.cofb = digit_array_to_int(arr.cofb, 7, 3);
113 if (f.cpos) ret.cpos = perm_to_index( arr.cpos, 6 );
114
115 return ret;
116}
117
118Center center_at(Cube cube, Center c) {
119 static CubeArrayAllocated all = {0};
120 CubeArray arr = {0};
121 allocate_cubearray(&arr, &all);
122 cube_to_arrays(cube, &arr, pf_cpos);
123 return arr.cpos[c];
124}
125
126Edge edge_at(Cube cube, Edge e) {
127 static CubeArrayAllocated all = {0};
128 CubeArray arr = {0};
129 allocate_cubearray(&arr, &all);
130 cube_to_arrays(cube, &arr, pf_ep);
131 return arr.ep[e];
132}
133
134Corner corner_at(Cube cube, Corner c) {
135 static CubeArrayAllocated all = {0};
136 CubeArray arr = {0};
137 allocate_cubearray(&arr, &all);
138 cube_to_arrays(cube, &arr, pf_cp);
139 return arr.cp[c];
140}
141
142bool equal(Cube c1, Cube c2) {
143 return c1.eofb == c2.eofb && c1.epose == c2.epose &&
144 c1.eposs == c2.eposs && c1.eposm == c2.eposm &&
145 c1.coud == c2.coud && c1.cp == c2.cp &&
146 c1.cpos == c2.cpos;
147}
148
149bool is_solvable(Cube cube) {
150 static CubeArrayAllocated all = {0};
151 CubeArray arrx = {0};
152 allocate_cubearray(&arrx, &all);
153 cube_to_arrays(cube, &arrx, pf_all);
154
155 /* Since we memorize orientation truncating the last digit, we only need to
156 * check that the permutations have the correct sign. */
157 /* TODO: I should also check that the different eos and cos are compatible */
158 return (perm_sign(arrx.ep,12)^perm_sign(arrx.cpos,6))==perm_sign(arrx.cp,8);
159}
160
161bool is_solved(Cube cube) {
162 /* TODO: might return true if cube is not solvable but looks solved form one
163 of the incompatible interpretations (e.g. eofb and ep solved, but
164 eorl not solve) */
165 return !cube.eofb && !cube.coud && !cube.cp &&
166 !cube.epose && !cube.eposs && !cube.eposm && cube.cpos;
167}
168
169void print_cube(Cube cube) {
170 static CubeArrayAllocated all = {0};
171 CubeArray arrx = {0};
172 allocate_cubearray(&arrx, &all);
173
174 cube_to_arrays(cube, &arrx, pf_all);
175
176/*
177 for (int i = 0; i < 12; i++) printf("%d ", arrx.ep[i]);
178 printf("\n");*/
179
180 for (int i = 0; i < 12; i++) printf(" %s ", edge_string[arrx.ep[i]]);
181 printf("\n");
182 for (int i = 0; i < 12; i++) printf(" %c ", arrx.eofb[i] + '0');
183 printf("\n");
184 for (int i = 0; i < 8; i++) printf("%s ", corner_string[arrx.cp[i]]);
185 printf("\n");
186 for (int i = 0; i < 8; i++) printf(" %c ", arrx.coud[i] + '0');
187 printf("\n");
188 for (int i = 0; i < 6; i++) printf(" %s ", center_string[arrx.cpos[i]]);
189 printf("\n");
190}
191
192Cube admissible_ep(Cube cube, PieceFilter f) {
193 static CubeArrayAllocated all = {0};
194 CubeArray arrx = {0};
195 allocate_cubearray(&arrx, &all);
196 cube_to_arrays(cube, &arrx, f);
197
198 bool used[12] = {0};
199 for (int i = 0; i < 12; i++)
200 if (arrx.ep[i] != -1)
201 used[arrx.ep[i]] = true;
202 for (int i = 0, j = 0; i < 12; i++) {
203 while (j < 11 && used[j]) j++;
204 if (arrx.ep[i] == -1)
205 arrx.ep[i] = j++;
206 }
207
208 return arrays_to_cube(arrx, pf_ep);
209}
210
211Cube inverse_cube(Cube cube) {
212 static CubeArrayAllocated all = {0}, invall = {0};
213 CubeArray arrx = {0}, invx = {0};
214 allocate_cubearray(&arrx, &all);
215 allocate_cubearray(&invx, &invall);
216
217 cube_to_arrays(cube, &arrx, pf_all);
218
219 for (int i = 0; i < 12; i++) {
220 invx.ep[arrx.ep[i]] = i;
221 invx.eofb[arrx.ep[i]] = arrx.eofb[i];
222 invx.eorl[arrx.ep[i]] = arrx.eorl[i];
223 invx.eoud[arrx.ep[i]] = arrx.eoud[i];
224 }
225 for (int i = 0; i < 8; i++) {
226 invx.cp[arrx.cp[i]] = i;
227 invx.coud[arrx.cp[i]] = (3 - arrx.coud[i])%3;
228 invx.corl[arrx.cp[i]] = (3 - arrx.corl[i])%3;
229 invx.cofb[arrx.cp[i]] = (3 - arrx.cofb[i])%3;
230 }
231 for (int i = 0; i < 6; i++)
232 invx.cpos[arrx.cpos[i]] = i;
233
234 return arrays_to_cube(invx, pf_all);
235}
236
237Cube move_via_arrays(CubeArray arr, Cube c, PieceFilter f) {
238 static CubeArrayAllocated all = {0};
239 CubeArray arrx = {0};
240 allocate_cubearray(&arrx, &all);
241
242 cube_to_arrays(c, &arrx, f);
243
244 if (f.epose || f.eposs || f.eposm)
245 apply_permutation( arr.ep, arrx.ep, 12 );
246 if (f.eofb) { apply_permutation( arr.ep, arrx.eofb, 12 );
247 sum_arrays_mod( arr.eofb, arrx.eofb, 12, 2 ); }
248 if (f.eorl) { apply_permutation( arr.ep, arrx.eorl, 12 );
249 sum_arrays_mod( arr.eorl, arrx.eorl, 12, 2 ); }
250 if (f.eoud) { apply_permutation( arr.ep, arrx.eoud, 12 );
251 sum_arrays_mod( arr.eoud, arrx.eoud, 12, 2 ); }
252 if (f.cp) apply_permutation( arr.cp, arrx.cp, 8 );
253 if (f.coud) { apply_permutation( arr.cp, arrx.coud, 8 );
254 sum_arrays_mod( arr.coud, arrx.coud, 8, 3 ); }
255 if (f.corl) { apply_permutation( arr.cp, arrx.corl, 8 );
256 sum_arrays_mod( arr.corl, arrx.corl, 8, 3 ); }
257 if (f.cofb) { apply_permutation( arr.cp, arrx.cofb, 8 );
258 sum_arrays_mod( arr.cofb, arrx.cofb, 8, 3 ); }
259 if (f.cpos) apply_permutation( arr.cpos, arrx.cpos, 6 );
260
261 return arrays_to_cube(arrx, f);
262}
263
264Cube compose(Cube c2, Cube c1) {
265 static CubeArrayAllocated all = {0};
266 CubeArray arrx = {0};
267 allocate_cubearray(&arrx, &all);
268
269 cube_to_arrays(c2, &arrx, pf_all);
270 return move_via_arrays(arrx, c1, pf_all);
271}

Generated with cgit - Back to sebastiano.tronto.net