1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
#define EOSHIFT UINT8_C(4)
#define COSHIFT UINT8_C(5)
#define PBITS UINT8_C(0xF)
#define ESEPBIT_1 UINT8_C(0x4)
#define ESEPBIT_2 UINT8_C(0x8)
#define CSEPBIT UINT8_C(0x4)
#define EOBIT UINT8_C(0x10)
#define COBITS UINT8_C(0xF0)
#define COBITS_2 UINT8_C(0x60)
#define CTWIST_CW UINT8_C(0x20)
#define CTWIST_CCW UINT8_C(0x40)
#define EFLIP UINT8_C(0x10)
STATIC_INLINE int popcount_u32(uint32_t);
STATIC_INLINE int popcount_u64(uint64_t);
STATIC void pieces(cube_t [static 1], uint8_t [static 8], uint8_t [static 12]);
STATIC_INLINE bool equal(cube_t, cube_t);
STATIC_INLINE cube_t invertco(cube_t);
STATIC_INLINE cube_t compose_edges(cube_t, cube_t);
STATIC_INLINE cube_t compose_corners(cube_t, cube_t);
STATIC_INLINE cube_t compose(cube_t, cube_t);
STATIC_INLINE cube_t inverse(cube_t);
STATIC_INLINE uint64_t coord_co(cube_t);
STATIC_INLINE cube_t invcoord_co(uint64_t);
STATIC_INLINE uint64_t coord_csep(cube_t);
STATIC_INLINE uint64_t coord_cocsep(cube_t);
STATIC_INLINE uint64_t coord_eo(cube_t);
STATIC_INLINE uint64_t coord_esep(cube_t);
STATIC_INLINE cube_t invcoord_esep(uint64_t);
STATIC_INLINE uint64_t coord_epudsep(cube_t);
STATIC_INLINE cube_t invcoord_epudsep(uint64_t);
STATIC_INLINE bool is_eo_even(cube_t);
STATIC_INLINE void copy_corners(cube_t [static 1], cube_t);
STATIC_INLINE void copy_co(cube_t [static 1], cube_t);
STATIC_INLINE void copy_edges(cube_t [static 1], cube_t);
STATIC_INLINE void set_eo(cube_t [static 1], uint64_t);
STATIC_INLINE void invcoord_esep_array(uint64_t, uint64_t, uint8_t[static 12]);
STATIC_INLINE cube_t invcoord_eoesep(uint64_t);
STATIC_INLINE uint64_t coord_epudsep_array(const uint8_t [8]);
STATIC_INLINE void invcoord_epudsep_array(uint64_t, uint8_t [8]);
STATIC_INLINE uint64_t coord_cp(cube_t);
STATIC_INLINE cube_t invcoord_cp(uint64_t);
STATIC_INLINE uint64_t coord_epud(cube_t);
STATIC_INLINE cube_t invcoord_epud(uint64_t);
STATIC_INLINE uint64_t coord_epe(cube_t);
STATIC_INLINE cube_t invcoord_epe(uint64_t);
STATIC_INLINE void
invcoord_esep_array(uint64_t set1, uint64_t set2, uint8_t mem[static 12])
{
uint64_t bit1, bit2, i, j, jj, k, l, s, v, w, is1;
uint8_t slice[3] = {0};
for (i = 0, j = 0, k = 4, l = 4; i < 12; i++)
{
v = binomial[11 - i][k];
jj = j < 8;
w = jj * binomial[7 - (j * jj)][l];
bit2 = set2 >= v;
bit1 = set1 >= w;
is1 = (1 - bit2) * bit1;
set2 -= bit2 * v;
k -= bit2;
set1 -= is1 * w;
l -= is1;
j += (1 - bit2);
s = 2 * bit2 + (1 - bit2) * bit1;
mem[i] = (slice[s]++) | (uint8_t)(s << 2);
}
}
STATIC_INLINE cube_t
invcoord_eoesep(uint64_t i)
{
cube_t c;
uint64_t esep, eo;
esep = i >> INT64_C(11);
eo = i % POW_2_11;
c = invcoord_esep(esep);
set_eo(&c, eo);
return c;
}
STATIC_INLINE uint64_t
coord_epudsep_array(const uint8_t e[8])
{
uint8_t i, k, is;
uint64_t ret;
ret = 0;
k = 4;
for (i = 0; i < 8; i++) {
is = (e[i] & UINT8_C(4)) >> UINT8_C(2);
ret += is * binomial[7-i][k];
k -= is;
}
return ret;
}
STATIC_INLINE void
invcoord_epudsep_array(uint64_t c, uint8_t ret[8])
{
uint8_t i, k, is, x, y;
k = 4;
x = 0;
y = 4;
for (i = 0; i < 8; i++) {
is = c >= binomial[7-i][k];
ret[i] = is*y + (1-is)*x;
y += is;
x += 1-is;
c -= is * binomial[7-i][k];
k -= is;
}
}
|