diff options
Diffstat (limited to 'src/fst.c')
| -rw-r--r-- | src/fst.c | 124 |
1 files changed, 80 insertions, 44 deletions
| @@ -3,7 +3,6 @@ | |||
| 3 | #include "fst.h" | 3 | #include "fst.h" |
| 4 | 4 | ||
| 5 | static FstCube ep_to_fst_epos(int *ep); | 5 | static FstCube ep_to_fst_epos(int *ep); |
| 6 | static void transform_ep_only(Trans t, int *ep, Cube *dst); | ||
| 7 | static void init_fst_corner_invtables(); | 6 | static void init_fst_corner_invtables(); |
| 8 | static void init_fst_eo_invtables(); | 7 | static void init_fst_eo_invtables(); |
| 9 | static void init_fst_eo_update(uint64_t, uint64_t, int, Cube *); | 8 | static void init_fst_eo_update(uint64_t, uint64_t, int, Cube *); |
| @@ -54,24 +53,12 @@ cube_to_fst(Cube *cube) | |||
| 54 | static FstCube | 53 | static FstCube |
| 55 | ep_to_fst_epos(int *ep) | 54 | ep_to_fst_epos(int *ep) |
| 56 | { | 55 | { |
| 57 | /* TODO: maybe optimize */ | ||
| 58 | 56 | ||
| 59 | /* TODO: this version if faster, but broken | 57 | /* The block of commented code works, but it is slower. |
| 60 | probably need to fix transform_ep_only() | 58 | The actual code is mysterious, and there is some overlap with coord.c |
| 61 | 59 | (coord_eposepe.i), and trans.c, butbut it is faster. */ | |
| 62 | FstCube ret; | ||
| 63 | Cube c; | ||
| 64 | |||
| 65 | memcpy(c.ep, ep, 12 * sizeof(int)); | ||
| 66 | ret.uf_eposepe = coord_eposepe.i[0]->index(&c); | ||
| 67 | |||
| 68 | transform_ep_only(fr, ep, &c); | ||
| 69 | ret.fr_eposepe = coord_eposepe.i[0]->index(&c); | ||
| 70 | |||
| 71 | transform_ep_only(rd, ep, &c); | ||
| 72 | ret.rd_eposepe = coord_eposepe.i[0]->index(&c); | ||
| 73 | */ | ||
| 74 | 60 | ||
| 61 | /* | ||
| 75 | FstCube ret; | 62 | FstCube ret; |
| 76 | Cube c, d; | 63 | Cube c, d; |
| 77 | 64 | ||
| @@ -90,16 +77,89 @@ ep_to_fst_epos(int *ep) | |||
| 90 | ret.rd_eposepe = coord_eposepe.i[0]->index(&d); | 77 | ret.rd_eposepe = coord_eposepe.i[0]->index(&d); |
| 91 | 78 | ||
| 92 | return ret; | 79 | return ret; |
| 80 | */ | ||
| 81 | |||
| 82 | static int eind[12] = { | ||
| 83 | [FR] = 0, [FL] = 1, [BL] = 2, [BR] = 3, | ||
| 84 | [UR] = 0, [DR] = 1, [DL] = 2, [UL] = 3, | ||
| 85 | [DB] = 0, [DF] = 1, [UF] = 2, [UB] = 3 | ||
| 86 | }; | ||
| 87 | static int eptrans_fr[12] = { | ||
| 88 | [FR] = UF, [DF] = UL, [FL] = UB, [UF] = UR, | ||
| 89 | [BR] = DF, [DB] = DL, [BL] = DB, [UB] = DR, | ||
| 90 | [UR] = FR, [DR] = FL, [DL] = BL, [UL] = BR | ||
| 91 | }; | ||
| 92 | static int eptrans_rd[12] = { | ||
| 93 | [DR] = UF, [FR] = UL, [UR] = UB, [BR] = UR, | ||
| 94 | [DL] = DF, [FL] = DL, [UL] = DB, [BL] = DR, | ||
| 95 | [DB] = FR, [DF] = FL, [UF] = BL, [UB] = BR | ||
| 96 | }; | ||
| 97 | |||
| 98 | FstCube ret; | ||
| 99 | int i, ce, cs, cm; | ||
| 100 | int epe[4], eps[4], epm[4], epose[12], eposs[12], eposm[12]; | ||
| 101 | |||
| 102 | memset(epose, 0, 12*sizeof(int)); | ||
| 103 | memset(eposs, 0, 12*sizeof(int)); | ||
| 104 | memset(eposm, 0, 12*sizeof(int)); | ||
| 105 | |||
| 106 | for (i = 0, ce = 0; i < 12; i++) { | ||
| 107 | switch (edge_slice[ep[i]]) { | ||
| 108 | case 0: | ||
| 109 | epose[i] = 1; | ||
| 110 | epe[ce++] = eind[ep[i]]; | ||
| 111 | break; | ||
| 112 | case 1: | ||
| 113 | eposs[eptrans_fr[i]] = eind[ep[i]] + 1; | ||
| 114 | break; | ||
| 115 | default: | ||
| 116 | eposm[eptrans_rd[i]] = eind[ep[i]] + 1; | ||
| 117 | break; | ||
| 118 | } | ||
| 119 | } | ||
| 120 | |||
| 121 | for (i = 0, cs = 0, cm = 0; i < 12; i++) { | ||
| 122 | if (eposs[i]) { | ||
| 123 | eps[cs++] = eposs[i] - 1; | ||
| 124 | eposs[i] = 1; | ||
| 125 | } | ||
| 126 | if (eposm[i]) { | ||
| 127 | epm[cm++] = eposm[i] - 1; | ||
| 128 | eposm[i] = 1; | ||
| 129 | } | ||
| 130 | } | ||
| 131 | |||
| 132 | ret.uf_eposepe = subset_to_index(epose, 12, 4) * FACTORIAL4 + | ||
| 133 | perm_to_index(epe, 4); | ||
| 134 | ret.fr_eposepe = subset_to_index(eposs, 12, 4) * FACTORIAL4 + | ||
| 135 | perm_to_index(eps, 4); | ||
| 136 | ret.rd_eposepe = subset_to_index(eposm, 12, 4) * FACTORIAL4 + | ||
| 137 | perm_to_index(epm, 4); | ||
| 138 | |||
| 139 | return ret; | ||
| 93 | } | 140 | } |
| 94 | 141 | ||
| 95 | FstCube | 142 | FstCube |
| 96 | fst_inverse(FstCube fst) | 143 | fst_inverse(FstCube fst) |
| 97 | { | 144 | { |
| 98 | FstCube ret; | 145 | FstCube ret; |
| 99 | int i, ep_inv[12]; | 146 | int ep_inv[12]; |
| 147 | |||
| 148 | ep_inv[FR] = fst_where_is_edge_arr[0][FR][fst.uf_eposepe]; | ||
| 149 | ep_inv[FL] = fst_where_is_edge_arr[0][FL][fst.uf_eposepe]; | ||
| 150 | ep_inv[BL] = fst_where_is_edge_arr[0][BL][fst.uf_eposepe]; | ||
| 151 | ep_inv[BR] = fst_where_is_edge_arr[0][BR][fst.uf_eposepe]; | ||
| 152 | |||
| 153 | ep_inv[UR] = fst_where_is_edge_arr[1][UR][fst.fr_eposepe]; | ||
| 154 | ep_inv[UL] = fst_where_is_edge_arr[1][UL][fst.fr_eposepe]; | ||
| 155 | ep_inv[DR] = fst_where_is_edge_arr[1][DR][fst.fr_eposepe]; | ||
| 156 | ep_inv[DL] = fst_where_is_edge_arr[1][DL][fst.fr_eposepe]; | ||
| 157 | |||
| 158 | ep_inv[UF] = fst_where_is_edge_arr[2][UF][fst.rd_eposepe]; | ||
| 159 | ep_inv[UB] = fst_where_is_edge_arr[2][UB][fst.rd_eposepe]; | ||
| 160 | ep_inv[DF] = fst_where_is_edge_arr[2][DF][fst.rd_eposepe]; | ||
| 161 | ep_inv[DB] = fst_where_is_edge_arr[2][DB][fst.rd_eposepe]; | ||
| 100 | 162 | ||
| 101 | for (i = 0; i < 12; i++) | ||
| 102 | ep_inv[i] = fst_where_is_edge(i, fst); | ||
| 103 | ret = ep_to_fst_epos(ep_inv); | 163 | ret = ep_to_fst_epos(ep_inv); |
| 104 | 164 | ||
| 105 | ret.uf_eofb = ((uint16_t)eo_invtable[0][fst.uf_eofb][fst.uf_eposepe]) | | 165 | ret.uf_eofb = ((uint16_t)eo_invtable[0][fst.uf_eofb][fst.uf_eposepe]) | |
| @@ -175,30 +235,6 @@ fst_to_cube(FstCube fst, Cube *cube) | |||
| 175 | cube->xp[i] = i; | 235 | cube->xp[i] = i; |
| 176 | } | 236 | } |
| 177 | 237 | ||
| 178 | int | ||
| 179 | fst_where_is_edge(int e, FstCube fst) | ||
| 180 | { | ||
| 181 | switch (edge_slice[e]) { | ||
| 182 | case 0: | ||
| 183 | return fst_where_is_edge_arr[0][e][fst.uf_eposepe]; | ||
| 184 | case 1: | ||
| 185 | return fst_where_is_edge_arr[1][e][fst.fr_eposepe]; | ||
| 186 | default: | ||
| 187 | return fst_where_is_edge_arr[2][e][fst.rd_eposepe]; | ||
| 188 | } | ||
| 189 | |||
| 190 | return -1; | ||
| 191 | } | ||
| 192 | |||
| 193 | static void | ||
| 194 | transform_ep_only(Trans t, int *ep, Cube *dst) | ||
| 195 | { | ||
| 196 | int i; | ||
| 197 | |||
| 198 | for (i = 0; i < 12; i++) | ||
| 199 | dst->ep[i] = trans_ep_alg[t][ep[trans_ep_inv[t][i]]]; | ||
| 200 | } | ||
| 201 | |||
| 202 | void | 238 | void |
| 203 | init_fst() | 239 | init_fst() |
| 204 | { | 240 | { |
