build.c (7951B)
1 #include <inttypes.h> 2 #include <stdbool.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <string.h> 6 7 #include "../src/cube.h" 8 #include "../src/coord.h" 9 #include "../src/solve.h" 10 #include "../src/steps.h" 11 #include "../src/nissy.h" 12 13 static void gen_coord_comp(Coordinate *); 14 static void gen_coord_sym(Coordinate *); 15 static void gen_ptable(Coordinate *); 16 static void gen_ptable_bfs(Coordinate *, int); 17 static void gen_ptable_fixnasty(Coordinate *, coord_value_t, int); 18 static void gen_ptable_compress(Coordinate *); 19 static void gen_ptable_setbase(Coordinate *); 20 21 static char buf[TABLESFILESIZE]; 22 23 static void 24 gen_coord_comp(Coordinate *coord) 25 { 26 coord_value_t ui; 27 Cube c, mvd; 28 Move m; 29 Trans t; 30 31 fprintf(stderr, "%s: generating COMP coordinate\n", coord->name); 32 33 coord->max = indexers_getmax(coord->i); 34 35 fprintf(stderr, "%s: size is %" PRIu32 "\n", coord->name, coord->max); 36 37 fprintf(stderr, "%s: generating mtable\n", coord->name); 38 alloc_mtable(coord); 39 for (ui = 0; ui < coord->max; ui++) { 40 if (ui % 100000 == 0) 41 fprintf(stderr, "\t(%" PRIu32 " done)\n", ui); 42 indexers_makecube(coord->i, ui, &c); 43 for (m = 0; m < NMOVES_HTM; m++) { 44 copy_cube(&c, &mvd); 45 apply_move(m, &mvd); 46 coord->mtable[m][ui] = indexers_getind(coord->i, &mvd); 47 } 48 } 49 fprintf(stderr, "\t(%" PRIu32 " done)\n", coord->max); 50 51 fprintf(stderr, "%s: generating ttable\n", coord->name); 52 alloc_ttable(coord); 53 for (ui = 0; ui < coord->max; ui++) { 54 if (ui % 100000 == 0) 55 fprintf(stderr, "\t(%" PRIu32 " done)\n", ui); 56 indexers_makecube(coord->i, ui, &c); 57 for (t = 0; t < NTRANS; t++) { 58 copy_cube(&c, &mvd); 59 apply_trans(t, &mvd); 60 coord->ttable[t][ui] = indexers_getind(coord->i, &mvd); 61 } 62 } 63 fprintf(stderr, "\t(%" PRIu32 " done)\n", coord->max); 64 } 65 66 static void 67 gen_coord_sym(Coordinate *coord) 68 { 69 coord_value_t i, in, ui, uj, uu, nr; 70 int j; 71 Move m; 72 Trans t; 73 74 fprintf(stderr, "%s: generating SYM coordinate\n", coord->name); 75 76 alloc_sd(coord, true); 77 78 fprintf(stderr, "%s: generating symdata\n", coord->name); 79 for (i = 0; i < coord->base[0]->max; i++) 80 coord->symclass[i] = coord->base[0]->max + 1; 81 for (i = 0, nr = 0; i < coord->base[0]->max; i++) { 82 if (coord->symclass[i] != coord->base[0]->max + 1) 83 continue; 84 85 coord->symrep[nr] = i; 86 coord->transtorep[i] = uf; 87 coord->selfsim[nr] = (coord_value_t)0; 88 for (j = 0; j < coord->tgrp->n; j++) { 89 t = coord->tgrp->t[j]; 90 in = trans_coord(coord->base[0], t, i); 91 coord->symclass[in] = nr; 92 if (in == i) 93 coord->selfsim[nr] |= ((coord_value_t)1<<t); 94 else 95 coord->transtorep[in] = inverse_trans(t); 96 } 97 nr++; 98 } 99 100 coord->max = nr; 101 102 fprintf(stderr, "%s: number of classes is %" PRIu32 "\n", 103 coord->name, coord->max); 104 105 /* Reallocating for maximum number of classes found */ 106 /* TODO: remove, not needed anymore because not writing to file */ 107 /* 108 coord->symrep = realloc(coord->symrep, coord->max*sizeof(coord_value_t)); 109 coord->selfsim = realloc(coord->selfsim, coord->max*sizeof(coord_value_t)); 110 */ 111 112 fprintf(stderr, "%s: generating mtable and ttrep_move\n", coord->name); 113 alloc_mtable(coord); 114 alloc_ttrep_move(coord); 115 for (ui = 0; ui < coord->max; ui++) { 116 if (ui % 100000 == 0) 117 fprintf(stderr, "\t(%" PRIu32 " done)\n", ui); 118 uu = coord->symrep[ui]; 119 for (m = 0; m < NMOVES_HTM; m++) { 120 uj = move_coord(coord->base[0], m, uu, NULL); 121 coord->mtable[m][ui] = coord->symclass[uj]; 122 coord->ttrep_move[m][ui] = coord->transtorep[uj]; 123 } 124 } 125 fprintf(stderr, "\t(%" PRIu32 " done)\n", coord->max); 126 } 127 128 void 129 gen_coord(Coordinate *coord) 130 { 131 int i; 132 133 if (coord == NULL || coord->generated) 134 return; 135 136 fprintf(stderr, "%s: gen_coord started\n", coord->name); 137 for (i = 0; i < 2; i++) { 138 if (coord->base[i] != NULL) { 139 fprintf(stderr, "%s: generating base[%d] = %s\n", 140 coord->name, i, coord->base[i]->name); 141 gen_coord(coord->base[i]); 142 } 143 } 144 145 switch (coord->type) { 146 case COMP_COORD: 147 if (coord->i[0] == NULL) 148 goto error_gc; 149 gen_coord_comp(coord); 150 break; 151 case SYM_COORD: 152 if (coord->base[0] == NULL || coord->tgrp == NULL) 153 goto error_gc; 154 gen_coord_sym(coord); 155 break; 156 case SYMCOMP_COORD: 157 if (coord->base[0] == NULL || coord->base[1] == NULL) 158 goto error_gc; 159 coord->max = coord->base[0]->max * coord->base[1]->max; 160 break; 161 default: 162 break; 163 } 164 165 coord->generated = true; 166 gen_ptable(coord); 167 168 fprintf(stderr, "%s: gen_coord completed\n", coord->name); 169 170 return; 171 172 error_gc: 173 fprintf(stderr, "Error generating coordinates.\n"); 174 exit(1); 175 } 176 177 static void 178 gen_ptable(Coordinate *coord) 179 { 180 bool compact; 181 int d, i; 182 coord_value_t oldn, sz; 183 184 alloc_ptable(coord, true); 185 186 /* For the first steps we proceed the same way for compact and not */ 187 compact = coord->compact; 188 coord->compact = false; 189 190 fprintf(stderr, "%s: generating ptable\n", coord->name); 191 192 sz = ptablesize(coord) * sizeof(entry_group_t); 193 memset(coord->ptable, ~(uint8_t)0, sz); 194 for (i = 0; i < 16; i++) 195 coord->count[i] = 0; 196 197 coord->updated = 0; 198 oldn = 0; 199 ptableupdate(coord, 0, 0); 200 gen_ptable_fixnasty(coord, 0, 0); 201 fprintf(stderr, "\tDepth %d done, generated %" 202 PRIu32 "\t(%" PRIu32 "/%" PRIu32 ")\n", 203 0, coord->updated - oldn, coord->updated, coord->max); 204 oldn = coord->updated; 205 coord->count[0] = coord->updated; 206 for (d = 0; d < 15 && coord->updated < coord->max; d++) { 207 gen_ptable_bfs(coord, d); 208 fprintf(stderr, "\tDepth %d done, generated %" 209 PRIu32 "\t(%" PRIu32 "/%" PRIu32 ")\n", 210 d+1, coord->updated-oldn, coord->updated, coord->max); 211 coord->count[d+1] = coord->updated - oldn; 212 oldn = coord->updated; 213 } 214 215 gen_ptable_setbase(coord); 216 217 if (compact) { 218 fprintf(stderr, "%s: compressing ptable\n", coord->name); 219 gen_ptable_compress(coord); 220 } 221 222 fprintf(stderr, "%s: ptable generated\n", coord->name); 223 } 224 225 static void 226 gen_ptable_bfs(Coordinate *coord, int d) 227 { 228 coord_value_t i, ii; 229 int pval; 230 Move m; 231 232 for (i = 0; i < coord->max; i++) { 233 pval = ptableval(coord, i); 234 if (pval != d) 235 continue; 236 for (m = U; m <= B3; m++) { 237 if (!coord->moveset(m)) 238 continue; 239 ii = move_coord(coord, m, i, NULL); 240 ptableupdate(coord, ii, d+1); 241 gen_ptable_fixnasty(coord, ii, d+1); 242 } 243 } 244 } 245 246 static void 247 gen_ptable_fixnasty(Coordinate *coord, coord_value_t i, int d) 248 { 249 coord_value_t ii, ss, M; 250 int j; 251 Trans t; 252 253 if (coord->type != SYMCOMP_COORD) 254 return; 255 256 M = coord->base[1]->max; 257 ss = coord->base[0]->selfsim[i/M]; 258 for (j = 0; j < coord->base[0]->tgrp->n; j++) { 259 t = coord->base[0]->tgrp->t[j]; 260 if (t == uf || !(ss & ((coord_value_t)1<<t))) 261 continue; 262 ii = trans_coord(coord, t, i); 263 ptableupdate(coord, ii, d); 264 } 265 } 266 267 static void 268 gen_ptable_compress(Coordinate *coord) 269 { 270 int val; 271 coord_value_t i, j; 272 entry_group_t mask, v; 273 274 fprintf(stderr, "Compressing table to 2 bits per entry\n"); 275 276 for (i = 0; i < coord->max; i += ENTRIES_PER_GROUP_COMPACT) { 277 mask = (entry_group_t)0; 278 for (j = 0; j < ENTRIES_PER_GROUP_COMPACT; j++) { 279 if (i+j >= coord->max) 280 break; 281 val = ptableval(coord, i+j) - coord->ptablebase; 282 v = (entry_group_t)MIN(3, MAX(0, val)); 283 mask |= v << (2*j); 284 } 285 coord->ptable[i/ENTRIES_PER_GROUP_COMPACT] = mask; 286 } 287 288 coord->compact = true; 289 290 /* TODO: remove, not necessary anymore */ 291 /* 292 coord->ptable = realloc(coord->ptable, 293 sizeof(entry_group_t)*ptablesize(coord)); 294 */ 295 } 296 297 static void 298 gen_ptable_setbase(Coordinate *coord) 299 { 300 int i; 301 coord_value_t sum, newsum; 302 303 coord->ptablebase = 0; 304 sum = coord->count[0] + coord->count[1] + coord->count[2]; 305 for (i = 3; i < 16; i++) { 306 newsum = sum + coord->count[i] - coord->count[i-3]; 307 if (newsum > sum) 308 coord->ptablebase = i-3; 309 sum = newsum; 310 } 311 } 312 313 int 314 main(void) 315 { 316 int i; 317 size_t b; 318 FILE *file; 319 320 init_cube(); 321 322 b = 0; 323 for (i = 0; coordinates[i] != NULL; i++) { 324 gen_coord(coordinates[i]); 325 b += write_coord(coordinates[i], &buf[b]); 326 } 327 328 if ((file = fopen("tables", "wb")) == NULL) 329 return 1; 330 331 if (fwrite(buf, 1, b, file) != b) 332 return 1; 333 334 fprintf(stderr, "Written %zu bytes\n", b); 335 336 return 0; 337 }