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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
STATIC size_t gendata_coord(const coord_t *, void *);
STATIC int64_t gendata_coord_dispatch(const char *, void *);
STATIC tableinfo_t genptable_coord(const coord_t *, const void *, uint8_t *);
STATIC void getdistribution_coord(
const uint8_t *, const char *, uint64_t [static INFO_DISTRIBUTION_LEN]);
STATIC uint8_t get_coord_pval(const coord_t *, const uint8_t *, uint64_t);
STATIC void set_coord_pval(const coord_t *, uint8_t *, uint64_t, uint8_t);
STATIC int64_t
gendata_coord_dispatch(const char *coordstr, void *buf)
{
coord_t *coord;
parse_coord_and_axis(coordstr, strlen(coordstr), &coord, NULL);
if (coord == NULL) {
LOG("Could not parse coordinate '%s'\n", coord);
return NISSY_ERROR_INVALID_SOLVER;
}
return (int64_t)gendata_coord(coord, buf);
}
STATIC size_t
gendata_coord(const coord_t *coord, void *buf)
{
uint64_t coord_dsize, tablesize, ninfo;
void *pruningbuf, *coord_data;
uint8_t *table;
tableinfo_t coord_data_info, pruning_info;
coord_data = buf == NULL ? NULL : ((uint8_t *)buf) + INFOSIZE;
coord_dsize = coord->gendata(coord_data);
ninfo = coord_dsize == 0 ? 1 : 2;
tablesize = DIV_ROUND_UP(coord->max, 2);
if (buf == NULL)
goto gendata_coord_return_size;
if (ninfo == 2) {
coord_data_info = (tableinfo_t) {
.solver = "coord helper table for ",
.type = TABLETYPE_SPECIAL,
.infosize = INFOSIZE,
.fullsize = INFOSIZE + coord_dsize,
.hash = 0, /* TODO */
.next = INFOSIZE + coord_dsize,
/* Unknown / non-applicable values */
.entries = 0,
.classes = 0,
.bits = 0,
.base = 0,
.maxvalue = 0,
};
append_coord_name(coord, coord_data_info.solver);
writetableinfo(&coord_data_info, INFOSIZE + coord_dsize, buf);
pruningbuf = ((uint8_t *)buf) + INFOSIZE + coord_dsize;
} else {
pruningbuf = buf;
}
table = ((uint8_t *)pruningbuf) + INFOSIZE;
pruning_info = genptable_coord(coord, coord_data, table);
writetableinfo(&pruning_info, INFOSIZE + tablesize, pruningbuf);
gendata_coord_return_size:
return ninfo * INFOSIZE + coord_dsize + tablesize;
}
STATIC tableinfo_t
genptable_coord(const coord_t *coord, const void *data, uint8_t *table)
{
uint64_t tablesize, i, j, d, tot;
tableinfo_t info;
uint8_t m;
cube_t c, cc;
tablesize = DIV_ROUND_UP(coord->max, 2);
memset(table, 0xFF, tablesize);
info = (tableinfo_t) {
.solver = "coordinate solver for ",
.type = TABLETYPE_PRUNING,
.infosize = INFOSIZE,
.fullsize = INFOSIZE + tablesize,
.hash = 0, /* TODO */
.entries = coord->max,
.classes = 0,
.bits = 4,
.base = 0,
.maxvalue = 0,
.next = 0
};
memset(info.distribution, 0, INFO_DISTRIBUTION_LEN * sizeof(uint64_t));
append_coord_name(coord, info.solver);
i = coord->coord(SOLVED_CUBE, data);
set_coord_pval(coord, table, i, 0);
info.distribution[0] = 1;
for (d = 1, tot = 1; tot < coord->max; d++) {
for (i = 0; i < coord->max; i++) {
if (get_coord_pval(coord, table, i) == d-1) {
c = coord->cube(i, data);
for (m = 0; m < 18; m++) {
cc = move(c, m);
j = coord->coord(cc, data);
if (get_coord_pval(coord, table, j) > d) {
set_coord_pval(coord, table, j, d);
tot++;
info.distribution[d]++;
}
}
}
}
}
info.maxvalue = d-1;
return info;
}
STATIC void
getdistribution_coord(
const uint8_t *table,
const char *coord,
uint64_t distr[static INFO_DISTRIBUTION_LEN]
)
{
uint8_t v;
uint64_t i;
coord_t *c;
memset(distr, 0, INFO_DISTRIBUTION_LEN * sizeof(uint64_t));
if((c = parse_coord(coord, strlen(coord))) == NULL)
return;
for (i = 0; i < c->max; i++) {
v = get_coord_pval(c, table, i);
distr[v]++;
}
}
STATIC uint8_t
get_coord_pval(const coord_t *coord, const uint8_t *table, uint64_t i)
{
return (table[COORD_INDEX(i)] & COORD_MASK(i)) >> COORD_SHIFT(i);
}
STATIC void
set_coord_pval(const coord_t *coord, uint8_t *table, uint64_t i, uint8_t val)
{
table[COORD_INDEX(i)] = (table[COORD_INDEX(i)] & (~COORD_MASK(i)))
| (val << COORD_SHIFT(i));
}
|