aboutsummaryrefslogtreecommitdiff
path: root/src/fst.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fst.c')
-rw-r--r--src/fst.c291
1 files changed, 269 insertions, 22 deletions
diff --git a/src/fst.c b/src/fst.c
index 91c022a..ebd3333 100644
--- a/src/fst.c
+++ b/src/fst.c
@@ -2,7 +2,30 @@
2 2
3#include "fst.h" 3#include "fst.h"
4 4
5static void fst_to_ep(FstCube fst, int *ep); 5static FstCube ep_to_fst_epos(int *ep);
6static int fst_where_is_edge(int e, FstCube fst);
7static void transform_ep_only(Trans t, int *ep, Cube *dst);
8static void init_fst_corner_invtables();
9static void init_fst_eo_invtables();
10static void init_fst_eo_update(uint64_t, uint64_t, int, Cube *);
11static void init_fst_transalg();
12static void init_fst_where_is_edge();
13
14static int edge_slice[12] = {[FR] = 0, [FL] = 0, [BL] = 0, [BR] = 0,
15 [UL] = 1, [UR] = 1, [DR] = 1, [DL] = 1,
16 [UF] = 2, [UB] = 2, [DF] = 2, [DB] = 2};
17
18static uint16_t inv_coud[FACTORIAL8][POW3TO7];
19static uint16_t inv_cp[FACTORIAL8];
20static uint16_t uf_cp_to_fr_cp[FACTORIAL8];
21static uint16_t uf_cp_to_rd_cp[FACTORIAL8];
22
23static int16_t eo_invtable[3][POW2TO11][BINOM12ON4*FACTORIAL4];
24
25static int trans_ep_alg[NROTATIONS][12];
26static int trans_ep_inv[NROTATIONS][12];
27
28static uint16_t fst_where_is_edge_arr[3][12][BINOM12ON4*FACTORIAL4];
6 29
7FstCube 30FstCube
8cube_to_fst(Cube *cube) 31cube_to_fst(Cube *cube)
@@ -11,19 +34,39 @@ cube_to_fst(Cube *cube)
11 FstCube ret; 34 FstCube ret;
12 35
13 copy_cube(cube, &c); 36 copy_cube(cube, &c);
14 ret.uf_eofb = index_eofb(&c); 37 ret.uf_eofb = coord_eofb.i[0]->index(&c);
15 ret.uf_eposepe = index_eposepe(&c); 38 ret.uf_eposepe = coord_eposepe.i[0]->index(&c);
16 ret.uf_coud = index_coud(&c); 39 ret.uf_coud = coord_coud.i[0]->index(&c);
17 ret.uf_cp = index_cp(&c); 40 ret.uf_cp = coord_cp.i[0]->index(&c);
18 copy_cube(cube, &c); 41 copy_cube(cube, &c);
19 transform_cube(fr, &c); 42 apply_trans(fr, &c);
20 ret.fr_eofb = index_eofb(&c); 43 ret.fr_eofb = coord_eofb.i[0]->index(&c);
21 ret.fr_eposepe = index_eposepe(&c); 44 ret.fr_eposepe = coord_eposepe.i[0]->index(&c);
22 ret.fr_coud = index_coud(&c); 45 ret.fr_coud = coord_coud.i[0]->index(&c);
23 transform_cube(rd, &c); 46 apply_trans(rd, &c);
24 ret.rd_eofb = index_eofb(&c); 47 ret.rd_eofb = coord_eofb.i[0]->index(&c);
25 ret.rd_eposepe = index_eposepe(&c); 48 ret.rd_eposepe = coord_eposepe.i[0]->index(&c);
26 ret.rd_coud = index_coud(&c); 49 ret.rd_coud = coord_coud.i[0]->index(&c);
50
51 return ret;
52}
53
54static FstCube
55ep_to_fst_epos(int *ep)
56{
57 /* TODO: maybe optimize? */
58
59 FstCube ret;
60 Cube c;
61
62 memcpy(c.ep, ep, 12 * sizeof(int));
63 ret.uf_eposepe = coord_eposepe.i[0]->index(&c);
64
65 transform_ep_only(fr, ep, &c);
66 ret.fr_eposepe = coord_eposepe.i[0]->index(&c);
67
68 transform_ep_only(rd, ep, &c);
69 ret.rd_eposepe = coord_eposepe.i[0]->index(&c);
27 70
28 return ret; 71 return ret;
29} 72}
@@ -31,28 +74,232 @@ cube_to_fst(Cube *cube)
31FstCube 74FstCube
32fst_inverse(FstCube fst) 75fst_inverse(FstCube fst)
33{ 76{
34 /* TODO */ 77 FstCube ret;
78 int i, ep_inv[12];
79
80 for (i = 0; i < 12; i++)
81 ep_inv[i] = fst_where_is_edge(i, fst);
82 ret = ep_to_fst_epos(ep_inv);
83
84 ret.uf_eofb = ((uint16_t)eo_invtable[0][fst.uf_eofb][fst.uf_eposepe]) |
85 ((uint16_t)eo_invtable[1][fst.uf_eofb][fst.fr_eposepe]) |
86 ((uint16_t)eo_invtable[2][fst.uf_eofb][fst.rd_eposepe]);
87 ret.fr_eofb = ((uint16_t)eo_invtable[0][fst.fr_eofb][fst.uf_eposepe]) |
88 ((uint16_t)eo_invtable[1][fst.fr_eofb][fst.fr_eposepe]) |
89 ((uint16_t)eo_invtable[2][fst.fr_eofb][fst.rd_eposepe]);
90 ret.rd_eofb = ((uint16_t)eo_invtable[0][fst.rd_eofb][fst.uf_eposepe]) |
91 ((uint16_t)eo_invtable[1][fst.rd_eofb][fst.fr_eposepe]) |
92 ((uint16_t)eo_invtable[2][fst.rd_eofb][fst.rd_eposepe]);
93
94 ret.uf_cp = inv_cp[fst.uf_cp];
95
96 ret.uf_coud = inv_coud[fst.uf_cp][fst.uf_coud];
97 ret.fr_coud = inv_coud[uf_cp_to_fr_cp[fst.uf_cp]][fst.fr_coud];
98 ret.rd_coud = inv_coud[uf_cp_to_rd_cp[fst.uf_cp]][fst.rd_coud];
99
100 return ret;
35} 101}
36 102
37FstCube 103FstCube
38fst_move(Move m, FstCube fst) 104fst_move(Move m, FstCube fst)
39{ 105{
40 /* TODO */ 106 FstCube ret;
107 Move m_fr, m_rd;
108
109 m_fr = transform_move(fr, m);
110 m_rd = transform_move(rd, m);
111
112 ret.uf_eofb = coord_eofb.mtable[m][fst.uf_eofb];
113 ret.uf_eposepe = coord_eposepe.mtable[m][fst.uf_eposepe];
114 ret.uf_coud = coord_coud.mtable[m][fst.uf_coud];
115 ret.uf_cp = coord_cp.mtable[m][fst.uf_cp];
116
117 ret.fr_eofb = coord_eofb.mtable[m_fr][fst.fr_eofb];
118 ret.fr_eposepe = coord_eposepe.mtable[m_fr][fst.fr_eposepe];
119 ret.fr_coud = coord_coud.mtable[m_fr][fst.fr_coud];
120
121 ret.rd_eofb = coord_eofb.mtable[m_rd][fst.rd_eofb];
122 ret.rd_eposepe = coord_eposepe.mtable[m_rd][fst.rd_eposepe];
123 ret.rd_coud = coord_coud.mtable[m_rd][fst.rd_coud];
124
125 return ret;
41} 126}
42 127
43void 128void
44fst_to_cube(FstCube fst, Cube *cube) 129fst_to_cube(FstCube fst, Cube *cube)
45{ 130{
46 invindex_eofb((uint64_t)fst.uf_eofb, cube); 131 Cube e, s, m;
47 fst_to_ep(fst, cube->ep); 132 int i;
48 invindex_coud((uint64_t)fst.uf_coud, cube); 133
49 invindex_cp((uint64_t)fst.uf_cp, cube); 134 coord_eposepe.i[0]->to_cube(fst.uf_eposepe, &e);
135 coord_eposepe.i[0]->to_cube(fst.fr_eposepe, &s);
136 apply_trans(inverse_trans(fr), &s);
137 coord_eposepe.i[0]->to_cube(fst.rd_eposepe, &m);
138 apply_trans(inverse_trans(rd), &m);
139
140 for (i = 0; i < 12; i++) {
141 if (edge_slice[e.ep[i]] == 0)
142 cube->ep[i] = e.ep[i];
143 if (edge_slice[s.ep[i]] == 1)
144 cube->ep[i] = s.ep[i];
145 if (edge_slice[m.ep[i]] == 2)
146 cube->ep[i] = m.ep[i];
147 }
148
149 coord_eofb.i[0]->to_cube((uint64_t)fst.uf_eofb, cube);
150 coord_coud.i[0]->to_cube((uint64_t)fst.uf_coud, cube);
151 coord_cp.i[0]->to_cube((uint64_t)fst.uf_cp, cube);
152}
153
154static int
155fst_where_is_edge(int e, FstCube fst)
156{
157 switch (edge_slice[e]) {
158 case 0:
159 return fst_where_is_edge_arr[0][e][fst.uf_eposepe];
160 case 1:
161 return fst_where_is_edge_arr[1][e][fst.fr_eposepe];
162 default:
163 return fst_where_is_edge_arr[2][e][fst.rd_eposepe];
164 }
165
166 return -1;
167}
168
169static void
170transform_ep_only(Trans t, int *ep, Cube *dst)
171{
172 int i;
173
174 for (i = 0; i < 12; i++)
175 dst->ep[i] = trans_ep_alg[t][ep[trans_ep_inv[t][i]]];
176}
177
178void
179init_fst()
180{
181 init_fst_corner_invtables();
182 init_fst_eo_invtables();
183 init_fst_transalg();
184 init_fst_where_is_edge();
185}
186
187static void
188init_fst_corner_invtables()
189{
190/* TODO: this can be optimized by transforming and copying only corners */
191/* A factor of about 4 would be saved in the innermost loop */
192
193 Cube c, d;
194 uint64_t cp, coud;
195
196 for (cp = 0; cp < FACTORIAL8; cp++) {
197 make_solved(&c);
198 coord_cp.i[0]->to_cube(cp, &c);
199
200 copy_cube(&c, &d);
201 invert_cube(&d);
202 inv_cp[cp] = coord_coud.i[0]->index(&d);
203
204 for (coud = 0; coud < POW3TO7; coud++) {
205 copy_cube(&c, &d);
206 coord_coud.i[0]->to_cube(coud, &d);
207 invert_cube(&d);
208 inv_coud[cp][coud] = coord_coud.i[0]->index(&d);
209 }
210
211 copy_cube(&c, &d);
212 apply_trans(fr, &d);
213 uf_cp_to_fr_cp[cp] = coord_cp.i[0]->index(&d);
214
215 copy_cube(&c, &d);
216 apply_trans(rd, &d);
217 uf_cp_to_rd_cp[cp] = coord_cp.i[0]->index(&d);
218 }
219}
220
221static void
222init_fst_eo_invtables()
223{
224 uint64_t ep, eo;
225 Cube c, d;
226
227 for (ep = 0; ep < BINOM12ON4 * FACTORIAL4; ep++) {
228 make_solved(&c);
229 coord_eposepe.i[0]->to_cube(ep, &c);
230 for (eo = 0; eo < POW2TO11; eo++) {
231 coord_eofb.i[0]->to_cube(eo, &c);
232 copy_cube(&c, &d);
233 init_fst_eo_update(eo, ep, 0, &d);
234 apply_trans(inverse_trans(fr), &d);
235 init_fst_eo_update(eo, ep, 1, &d);
236 copy_cube(&c, &d);
237 apply_trans(inverse_trans(rd), &d);
238 init_fst_eo_update(eo, ep, 2, &d);
239 }
240 }
50} 241}
51 242
52static void 243static void
53fst_to_ep(FstCube fst, int *ep) 244init_fst_eo_update(uint64_t eo, uint64_t ep, int s, Cube *d)
54{ 245{
55 /* TODO */ 246 int i;
247
248 for (i = 0; i < 12; i++)
249 if (d->eo[i])
250 eo_invtable[s][eo][ep] |= ((uint16_t)1) << d->ep[i];
56} 251}
57 252
58#endif 253static void
254init_fst_transalg()
255{
256 Trans t;
257 Alg *alg;
258 Cube c;
259 int i;
260
261 for (t = uf; t < NROTATIONS; t++) {
262 make_solved(&c);
263 alg = rotation_alg(t);
264 apply_alg(alg, &c);
265 for (i = 0; i < 12; i++)
266 trans_ep_alg[t][i] = c.ep[i];
267 invert_cube(&c);
268 for (i = 0; i < 12; i++)
269 trans_ep_inv[t][i] = c.ep[i];
270 }
271}
272
273static void
274init_fst_where_is_edge()
275{
276 Cube c, d;
277 uint64_t e;
278
279 init_trans();
280
281 make_solved(&c);
282 for (e = 0; e < BINOM12ON4 * FACTORIAL4; e++) {
283 coord_eposepe.i[0]->to_cube(e, &c);
284
285 copy_cube(&c, &d);
286 fst_where_is_edge_arr[0][FR][e] = where_is_edge(FR, &d);
287 fst_where_is_edge_arr[0][FL][e] = where_is_edge(FL, &d);
288 fst_where_is_edge_arr[0][BL][e] = where_is_edge(BL, &d);
289 fst_where_is_edge_arr[0][BR][e] = where_is_edge(BR, &d);
290
291 copy_cube(&c, &d);
292 apply_trans(inverse_trans(fr), &d);
293 fst_where_is_edge_arr[1][UL][e] = where_is_edge(UL, &d);
294 fst_where_is_edge_arr[1][UR][e] = where_is_edge(UR, &d);
295 fst_where_is_edge_arr[1][DL][e] = where_is_edge(DL, &d);
296 fst_where_is_edge_arr[1][DR][e] = where_is_edge(DR, &d);
297
298 copy_cube(&c, &d);
299 apply_trans(inverse_trans(rd), &d);
300 fst_where_is_edge_arr[2][UF][e] = where_is_edge(UF, &d);
301 fst_where_is_edge_arr[2][UB][e] = where_is_edge(UB, &d);
302 fst_where_is_edge_arr[2][DF][e] = where_is_edge(DF, &d);
303 fst_where_is_edge_arr[2][DB][e] = where_is_edge(DB, &d);
304 }
305}

Generated with cgit - Back to sebastiano.tronto.net