aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano.tronto@gmail.com>2020-07-12 20:44:09 +0200
committerSebastiano Tronto <sebastiano.tronto@gmail.com>2020-07-12 20:44:09 +0200
commite1ebff51092baf5581b728baec05c52c4bb3445e (patch)
tree8e3cc3fa0cf10bbe35a3bacfba8e1d96f850b058 /src
parent0fe7c8b43c50ae5701463acbb186a6fe0f53a773 (diff)
downloadnissy-e1ebff51092baf5581b728baec05c52c4bb3445e.tar.gz
nissy-e1ebff51092baf5581b728baec05c52c4bb3445e.zip
Added feature: scramble
Diffstat (limited to 'src')
-rw-r--r--src/main.c29
-rw-r--r--src/solver.c100
-rw-r--r--src/solver.h1
-rw-r--r--src/utils.c17
-rw-r--r--src/utils.h4
5 files changed, 135 insertions, 16 deletions
diff --git a/src/main.c b/src/main.c
index 0a29d0e..125e4ec 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,6 +1,7 @@
1/* blabla */ 1/* blabla */
2#include <stdio.h> 2#include <stdio.h>
3#include <stdlib.h> 3#include <stdlib.h>
4#include <time.h>
4#include "utils.h" 5#include "utils.h"
5#include "coordinates.h" 6#include "coordinates.h"
6#include "io.h" 7#include "io.h"
@@ -11,6 +12,8 @@
11char *commands[][10] = { 12char *commands[][10] = {
12 {"help", "[COMMAND]", 13 {"help", "[COMMAND]",
13 "Print this help, or a help page for COMMAND."}, 14 "Print this help, or a help page for COMMAND."},
15 {"scramble", "",
16 "Prints a random-state scramble"},
14 {"save", "[MOVES|@ID|$ID]", 17 {"save", "[MOVES|@ID|$ID]",
15 "Save or copy a scramble."}, 18 "Save or copy a scramble."},
16 {"change", "$ID1 [MOVES|$ID2|@ID2]", 19 {"change", "$ID1 [MOVES|$ID2|@ID2]",
@@ -141,6 +144,28 @@ void help_cmd(int n, char cmdtok[][100]) {
141 } 144 }
142} 145}
143 146
147void scramble_cmd(int n, char cmdtok[][100]) {
148 if (n > 1 || cmdtok[0][0] != 's') { /* Second case avoids warning */
149 printf("scramble: wrong syntax\n");
150 return;
151 }
152
153 srand(time(NULL));
154 int eofb = rand() % pow2to11;
155 int coud = rand() % pow3to7;
156 int ep = rand() % factorial12;
157 int cp = rand() % factorial8;
158 while (perm_sign_int(ep, 12) != perm_sign_int(cp, 8))
159 ep = (ep+1) % factorial12;
160
161 /* Debug */
162 /* printf("State: %d %d %d %d\n", eofb, coud, ep, cp); */
163
164 int scram[2][30];
165 reach_state(eofb, coud, ep, cp, scram);
166 print_results(1, scram);
167}
168
144void save_cmd(int n, char cmdtok[][100]) { 169void save_cmd(int n, char cmdtok[][100]) {
145 int scram[255]; 170 int scram[255];
146 if (n == 1) { 171 if (n == 1) {
@@ -534,7 +559,7 @@ void dr_cmd(int n, char cmdtok[][100]) {
534 int dr_list[m+5][30], ndr; 559 int dr_list[m+5][30], ndr;
535 if (from) { 560 if (from) {
536 ndr = drfrom_scram_spam(scram_unnissed, dr_list, from, fb, rl, ud, 561 ndr = drfrom_scram_spam(scram_unnissed, dr_list, from, fb, rl, ud,
537 m, b, niss, hide); 562 m, b, niss, hide);
538 if (ndr == -1) { 563 if (ndr == -1) {
539 printf("dr: from given, but EO not found (possibly other error).\n"); 564 printf("dr: from given, but EO not found (possibly other error).\n");
540 return; 565 return;
@@ -761,7 +786,7 @@ void exit_quit_cmd(int n, char cmdtok[][100]) {
761} 786}
762 787
763void (*cmd_list[])(int n, char cmdtok[][100]) = { 788void (*cmd_list[])(int n, char cmdtok[][100]) = {
764 help_cmd, save_cmd, change_cmd, print_cmd, 789 help_cmd, scramble_cmd, save_cmd, change_cmd, print_cmd,
765 add_cmd, invert_cmd, unniss_cmd, pic_cmd, 790 add_cmd, invert_cmd, unniss_cmd, pic_cmd,
766 solve_cmd, replace_cmd, 791 solve_cmd, replace_cmd,
767 eo_cmd, dr_cmd, htr_cmd, 792 eo_cmd, dr_cmd, htr_cmd,
diff --git a/src/solver.c b/src/solver.c
index d918a54..c61aec4 100644
--- a/src/solver.c
+++ b/src/solver.c
@@ -463,11 +463,11 @@ int dr_scram_spam(int scram[], int dr_list[][30], int fb, int rl, int ud,
463/* DR finish */ 463/* DR finish */
464/*************/ 464/*************/
465void dr_finish_dfs(int cp, int ep8, int ep4, int sol[][30], int *sol_count, 465void dr_finish_dfs(int cp, int ep8, int ep4, int sol[][30], int *sol_count,
466 int ep8_t_table[factorial8][19], 466 int ep8_t_table[factorial8][19],
467 int ep4_t_table[factorial4][19], 467 int ep4_t_table[factorial4][19],
468 int cp_p_table[factorial8], 468 int cp_p_table[factorial8],
469 int ep8_p_table[factorial8], 469 int ep8_p_table[factorial8],
470 int mask, int last1, int last2, int moves, int m, int d) { 470 int mask, int last1, int last2, int moves, int m, int d) {
471 471
472 472
473 if (*sol_count >= m || moves + cp_p_table[cp] > d || 473 if (*sol_count >= m || moves + cp_p_table[cp] > d ||
@@ -717,7 +717,7 @@ void small_optimal_dfs(int eofb, int eorl, int eoud, int ep,
717 } 717 }
718} 718}
719 719
720/* Solves directly using only medium tables. Suitable for short solutions. */ 720/* Solves directly using only medium tables. Suitable for short solutions.
721void medium_optimal_dfs(int eofb, int eorl, int eoud, 721void medium_optimal_dfs(int eofb, int eorl, int eoud,
722 int epose, int eposs, int eposm, int ep, 722 int epose, int eposs, int eposm, int ep,
723 int coud, int cofb, int corl, int cp, 723 int coud, int cofb, int corl, int cp,
@@ -766,6 +766,7 @@ void medium_optimal_dfs(int eofb, int eorl, int eoud,
766 } 766 }
767 } 767 }
768} 768}
769*/
769 770
770/* Uses huge tables */ 771/* Uses huge tables */
771int optimal_dfs(int ep, int cp, int eo, int co, int emslices, 772int optimal_dfs(int ep, int cp, int eo, int co, int emslices,
@@ -836,14 +837,6 @@ int solve_scram(int scram[], int sol[][30], int m, int b, int optimal) {
836 if (n >= m || b <= 10) 837 if (n >= m || b <= 10)
837 return n; 838 return n;
838 839
839 /* Then we try a slightly larger optimal solver */
840 /*
841 int max_medium = 11;
842 init_directdr_pruning_tables();
843 for (int i = 0; i <= min(b, max_medium); i++)
844 medium_optimal_dfs(eofb, eorl, eoud, epose, eposs, eposm, ep,
845 coud, cofb, corl, cp, sol, &n, 0, 0, 0, m, i);
846 */
847 840
848 /* If we found at least a solution, we return */ 841 /* If we found at least a solution, we return */
849 if (n > 0) 842 if (n > 0)
@@ -891,3 +884,82 @@ int solve_scram(int scram[], int sol[][30], int m, int b, int optimal) {
891 } 884 }
892 return best > b ? 0 : 1; 885 return best > b ? 0 : 1;
893} 886}
887
888/* Given eofb, coud, ep and cp it finds a scramble that reaches that state.
889 * It uses a simple 3-step solver to find a preliminary "solution", and then
890 * gives this solutions as a scramble to a better solver (see above). */
891int reach_state(int eofb, int coud, int ep, int cp, int sol[][30]) {
892
893 int fake_count = 0, fake_scram[30];
894 int eo_list[2][30], dr_list[2][30], finish_list[2][30];
895
896 /* Convert ep to array */
897 int ep_arr[12];
898 ep_int_to_array(ep, ep_arr);
899
900 /* Find EO */
901 init_small_pruning_tables();
902 for (int d = 0; d < 10; d++) {
903 niss_eo_dfs(eofb, fake_scram, eo_list, &fake_count, eofb_transition_table,
904 eofb_pruning_table, 0, 0, 0, 1, d, 0, 0, 0);
905 if (fake_count) {
906 fake_count = 0;
907 break;
908 }
909 }
910
911 /* Apply moves found, find epose */
912 for (int i = 0; eo_list[0][i]; i++) {
913 coud = coud_transition_table[coud][eo_list[0][i]];
914 cp = cp_transition_table[cp][eo_list[0][i]];
915 apply_move_ep_array(eo_list[0][i], ep_arr);
916 }
917 int epose = epose_array_to_int(ep_arr);
918
919 /* Find DR */
920 init_drfromeo_pruning_tables();
921 for (int d = 0; d < 16; d++) {
922 niss_dr_from_eo_dfs(coud, epose, fake_scram, fake_scram, dr_list,
923 &fake_count, coud_transition_table,
924 epose_transition_table,
925 coud_epose_from_eofb_pruning_table, move_mask_eofb,
926 0, 0, 0, 0, 0, 1, d, 0, 0, 0);
927 if (fake_count) {
928 fake_count = 0;
929 break;
930 }
931 }
932
933 /* Apply moves found, find epud and epe */
934 for (int i = 0; dr_list[0][i]; i++) {
935 cp = cp_transition_table[cp][dr_list[0][i]];
936 apply_move_ep_array(dr_list[0][i], ep_arr);
937 }
938 int epud = epud_array_to_int(ep_arr);
939 int epe = epe_array_to_int(ep_arr);
940
941 /* Find finish */
942 init_small_pruning_tables();
943 for (int d = 0; d < 16; d++) {
944 dr_finish_dfs(cp, epud, epe, finish_list, &fake_count,
945 epud_transition_table, epe_transition_table,
946 cp_drud_pruning_table, epud_pruning_table, move_mask_drud,
947 0, 0, 0, 1, d);
948 if (fake_count) {
949 fake_count = 0;
950 break;
951 }
952 }
953
954 int scram[50];
955
956 /* Debug */
957 /*print_moves(eo_list[0]); printf("\n");
958 print_moves(dr_list[0]); printf("\n");
959 print_moves(finish_list[0]); printf("\n");*/
960
961 copy_moves(eo_list[0], scram);
962 append_moves(dr_list[0], scram);
963 append_moves(finish_list[0], scram);
964 return solve_scram(scram, sol, 1, 25, 0);
965}
diff --git a/src/solver.h b/src/solver.h
index 14997ed..d154c8f 100644
--- a/src/solver.h
+++ b/src/solver.h
@@ -11,3 +11,4 @@ int dr_corners_scram_spam(int scram[], int sol[][30], int from, int m, int b,
11int dr_finish_scram_spam(int scram[], int sol[][30], int from, int m, int b); 11int dr_finish_scram_spam(int scram[], int sol[][30], int from, int m, int b);
12int htr_finish_scram_spam(int scram[], int sol[][30], int m, int b); 12int htr_finish_scram_spam(int scram[], int sol[][30], int m, int b);
13int solve_scram(int scram[], int sol[][30], int m, int b, int optimal); 13int solve_scram(int scram[], int sol[][30], int m, int b, int optimal);
14int reach_state(int eofb, int coud, int ep, int cp, int sol[][30]);
diff --git a/src/utils.c b/src/utils.c
index c672453..5b7df06 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -65,6 +65,23 @@ void index_to_perm(int p, int n, int *r) {
65 } 65 }
66} 66}
67 67
68
69int perm_sign_array(int a[], int n) {
70 int ret = 0;
71 for (int i = 0; i < n; i++)
72 for (int j = i+1; j < n; j++)
73 if (a[i]>a[j])
74 ret++;
75 return ret % 2;
76}
77
78int perm_sign_int(int p, int n) {
79 int a[n];
80 index_to_perm(p, n, a);
81 return perm_sign_array(a, n);
82}
83
84
68/* Converts a k-element subset of a set with an element from an array of n 85/* Converts a k-element subset of a set with an element from an array of n
69 * elements, of which k are 1 (or just non-zero) and n-k are 0, to its index 86 * elements, of which k are 1 (or just non-zero) and n-k are 0, to its index
70 * in the sorted list of all such subsets. 87 * in the sorted list of all such subsets.
diff --git a/src/utils.h b/src/utils.h
index b24ccb2..45a6302 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -36,6 +36,10 @@ int perm_to_index(int *a, int n);
36 * (see perm_to_index) and saves the result to r. */ 36 * (see perm_to_index) and saves the result to r. */
37void index_to_perm(int p, int n, int *r); 37void index_to_perm(int p, int n, int *r);
38 38
39/* Determine the sign of a permutation, either in integer or array format. */
40int perm_sign_array(int a[], int n);
41int perm_sign_int(int p, int n);
42
39/* Converts a k-element subset of a set with an element from an array of n 43/* Converts a k-element subset of a set with an element from an array of n
40 * elements, of which k are 1 and n-k are 0, to its index in the sorted list 44 * elements, of which k are 1 and n-k are 0, to its index in the sorted list
41 * of all such subsets. 45 * of all such subsets.

Generated with cgit - Back to sebastiano.tronto.net