aboutsummaryrefslogtreecommitdiff
path: root/src/solvers/coord/dr.h
blob: a3122855cd42ccc9cc53ffb99d339b0472838508 (plain)
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#define DREOESEP_CLASSES   UINT64_C(64430)
#define DREOESEP_MAX       (POW_2_11 * COMB_12_4)

#define DR_CLASS_TABLESIZE (sizeof(uint32_t) * (size_t)DREOESEP_MAX)
#define DR_REP_TABLESIZE   (sizeof(uint32_t) * (size_t)DREOESEP_CLASSES)
#define DR_COORD_DATASIZE  (INFOSIZE + DR_CLASS_TABLESIZE + DR_REP_TABLESIZE)

#define DR_CLASS_SHIFT     UINT32_C(16)
#define DR_CLASS_MASK      (UINT32_C(0xFFFF) << DR_CLASS_SHIFT)
#define DR_CLASS(d)        (((d) & DR_CLASS_MASK) >> DR_CLASS_SHIFT)

#define DR_TTREP_SHIFT     UINT32_C(0)
#define DR_TTREP_MASK      (UINT32_C(0xFF) << DR_TTREP_SHIFT)
#define DR_TTREP(d)        (((d) & DR_TTREP_MASK) >> DR_TTREP_SHIFT)

#define DR_ISNASTY_SHIFT   UINT32_C(8)
#define DR_ISNASTY_MASK    (UINT32_C(0xFF) << DR_ISNASTY_SHIFT)
#define DR_ISNASTY(d)      (((d) & DR_ISNASTY_MASK) >> DR_ISNASTY_SHIFT)

STATIC uint64_t coord_dreoesep_nosym(cube_t);
STATIC cube_t invcoord_dreoesep_nosym(uint64_t);

STATIC uint64_t coordinate_dr_coord(cube_t, const void *);
STATIC cube_t coordinate_dr_cube(uint64_t, const void *);
STATIC bool coordinate_dr_isnasty(uint64_t, const void *);
STATIC uint64_t coordinate_dr_gendata(void *);

STATIC coord_t coordinate_dr = {
	.name = "DR",
	.coord = &coordinate_dr_coord,
	.cube = &coordinate_dr_cube,
	.isnasty = &coordinate_dr_isnasty,
	.gendata = coordinate_dr_gendata,
	.max = DREOESEP_CLASSES * POW_3_7,
	.trans_mask = TM_UDFIX,
	.moves_mask = MM_ALLMOVES,
	.axistrans = {
		[AXIS_UD] = TRANS_UFr,
		[AXIS_RL] = TRANS_RFr,
		[AXIS_FB] = TRANS_FDr,
	},
	.is_admissible = &solution_lastqt_cw,
};

STATIC uint64_t
coord_dreoesep_nosym(cube_t cube)
{
	uint64_t eo, esep;

	esep = coord_esep(cube) / COMB_8_4;
	eo = coord_eo(cube);

	return esep * POW_2_11 + eo;
}

STATIC cube_t
invcoord_dreoesep_nosym(uint64_t coord)
{
	uint64_t eo, esep;
	cube_t cube;

	eo = coord % POW_2_11;
	esep = (coord / POW_2_11) * COMB_8_4; 
	cube = invcoord_esep(esep);
	set_eo(&cube, eo);

	return cube;
}

STATIC uint64_t
coordinate_dr_coord(cube_t cube, const void *data)
{
	const char *datanoinfo;
	const uint32_t *data32;
	uint32_t d;
	cube_t transformed;

	datanoinfo = (const char *)data + INFOSIZE;
	data32 = (const uint32_t *)datanoinfo;
	d = data32[coord_dreoesep_nosym(cube)];
	transformed = transform(cube, DR_TTREP(d));
	
	return DR_CLASS(d) * POW_3_7 + coord_co(transformed);
}

STATIC cube_t
coordinate_dr_cube(uint64_t coord, const void *data)
{
	const char *datanoinfo;
	const uint32_t *rep32;
	cube_t cube;

	datanoinfo = (const char *)data + INFOSIZE;
	rep32 = (const uint32_t *)(datanoinfo + DR_CLASS_TABLESIZE);
	cube = invcoord_dreoesep_nosym(rep32[coord / POW_3_7]);
	copy_corners(&cube, invcoord_co(coord % POW_3_7));

	return cube;
}

STATIC bool
coordinate_dr_isnasty(uint64_t coord, const void *data)
{
	const char *datanoinfo;
	const uint32_t *classttrep, *rep32;
	uint32_t r;

	datanoinfo = (const char *)data + INFOSIZE;
	classttrep = (const uint32_t *)datanoinfo;
	rep32 = (const uint32_t *)(datanoinfo + DR_CLASS_TABLESIZE);
	r = rep32[coord / POW_3_7];

	return DR_ISNASTY(classttrep[r]);
}

STATIC size_t
coordinate_dr_gendata(void *data)
{
	uint64_t i, j, n, t, nasty;
	char *datanoinfo;
	uint32_t *classttrep, *rep;
	cube_t c;
	tableinfo_t info;

	if (data == NULL)
		goto coordinate_dr_gendata_returnsize;

	datanoinfo = (char *)data + INFOSIZE;
	classttrep = (uint32_t *)datanoinfo;
	rep = classttrep + (DR_CLASS_TABLESIZE / sizeof(uint32_t));
	memset(data, 0xFF, DR_COORD_DATASIZE);

	info = (tableinfo_t) {
		.solver = "coord data for DR",
		.type = TABLETYPE_SPECIAL,
		.infosize = INFOSIZE,
		.fullsize = DR_COORD_DATASIZE,
		.hash = 0,
		.entries = DREOESEP_CLASSES + DREOESEP_MAX,
		.classes = DREOESEP_CLASSES,
		.bits = 32,
		.base = 0,
		.maxvalue = 0,
		.next = 0
	};

	for (i = 0, n = 0; i < COMB_12_4 * POW_2_11; i++) {
		if (classttrep[i] != 0xFFFFFFFF)
			continue;

		c = invcoord_dreoesep_nosym(i);
		for (t = 1, nasty = 0; t < NTRANS && !nasty; t++) {
			if (!((UINT64_C(1) << t) & coordinate_dr.trans_mask))
				continue;

			nasty = i == coord_dreoesep_nosym(transform(c, t));
		}

		for (t = 0; t < NTRANS; t++) {
			if (!((UINT64_C(1) << t) & coordinate_dr.trans_mask))
				continue;

			j = coord_dreoesep_nosym(transform(c, t));
			classttrep[j] =
			    (n << DR_CLASS_SHIFT) |
			    (nasty << DR_ISNASTY_SHIFT) |
			    (inverse_trans(t) << DR_TTREP_SHIFT);
		}
		rep[n++] = i;
	}

	writetableinfo(&info, DR_COORD_DATASIZE, data);

	DBG_ASSERT(n == DREOESEP_CLASSES, 0,
	    "dr coordinate data: computed %" PRIu64 " classes, "
	    "expected %" PRIu64 "\n", n, DREOESEP_CLASSES);

coordinate_dr_gendata_returnsize:
	return DR_COORD_DATASIZE;
}

Generated with cgit - Back to sebastiano.tronto.net