aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano.tronto@gmail.com>2021-12-12 12:13:42 +0100
committerSebastiano Tronto <sebastiano.tronto@gmail.com>2021-12-12 12:13:42 +0100
commit490d6b168d29b46e55c48c59b5bdde281eebe67e (patch)
treef9ca5c3e9e26de580240cc9af22e06d3b7989bfe /src
parent9725570d740041b51d6bdfbc8416498ddad77666 (diff)
downloadnissy-490d6b168d29b46e55c48c59b5bdde281eebe67e.tar.gz
nissy-490d6b168d29b46e55c48c59b5bdde281eebe67e.zip
Faster inverse cube; makes optimal solving about 30% faster
Diffstat (limited to 'src')
-rw-r--r--src/cube.c220
-rw-r--r--src/cube.h3
-rw-r--r--src/moves.c2
-rw-r--r--src/pf.c15
-rw-r--r--src/pf.h2
5 files changed, 241 insertions, 1 deletions
diff --git a/src/cube.c b/src/cube.c
index 24cca4d..1e2f5d7 100644
--- a/src/cube.c
+++ b/src/cube.c
@@ -1,6 +1,21 @@
1#include "cube.h" 1#include "cube.h"
2 2
3/* Public functions implementation *******************************************/ 3/* Local functions ***********************************************************/
4
5static void init_inverse();
6static bool read_invtables_file();
7static bool write_invtables_file();
8
9/* Tables ********************************************************************/
10
11static uint16_t eo_invtable_e[POW2TO11][BINOM12ON4*FACTORIAL4];
12static uint16_t eo_invtable_s[POW2TO11][BINOM12ON4*FACTORIAL4];
13static uint16_t eo_invtable_m[POW2TO11][BINOM12ON4*FACTORIAL4];
14static uint16_t co_invtable[POW3TO7][FACTORIAL8];
15static uint16_t cp_invtable[FACTORIAL8];
16static uint16_t cpos_invtable[FACTORIAL6];
17
18/* Functions implementation **************************************************/
4 19
5int 20int
6array_ep_to_epos(int *ep, int *ss) 21array_ep_to_epos(int *ep, int *ss)
@@ -284,6 +299,7 @@ equal(Cube c1, Cube c2)
284 c1.cpos == c2.cpos; 299 c1.cpos == c2.cpos;
285} 300}
286 301
302/*
287Cube 303Cube
288inverse_cube(Cube cube) 304inverse_cube(Cube cube)
289{ 305{
@@ -319,6 +335,37 @@ inverse_cube(Cube cube)
319 335
320 return ret; 336 return ret;
321} 337}
338*/
339
340Cube
341inverse_cube(Cube cube)
342{
343 CubeArray inv;
344 Cube ret;
345 int i, ep[12];
346
347 for (i = 0; i < 12; i++)
348 ep[i] = where_is_edge(cube, i);
349 inv = (CubeArray){.ep = ep};
350 ret = arrays_to_cube(&inv, pf_ep);
351
352 ret.eofb = ((int)eo_invtable_e[cube.eofb][cube.epose]) |
353 ((int)eo_invtable_m[cube.eofb][cube.eposm]) |
354 ((int)eo_invtable_s[cube.eofb][cube.eposs]);
355 ret.eorl = ((int)eo_invtable_e[cube.eorl][cube.epose]) |
356 ((int)eo_invtable_m[cube.eorl][cube.eposm]) |
357 ((int)eo_invtable_s[cube.eorl][cube.eposs]);
358 ret.eoud = ((int)eo_invtable_e[cube.eoud][cube.epose]) |
359 ((int)eo_invtable_m[cube.eoud][cube.eposm]) |
360 ((int)eo_invtable_s[cube.eoud][cube.eposs]);
361 ret.cp = cp_invtable[cube.cp];
362 ret.cpos = cpos_invtable[cube.cpos];
363 ret.coud = co_invtable[cube.coud][cube.cp];
364 ret.corl = co_invtable[cube.corl][cube.cp];
365 ret.cofb = co_invtable[cube.cofb][cube.cp];
366
367 return ret;
368}
322 369
323bool 370bool
324is_admissible(Cube cube) { 371is_admissible(Cube cube) {
@@ -684,3 +731,174 @@ where_is_edge(Cube c, Edge e)
684 r2 = aux[2][c.eposm][e]; 731 r2 = aux[2][c.eposm][e];
685 return MAX(r0, MAX(r1, r2)); 732 return MAX(r0, MAX(r1, r2));
686} 733}
734
735static bool
736read_invtables_file()
737{
738 init_env();
739
740 FILE *f;
741 char fname[strlen(tabledir)+20];
742 int b;
743 unsigned int ui, meeo, meco, mecp, mecpos;
744 bool r;
745
746 strcpy(fname, tabledir);
747 strcat(fname, "/invtables");
748
749 if ((f = fopen(fname, "rb")) == NULL)
750 return false;
751
752 b = sizeof(uint16_t);
753 r = true;
754 meeo = BINOM12ON4*FACTORIAL4;
755 meco = FACTORIAL8;
756 mecp = FACTORIAL8;
757 mecpos = FACTORIAL6;
758
759 for (ui = 0; ui < POW2TO11; ui++) {
760 r = r && fread(eo_invtable_e[ui], b, meeo, f) == meeo;
761 r = r && fread(eo_invtable_m[ui], b, meeo, f) == meeo;
762 r = r && fread(eo_invtable_s[ui], b, meeo, f) == meeo;
763 }
764
765 for (ui = 0; ui < POW3TO7; ui++) {
766 r = r && fread(co_invtable[ui], b, meco, f) == meco;
767 }
768
769 r = r && fread(cp_invtable, b, mecp, f) == mecp;
770 r = r && fread(cpos_invtable, b, mecpos, f) == mecpos;
771
772 fclose(f);
773 return r;
774}
775
776static bool
777write_invtables_file()
778{
779 init_env();
780
781 FILE *f;
782 char fname[strlen(tabledir)+20];
783 unsigned int ui, meeo, meco, mecp, mecpos;
784 int b;
785 bool r;
786
787 strcpy(fname, tabledir);
788 strcat(fname, "/invtables");
789
790 if ((f = fopen(fname, "wb")) == NULL)
791 return false;
792
793 b = sizeof(uint16_t);
794 r = true;
795 meeo = BINOM12ON4*FACTORIAL4;
796 meco = FACTORIAL8;
797 mecp = FACTORIAL8;
798 mecpos = FACTORIAL6;
799
800 for (ui = 0; ui < POW2TO11; ui++) {
801 r = r && fwrite(eo_invtable_e[ui], b, meeo, f) == meeo;
802 r = r && fwrite(eo_invtable_m[ui], b, meeo, f) == meeo;
803 r = r && fwrite(eo_invtable_s[ui], b, meeo, f) == meeo;
804 }
805
806 for (ui = 0; ui < POW3TO7; ui++) {
807 r = r && fwrite(co_invtable[ui], b, meco, f) == meco;
808 }
809
810 r = r && fwrite(cp_invtable, b, mecp, f) == mecp;
811 r = r && fwrite(cpos_invtable, b, mecpos, f) == mecpos;
812
813 fclose(f);
814 return r;
815}
816
817void
818init_inverse()
819{
820 static bool initialized = false;
821 if (initialized)
822 return;
823 initialized = true;
824
825 if (read_invtables_file())
826 return;
827
828 fprintf(stderr, "Cannot load invtables, generating it\n");
829
830 CubeArray *aux, *inv;
831 Cube c;
832 int i, j, eoaux[12], eoinv[12];
833 unsigned int ui, uj;
834
835 aux = new_cubearray((Cube){0}, pf_all);
836 inv = new_cubearray((Cube){0}, pf_all);
837
838 for (ui = 0; ui < POW2TO11; ui++) {
839 int_to_sum_zero_array(ui, 2, 12, eoaux);
840 for (uj = 0; uj < BINOM12ON4*FACTORIAL4; uj++) {
841 for (j = 0; j < 12; j++)
842 eoinv[j] = 0;
843 c = (Cube){.epose = uj, .eposm = 0, .eposs = 0};
844 eoinv[FR] = eoaux[where_is_edge(c, FR)];
845 eoinv[FL] = eoaux[where_is_edge(c, FL)];
846 eoinv[BL] = eoaux[where_is_edge(c, BL)];
847 eoinv[BR] = eoaux[where_is_edge(c, BR)];
848 eo_invtable_e[ui][uj] = digit_array_to_int(eoinv,11,2);
849
850 for (j = 0; j < 12; j++)
851 eoinv[j] = 0;
852 c = (Cube){.epose = 0, .eposm = uj, .eposs = 0};
853 eoinv[UF] = eoaux[where_is_edge(c, UF)];
854 eoinv[UB] = eoaux[where_is_edge(c, UB)];
855 eoinv[DF] = eoaux[where_is_edge(c, DF)];
856 eoinv[DB] = eoaux[where_is_edge(c, DB)];
857 eo_invtable_m[ui][uj] = digit_array_to_int(eoinv,11,2);
858
859 for (j = 0; j < 12; j++)
860 eoinv[j] = 0;
861 c = (Cube){.epose = 0, .eposm = 0, .eposs = uj};
862 eoinv[UL] = eoaux[where_is_edge(c, UL)];
863 eoinv[UR] = eoaux[where_is_edge(c, UR)];
864 eoinv[DL] = eoaux[where_is_edge(c, DL)];
865 eoinv[DR] = eoaux[where_is_edge(c, DR)];
866 eo_invtable_s[ui][uj] = digit_array_to_int(eoinv,11,2);
867 }
868 }
869
870 for (ui = 0; ui < FACTORIAL8; ui++) {
871 cube_to_arrays((Cube){.cp = ui}, aux, pf_cp);
872 for (i = 0; i < 8; i++)
873 inv->cp[aux->cp[i]] = i;
874 cp_invtable[ui] = (uint16_t)arrays_to_cube(inv, pf_cp).cp;
875
876 for (uj = 0; uj < POW3TO7; uj++) {
877 cube_to_arrays((Cube){.coud = uj}, aux, pf_coud);
878 for (i = 0; i < 8; i++)
879 inv->coud[aux->cp[i]] = (3-aux->coud[i])%3;
880 co_invtable[uj][ui] =
881 (uint16_t)arrays_to_cube(inv, pf_coud).coud;
882 }
883 }
884
885 for (ui = 0; ui < FACTORIAL6; ui++) {
886 cube_to_arrays((Cube){.cpos = ui}, aux, pf_cpos);
887 for (i = 0; i < 6; i++)
888 inv->cpos[aux->cpos[i]] = i;
889 cpos_invtable[ui] =
890 (uint16_t)arrays_to_cube(inv, pf_cpos).cpos;
891 }
892
893 free_cubearray(aux, pf_all);
894 free_cubearray(inv, pf_all);
895
896 if (!write_invtables_file())
897 fprintf(stderr, "Error writing invtables\n");
898}
899
900void
901init_cube()
902{
903 init_inverse();
904}
diff --git a/src/cube.h b/src/cube.h
index 6c70e99..71e3cc5 100644
--- a/src/cube.h
+++ b/src/cube.h
@@ -4,6 +4,7 @@
4#include <stdio.h> 4#include <stdio.h>
5#include <time.h> 5#include <time.h>
6 6
7#include "env.h"
7#include "pf.h" 8#include "pf.h"
8#include "utils.h" 9#include "utils.h"
9 10
@@ -37,5 +38,7 @@ Center where_is_center(Cube cube, Center c);
37Corner where_is_corner(Cube cube, Corner c); 38Corner where_is_corner(Cube cube, Corner c);
38Edge where_is_edge(Cube cube, Edge e); 39Edge where_is_edge(Cube cube, Edge e);
39 40
41void init_cube();
42
40#endif 43#endif
41 44
diff --git a/src/moves.c b/src/moves.c
index bb749a5..5aca0ee 100644
--- a/src/moves.c
+++ b/src/moves.c
@@ -384,6 +384,8 @@ init_moves() {
384 Move m; 384 Move m;
385 Alg *equiv_alg[NMOVES]; 385 Alg *equiv_alg[NMOVES];
386 386
387 init_cube();
388
387 for (i = 0; i < NMOVES; i++) 389 for (i = 0; i < NMOVES; i++)
388 equiv_alg[i] = new_alg(equiv_alg_string[i]); 390 equiv_alg[i] = new_alg(equiv_alg_string[i]);
389 391
diff --git a/src/pf.c b/src/pf.c
index 34be4fd..7d86e4e 100644
--- a/src/pf.c
+++ b/src/pf.c
@@ -78,3 +78,18 @@ pf_co = {
78 .corl = true, 78 .corl = true,
79 .coud = true 79 .coud = true
80}; 80};
81
82PieceFilter
83pf_coud = {
84 .coud = true
85};
86
87PieceFilter
88pf_edges = {
89 .epose = true,
90 .eposs = true,
91 .eposm = true,
92 .eofb = true,
93 .eorl = true,
94 .eoud = true
95};
diff --git a/src/pf.h b/src/pf.h
index 85ee1eb..0b552dc 100644
--- a/src/pf.h
+++ b/src/pf.h
@@ -14,5 +14,7 @@ extern PieceFilter pf_s;
14extern PieceFilter pf_m; 14extern PieceFilter pf_m;
15extern PieceFilter pf_eo; 15extern PieceFilter pf_eo;
16extern PieceFilter pf_co; 16extern PieceFilter pf_co;
17extern PieceFilter pf_coud;
18extern PieceFilter pf_edges;
17 19
18#endif 20#endif

Generated with cgit - Back to sebastiano.tronto.net