aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--shell/shell.c2
-rw-r--r--src/solvers/coord/dr.h14
-rw-r--r--src/solvers/coord/gendata.h104
-rw-r--r--src/utils/math.h14
-rw-r--r--test/015_math_intpow/00_1_0.in3
-rw-r--r--test/015_math_intpow/00_1_0.out1
-rw-r--r--test/015_math_intpow/01_x_0.in3
-rw-r--r--test/015_math_intpow/01_x_0.out1
-rw-r--r--test/015_math_intpow/02_3_2.in3
-rw-r--r--test/015_math_intpow/02_3_2.out1
-rw-r--r--test/015_math_intpow/intpow_tests.c26
-rw-r--r--tools/expected_distributions.h18
12 files changed, 170 insertions, 20 deletions
diff --git a/shell/shell.c b/shell/shell.c
index 1b66f19..4b354c6 100644
--- a/shell/shell.c
+++ b/shell/shell.c
@@ -641,7 +641,7 @@ parse_uint(const char *argv, unsigned *result)
641static uint8_t 641static uint8_t
642parse_nisstype(const char *arg) 642parse_nisstype(const char *arg)
643{ 643{
644 if (!strcmp("normal", arg)) 644 if (!strcmp("normal", arg) || !strcmp("", arg))
645 return NISSY_NISSFLAG_NORMAL; 645 return NISSY_NISSFLAG_NORMAL;
646 646
647 if (!strcmp("inverse", arg)) 647 if (!strcmp("inverse", arg))
diff --git a/src/solvers/coord/dr.h b/src/solvers/coord/dr.h
index 5f3a99b..a312285 100644
--- a/src/solvers/coord/dr.h
+++ b/src/solvers/coord/dr.h
@@ -102,18 +102,21 @@ STATIC bool
102coordinate_dr_isnasty(uint64_t coord, const void *data) 102coordinate_dr_isnasty(uint64_t coord, const void *data)
103{ 103{
104 const char *datanoinfo; 104 const char *datanoinfo;
105 const uint32_t *classttrep; 105 const uint32_t *classttrep, *rep32;
106 uint32_t r;
106 107
107 datanoinfo = (const char *)data + INFOSIZE; 108 datanoinfo = (const char *)data + INFOSIZE;
108 classttrep = (const uint32_t *)datanoinfo; 109 classttrep = (const uint32_t *)datanoinfo;
110 rep32 = (const uint32_t *)(datanoinfo + DR_CLASS_TABLESIZE);
111 r = rep32[coord / POW_3_7];
109 112
110 return DR_ISNASTY(classttrep[coord]); 113 return DR_ISNASTY(classttrep[r]);
111} 114}
112 115
113STATIC size_t 116STATIC size_t
114coordinate_dr_gendata(void *data) 117coordinate_dr_gendata(void *data)
115{ 118{
116 uint64_t i, ii, j, n, t, nasty; 119 uint64_t i, j, n, t, nasty;
117 char *datanoinfo; 120 char *datanoinfo;
118 uint32_t *classttrep, *rep; 121 uint32_t *classttrep, *rep;
119 cube_t c; 122 cube_t c;
@@ -146,12 +149,11 @@ coordinate_dr_gendata(void *data)
146 continue; 149 continue;
147 150
148 c = invcoord_dreoesep_nosym(i); 151 c = invcoord_dreoesep_nosym(i);
149 ii = coord_dreoesep_nosym(c); 152 for (t = 1, nasty = 0; t < NTRANS && !nasty; t++) {
150 for (t = 0, nasty = 0; t < NTRANS && !nasty; t++) {
151 if (!((UINT64_C(1) << t) & coordinate_dr.trans_mask)) 153 if (!((UINT64_C(1) << t) & coordinate_dr.trans_mask))
152 continue; 154 continue;
153 155
154 nasty = ii == coord_dreoesep_nosym(transform(c, t)); 156 nasty = i == coord_dreoesep_nosym(transform(c, t));
155 } 157 }
156 158
157 for (t = 0; t < NTRANS; t++) { 159 for (t = 0; t < NTRANS; t++) {
diff --git a/src/solvers/coord/gendata.h b/src/solvers/coord/gendata.h
index 5e40575..423dad1 100644
--- a/src/solvers/coord/gendata.h
+++ b/src/solvers/coord/gendata.h
@@ -2,8 +2,11 @@ STATIC size_t gendata_coord(const coord_t [static 1], void *);
2STATIC int64_t gendata_coord_dispatch(const char *, void *); 2STATIC int64_t gendata_coord_dispatch(const char *, void *);
3STATIC tableinfo_t genptable_coord( 3STATIC tableinfo_t genptable_coord(
4 const coord_t [static 1], const void *, uint8_t *); 4 const coord_t [static 1], const void *, uint8_t *);
5STATIC bool switch_to_fromnew(uint64_t, uint64_t, uint64_t);
5STATIC uint64_t genptable_coord_fillneighbors( 6STATIC uint64_t genptable_coord_fillneighbors(
6 const coord_t [static 1], const void *, uint64_t, uint8_t, uint8_t *); 7 const coord_t [static 1], const void *, uint64_t, uint8_t, uint8_t *);
8STATIC uint64_t genptable_coord_fillfromnew(
9 const coord_t [static 1], const void *, uint64_t, uint8_t, uint8_t *);
7STATIC void getdistribution_coord( 10STATIC void getdistribution_coord(
8 const uint8_t *, const char *, uint64_t [static INFO_DISTRIBUTION_LEN]); 11 const uint8_t *, const char *, uint64_t [static INFO_DISTRIBUTION_LEN]);
9STATIC uint8_t get_coord_pval( 12STATIC uint8_t get_coord_pval(
@@ -83,7 +86,7 @@ genptable_coord(
83 uint8_t *table 86 uint8_t *table
84) 87)
85{ 88{
86 uint64_t tablesize, i, d, tot, t; 89 uint64_t tablesize, i, d, tot, t, nm;
87 tableinfo_t info; 90 tableinfo_t info;
88 91
89 tablesize = DIV_ROUND_UP(coord->max, 2); 92 tablesize = DIV_ROUND_UP(coord->max, 2);
@@ -107,26 +110,46 @@ genptable_coord(
107 memset(info.distribution, 0, INFO_DISTRIBUTION_LEN * sizeof(uint64_t)); 110 memset(info.distribution, 0, INFO_DISTRIBUTION_LEN * sizeof(uint64_t));
108 append_coord_name(coord, info.solver); 111 append_coord_name(coord, info.solver);
109 112
113 nm = popcount_u32(coord->moves_mask);
110 i = coord->coord(SOLVED_CUBE, data); 114 i = coord->coord(SOLVED_CUBE, data);
111 set_coord_pval(coord, table, i, 0); 115 set_coord_pval(coord, table, i, 0);
112 info.distribution[0] = 1; 116 info.distribution[0] = 1;
113 for (d = 1, tot = 1; tot < coord->max; d++) { 117 for (d = 1, tot = 1; tot < coord->max && d < 20; d++) {
114 for (i = 0; i < coord->max; i++) { 118 t = 0;
115 if (get_coord_pval(coord, table, i) == d-1) { 119 if (switch_to_fromnew(tot, coord->max, nm)) {
116 t = genptable_coord_fillneighbors( 120 for (i = 0; i < coord->max; i++)
117 coord, data, i, d, table); 121 if (get_coord_pval(coord, table, i) > d)
118 tot += t; 122 t += genptable_coord_fillfromnew(
119 info.distribution[d] += t; 123 coord, data, i, d, table);
120 } 124 } else {
125 for (i = 0; i < coord->max; i++)
126 if (get_coord_pval(coord, table, i) == d-1)
127 t += genptable_coord_fillneighbors(
128 coord, data, i, d, table);
121 } 129 }
122 LOG("Depth %" PRIu64 ": %" PRIu64 " of %" PRIu64 "\n", 130 tot += t;
123 d, tot, coord->max); 131 info.distribution[d] = t;
132 LOG("Depth %" PRIu64 ": found %" PRIu64 " (%" PRIu64 " of %"
133 PRIu64 ")\n", d, t, tot, coord->max);
124 } 134 }
125 info.maxvalue = d-1; 135 info.maxvalue = d-1;
126 136
127 return info; 137 return info;
128} 138}
129 139
140STATIC bool
141switch_to_fromnew(uint64_t done, uint64_t max, uint64_t nm)
142{
143 /*
144 Heuristic to determine if it is more conveniente to loop over
145 done coordinates and fill the new discovered, or to loop from new
146 coordinates and fill them if they have a done neighbor.
147 */
148
149 double r = (double)done / (double)max;
150 return 1.0 - intpow(1.0-r, nm) > nm * (1.0-r);
151}
152
130STATIC uint64_t 153STATIC uint64_t
131genptable_coord_fillneighbors( 154genptable_coord_fillneighbors(
132 const coord_t coord[static 1], 155 const coord_t coord[static 1],
@@ -136,15 +159,18 @@ genptable_coord_fillneighbors(
136 uint8_t *table 159 uint8_t *table
137) 160)
138{ 161{
162 bool isnasty;
139 uint8_t m; 163 uint8_t m;
140 uint64_t j, t, tot; 164 uint64_t ii, j, t, tot;
141 cube_t c, moved; 165 cube_t c, moved;
142 166
143 c = coord->cube(i, data); 167 c = coord->cube(i, data);
144 tot = 0; 168 tot = 0;
145 for (m = 0; m < NMOVES; m++) { 169 for (m = 0; m < NMOVES; m++) {
146 moved = move(c, m); 170 moved = move(c, m);
147 for (t = 0; t < NTRANS; t++) { 171 ii = coord->coord(moved, data);
172 isnasty = coord->isnasty(ii, data);
173 for (t = 0; t < NTRANS && (t == 0 || isnasty); t++) {
148 if (!((UINT64_C(1) << t) & coord->trans_mask)) 174 if (!((UINT64_C(1) << t) & coord->trans_mask))
149 continue; 175 continue;
150 176
@@ -159,6 +185,58 @@ genptable_coord_fillneighbors(
159 return tot; 185 return tot;
160} 186}
161 187
188STATIC uint64_t
189genptable_coord_fillfromnew(
190 const coord_t coord[static 1],
191 const void *data,
192 uint64_t i,
193 uint8_t d,
194 uint8_t *table
195)
196{
197 bool found;
198 uint8_t m;
199 uint64_t tot, t, ii, j, nsim, sim[NTRANS];
200 cube_t c;
201
202 tot = 0;
203 c = coord->cube(i, data);
204
205 for (t = 0, nsim = 0; t < NTRANS; t++) {
206 if (!((UINT64_C(1) << t) & coord->trans_mask))
207 continue;
208
209 ii = coord->coord(transform(c, t), data);
210 for (j = 0, found = false; j < nsim && !found; j++)
211 found = sim[j] == ii;
212 if (!found)
213 sim[nsim++] = ii;
214 }
215
216 for (j = 0, found = false; j < nsim && !found; j++) {
217 c = coord->cube(sim[j], data);
218 for (m = 0; m < NMOVES; m++) {
219 ii = coord->coord(move(c, m), data);
220 if (get_coord_pval(coord, table, ii) < d) {
221 found = true;
222 break;
223 }
224 }
225 }
226
227 tot = 0;
228 if (found) {
229 for (j = 0; j < nsim; j++) {
230 if (get_coord_pval(coord, table, sim[j]) > d) {
231 set_coord_pval(coord, table, sim[j], d);
232 tot++;
233 }
234 }
235 }
236
237 return tot;
238}
239
162STATIC void 240STATIC void
163getdistribution_coord( 241getdistribution_coord(
164 const uint8_t *table, 242 const uint8_t *table,
diff --git a/src/utils/math.h b/src/utils/math.h
index 21fc60b..a9d9b85 100644
--- a/src/utils/math.h
+++ b/src/utils/math.h
@@ -10,6 +10,7 @@ STATIC void indextoperm(int64_t, size_t n, uint8_t [n]);
10STATIC int permsign(size_t n, const uint8_t [n]); 10STATIC int permsign(size_t n, const uint8_t [n]);
11STATIC int64_t digitstosumzero(size_t n, const uint8_t [n], uint8_t); 11STATIC int64_t digitstosumzero(size_t n, const uint8_t [n], uint8_t);
12STATIC void sumzerotodigits(int64_t, size_t n, uint8_t, uint8_t [n]); 12STATIC void sumzerotodigits(int64_t, size_t n, uint8_t, uint8_t [n]);
13STATIC double intpow(double, uint64_t);
13 14
14STATIC int64_t 15STATIC int64_t
15factorial(int64_t n) 16factorial(int64_t n)
@@ -183,3 +184,16 @@ sumzerotodigits(int64_t d, size_t n, uint8_t b, uint8_t a[n])
183sumzerotodigits_error: 184sumzerotodigits_error:
184 memset(a, UINT8_ERROR, n); 185 memset(a, UINT8_ERROR, n);
185} 186}
187
188STATIC double
189intpow(double b, uint64_t e)
190{
191 double r;
192
193 if (e == 0)
194 return 1;
195
196 r = intpow(b, e/2);
197
198 return e % 2 == 0 ? r * r : b * r * r;
199}
diff --git a/test/015_math_intpow/00_1_0.in b/test/015_math_intpow/00_1_0.in
new file mode 100644
index 0000000..41c18f9
--- /dev/null
+++ b/test/015_math_intpow/00_1_0.in
@@ -0,0 +1,3 @@
11.0
20
31.0
diff --git a/test/015_math_intpow/00_1_0.out b/test/015_math_intpow/00_1_0.out
new file mode 100644
index 0000000..7326d96
--- /dev/null
+++ b/test/015_math_intpow/00_1_0.out
@@ -0,0 +1 @@
Ok
diff --git a/test/015_math_intpow/01_x_0.in b/test/015_math_intpow/01_x_0.in
new file mode 100644
index 0000000..1545b05
--- /dev/null
+++ b/test/015_math_intpow/01_x_0.in
@@ -0,0 +1,3 @@
1234324.52324234
20
31.0
diff --git a/test/015_math_intpow/01_x_0.out b/test/015_math_intpow/01_x_0.out
new file mode 100644
index 0000000..7326d96
--- /dev/null
+++ b/test/015_math_intpow/01_x_0.out
@@ -0,0 +1 @@
Ok
diff --git a/test/015_math_intpow/02_3_2.in b/test/015_math_intpow/02_3_2.in
new file mode 100644
index 0000000..b1c935f
--- /dev/null
+++ b/test/015_math_intpow/02_3_2.in
@@ -0,0 +1,3 @@
13.0
22
39.0
diff --git a/test/015_math_intpow/02_3_2.out b/test/015_math_intpow/02_3_2.out
new file mode 100644
index 0000000..7326d96
--- /dev/null
+++ b/test/015_math_intpow/02_3_2.out
@@ -0,0 +1 @@
Ok
diff --git a/test/015_math_intpow/intpow_tests.c b/test/015_math_intpow/intpow_tests.c
new file mode 100644
index 0000000..48b255c
--- /dev/null
+++ b/test/015_math_intpow/intpow_tests.c
@@ -0,0 +1,26 @@
1#include "../test.h"
2
3#define ABS(x) ((x) < 0 ? (-(x)) : (x))
4
5double intpow(double, uint64_t);
6
7const double tolerance = 1e-6;
8
9void run(void) {
10 char str[STRLENMAX];
11 double b, r, c;
12 uint64_t e;
13
14 fgets(str, STRLENMAX, stdin);
15 b = atof(str);
16 fgets(str, STRLENMAX, stdin);
17 e = atoll(str);
18 fgets(str, STRLENMAX, stdin);
19 r = atof(str);
20
21 c = intpow(b, e);
22 if (ABS(r - c) > tolerance)
23 printf("Error! Expected %lf but got %lf\n", r, c);
24 else
25 printf("Ok\n");
26}
diff --git a/tools/expected_distributions.h b/tools/expected_distributions.h
index 039e4d4..8ddb138 100644
--- a/tools/expected_distributions.h
+++ b/tools/expected_distributions.h
@@ -136,6 +136,22 @@ uint64_t expected_eo[21] = {
136 [7] = 13, 136 [7] = 13,
137}; 137};
138 138
139uint64_t expected_dr[21] = {
140 [0] = 1,
141 [1] = 1,
142 [2] = 5,
143 [3] = 44,
144 [4] = 487,
145 [5] = 5841,
146 [6] = 68364,
147 [7] = 776568,
148 [8] = 7950748,
149 [9] = 52098876,
150 [10] = 76236234,
151 [11] = 3771112,
152 [12] = 129,
153};
154
139static bool 155static bool
140distribution_equal(const uint64_t *expected, const uint64_t *actual, int n) 156distribution_equal(const uint64_t *expected, const uint64_t *actual, int n)
141{ 157{
@@ -218,6 +234,8 @@ check_distribution(const char *solver, size_t data_size, const void *data)
218 str = info.solver + 22; /* "coordinate solver for COORD" */ 234 str = info.solver + 22; /* "coordinate solver for COORD" */
219 if (!strcmp(str, "EO")) { 235 if (!strcmp(str, "EO")) {
220 return check_table(expected_eo, &info); 236 return check_table(expected_eo, &info);
237 } else if (!strcmp(str, "DR")) {
238 return check_table(expected_dr, &info);
221 } else { 239 } else {
222 goto check_distribution_unknown; 240 goto check_distribution_unknown;
223 } 241 }

Generated with cgit - Back to sebastiano.tronto.net