commit e2b154c40acaac4e7a7b3e379ada0404519c3750
parent 36c317ebd1cf1dba8a8cbec494f4d3971e6cefd3
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date: Thu, 31 Jul 2025 08:38:37 +0200
Added solvetest for EO (broken for now)
Diffstat:
7 files changed, 437 insertions(+), 120 deletions(-)
diff --git a/tools/400_solvetest/solve_test.c b/tools/400_solvetest/solve_test.c
@@ -1,120 +0,0 @@
-#include "../tool.h"
-#include "scrambles.h"
-
-#define SOL_BUFFER_LEN 100000
-
-char *solver;
-int64_t size = 0;
-unsigned char *buf;
-
-bool check_one(char *actual, char *expected) {
- unsigned i;
- size_t l_actual, l_expected;
-
- for (l_actual = 0; actual[l_actual] != '\n'; l_actual++) ;
- l_expected = strlen(expected);
- if (l_actual > l_expected)
- return false;
- for (i = 0; i < l_expected; i++) {
- if (!strncmp(actual, &expected[i], l_actual))
- return true;
- while(expected[i] != '\n') i++;
- }
- return false;
-}
-
-bool check_all(char *actual, char *expected) {
- unsigned i, found, n_expected;
- size_t l_actual;
-
- l_actual = strlen(actual);
- if (l_actual != strlen(expected))
- return false;
-
- for (i = 0, n_expected = 0; expected[i]; i++)
- n_expected += expected[i] == '\n';
-
- for (i = 0, found = 0; i < l_actual; i++)
- if (i == 0 || actual[i-1] == '\n')
- found += check_one(&actual[i], expected);
-
- return found == n_expected;
-}
-
-void run(void) {
- int i;
- int64_t n;
- long long stats[NISSY_SIZE_SOLVE_STATS];
- char sol[SOL_BUFFER_LEN], cube[NISSY_SIZE_CUBE];
-
- for (i = 0; s[i].scramble[0]; i++) {
- printf("\n%d. %s\n", i, s[i].scramble);
-
- /* Single solution */
- if (nissy_applymoves(NISSY_SOLVED_CUBE, s[i].scramble, cube)
- == -1) {
- printf("Invalid scramble\n");
- continue;
- }
- n = nissy_solve(cube, solver, NISSY_NISSFLAG_NORMAL,
- 0, 20, 1, -1, 0, size, buf, SOL_BUFFER_LEN, sol, stats,
- NULL, NULL);
- if (n == 0) {
- printf("Error: no solution\n");
- return;
- }
- if (check_one(sol, s[i].solutions)) {
- printf("Single solution is correct\n");
- } else {
- printf("Error!\n");
- printf("Found solution(s):\n%s", sol);
- printf("Valid solution(s):\n%s", s[i].solutions);
- return;
- }
-
- /* Multiple solutions */
- if (nissy_applymoves(NISSY_SOLVED_CUBE, s[i].scramble, cube)
- == -1) {
- printf("Invalid scramble\n");
- continue;
- }
- n = nissy_solve(cube, solver, NISSY_NISSFLAG_NORMAL,
- 0, 20, 100, 0, 0, size, buf, SOL_BUFFER_LEN, sol, stats,
- NULL, NULL);
- if (check_all(sol, s[i].solutions)) {
- printf("All solutions are correct\n");
- } else {
- printf("Error!\n");
- printf("Found solution(s):\n%s", sol);
- printf("Valid solution(s):\n%s", s[i].solutions);
- return;
- }
- }
-
- printf("\nAll scrambles solved correctly\n");
-}
-
-int main(int argc, char **argv) {
- char filename[255], dataid[NISSY_SIZE_DATAID];
-
- if (argc < 2) {
- printf("Error: not enough arguments. "
- "A solver must be given.\n");
- return 1;
- }
-
- solver = argv[1];
- srand(time(NULL));
- nissy_setlogger(log_stderr, NULL);
-
- sprintf(filename, "tables/%s", solver);
- if (getdata(solver, &buf, filename) != 0)
- return 1;
-
- size = nissy_solverinfo(solver, dataid);
-
- timerun(run);
-
- free(buf);
- return 0;
-}
diff --git a/tools/400_solvetest/scrambles.h b/tools/400_solvetest_optimal/scrambles.h
diff --git a/tools/400_solvetest_optimal/solvetest.c b/tools/400_solvetest_optimal/solvetest.c
@@ -0,0 +1,8 @@
+#define NISSFLAG NISSY_NISSFLAG_NORMAL
+#define MINMOVES 0
+#define MAXMOVES 20
+#define MAXSOLUTIONS 100
+#define OPTIMAL 0
+
+#include "scrambles.h"
+#include "../solvetest.h"
diff --git a/tools/401_solvetest_opt0_EO_FB/scrambles.h b/tools/401_solvetest_opt0_EO_FB/scrambles.h
@@ -0,0 +1,300 @@
+struct {
+ char *scramble;
+ char *solutions;
+} s[] = {
+[0] = {
+ .scramble = "B R' F2 D' B' R B' L U R2 U' B2 U L2 B2 L2 U' D R2 U B2 R2",
+ .solutions =
+ "L F' U' F\n"
+ "L' F D F\n"
+ "R B' U' B\n"
+ "R' B D B\n"
+ "(U2 F' L2 F)\n"
+ "(L2 F U2 F)\n"
+ "(U B' U' B)\n"
+ "(U2 B' U2 B)\n"
+ "(U' B' U B)\n"
+ "(L B L' B)\n"
+ "(L2 B L2 B)\n"
+ "(L' B L B)\n"
+ "B (U D' B)\n"
+ "B R' B (B)\n"
+},
+[1] = {
+ .scramble = "U2 L F' B R2 B2 D' B R L2 D' L2 B2 L2 U' F2 U' L2 D2 B2 U' L2",
+ .solutions =
+ "(B U D2 F)\n"
+ "R B (U' B)\n"
+ "R L B (B)\n"
+ "B (B R B)\n"
+},
+[2] = {
+ .scramble = "U2 F U D' L2 U' B U L U R2 D2 B2 D' F2 U' L2 U2 F2 R2 F2",
+ .solutions =
+ "(D' B D2 F)\n"
+ "(D' F L2 B)\n"
+ "(F D' L2 B)\n"
+ "(F L D' B)\n"
+},
+[3] = {
+ .scramble = "F2 R B' U D' F U L2 D2 R F L2 U2 B' R2 D2 F2 B' D2 L2 F2",
+ .solutions =
+ "B R F (U2 F)\n"
+ "B R' F (U F)\n"
+ "B' R F (U2 F)\n"
+ "B' R' F (U F)\n"
+ "B (B2 U F B)\n"
+ "B (B2 U' F B)\n"
+ "F B (U R' F)\n"
+ "F B (R' U2 F)\n"
+},
+[4] = {
+ .scramble = "R' U' D' B D2 R' U L' D' F U L2 B2 U F2 U D L2 F2 L2 F2",
+ .solutions =
+ "D L' B (B)\n"
+ "L' D B (B)\n"
+},
+[5] = {
+ .scramble = "D' B R B2 L' F R U' R2 B' R2 F2 D' L2 U' L2 U B2 D F2 D' F2 L2",
+ .solutions =
+ "U F (R2 B)\n"
+},
+[6] = {
+ .scramble = "L2 B' U D2 R2 D' B' L' U L2 U' F2 R2 D B2 L2 U2 D B2",
+ .solutions =
+ "F' B U F\n"
+ "F' B' U F\n"
+ "(D B' U2 F)\n"
+ "(D' B' U2 F)\n"
+ "(D F' L2 B)\n"
+ "(D' F' L2 B)\n"
+ "B (F D F)\n"
+},
+[7] = {
+ .scramble = "F2 D' L2 B L F L B2 U' F2 R2 L2 U2 L2 F L2 B2 R2 B U2",
+ .solutions =
+ "F U' L' D' F\n"
+ "F' U' R D F\n"
+ "F' R U' D F\n"
+ "(B D B L F)\n"
+ "(B D B' L F)\n"
+ "(B D' B L F)\n"
+ "(B D' B' L F)\n"
+ "(D F U2 R B)\n"
+ "(D' F U2 R B)\n"
+ "(L' B D F B)\n"
+ "(L' B D' F B)\n"
+ "(B L' D F B)\n"
+ "(B L' D' F B)\n"
+ "U F (D2 L' F)\n"
+ "U2 F (D' L' F)\n"
+ "U2 F (F2 R F)\n"
+ "U2 D' F (L2 F)\n"
+ "U2 R F (L F)\n"
+ "U' F (F D' F)\n"
+ "R U2 F (L F)\n"
+ "F (U D' L F)\n"
+ "F (U L D' F)\n"
+ "F (D' F2 R' F)\n"
+ "F (F D' R' F)\n"
+ "F (F2 U R F)\n"
+ "F' D L2 B (F)\n"
+ "F' L2 D B (F)\n"
+},
+[8] = {
+ .scramble = "D L2 F2 L U B R2 L' F U R2 U F2 D2 B2 R2 D' R2 U' F2 L2 D'",
+ .solutions =
+ "R' B U' R2 F\n"
+ "R' B R2 U' F\n"
+ "(F R2 U' D' F)\n"
+ "(U F L2 D' B)\n"
+ "(F L2 U' D' B)\n"
+ "(F2 B U F B)\n"
+ "(F2 B U' F B)\n"
+ "U' R D F (F)\n"
+ "D F (F U B)\n"
+ "D F (F' U B)\n"
+ "R F (D2 L F)\n"
+ "R F (L D2 F)\n"
+ "R U' D F (F)\n"
+ "F (B L2 D F)\n"
+ "B U' F (D' B)\n"
+ "B' U' F (D' B)\n"
+ "U2 F R B (B)\n"
+ "U2 F' R B (B)\n"
+ "F U R B (B)\n"
+ "F B2 L' B (B)\n"
+ "F' U R B (B)\n"
+ "F' B2 L' B (B)\n"
+},
+[9] = {
+ .scramble = "F R L2 U2 L' U2 R D' L F D2 L2 F R2 D2 B R2 U2 F2 R2 F",
+ .solutions =
+ "D2 B (F)\n"
+},
+[10] = {
+ .scramble = "R' U' R2 L2 D' L' F' B R2 D' F' U2 D2 L2 U2 F' U2 B2 R2 B D2",
+ .solutions =
+ "U' B R2 D' F\n"
+ "F U B R2 F\n"
+ "F U' B R2 F\n"
+ "F2 U B' L2 F\n"
+ "F2 U' B' L2 F\n"
+ "F U F D2 B\n"
+ "F U' F D2 B\n"
+ "F2 U F' D2 B\n"
+ "F2 U' F' D2 B\n"
+ "(B L B U F)\n"
+ "(B L B' U F)\n"
+ "(B L' B U F)\n"
+ "(B L' B' U F)\n"
+ "(L F R2 D B)\n"
+ "(L' F R2 D B)\n"
+ "(U' B L F B)\n"
+ "(U' B L' F B)\n"
+ "(B U' L F B)\n"
+ "(B U' L' F B)\n"
+ "U' R' F (L F)\n"
+ "R' F (D L F)\n"
+ "F2 L F (L F)\n"
+ "F2 L2 F (L' F)\n"
+ "B2 R2 F (L' F)\n"
+ "U2 B (D' L B)\n"
+ "U2 B (L D2 B)\n"
+},
+[11] = {
+ .scramble = "U B D R' L2 U' L' F2 L' B' R2 B2 L2 B2 D R2 F2 D R2 F2 D' L2",
+ .solutions =
+ "D R F\n"
+ "F2 L' F\n"
+},
+[12] = {
+ .scramble = "U2 L' U L U' L2 U F' R F U2 F2 D' B2 D' F2 R2 U' F2 R2 U",
+ .solutions =
+ "F L F\n"
+ "(F' R F)\n"
+},
+[13] = {
+ .scramble = "U2 D R L U' R L F' R F D2 B L2 F' L2 D2 F U2 D2 F D2",
+ .solutions =
+ "U R2 B (F)\n"
+ "R2 U B (F)\n"
+ "B (U' D F)\n"
+},
+[14] = {
+ .scramble = "L' B L F D' L U R' F2 B' R2 U2 B R2 U2 B U2 B' L2 U2 B2",
+ .solutions =
+ "U D F B\n"
+ "U D' F B\n"
+ "U' D F B\n"
+ "U' D' F B\n"
+ "D2 F (F B)\n"
+},
+[15] = {
+ .scramble = "B D F L2 D2 L' B' R B' R2 L2 U' B2 U F2 U' D' B2 U' F2",
+ .solutions =
+ "U' F R L B\n"
+ "U' F' R L B\n"
+ "L' U' F R B\n"
+ "L' U' F' R B\n"
+ "L' F R U B\n"
+ "L' F' R U B\n"
+ "F R U L B\n"
+ "F' R U L B\n"
+ "(D' R' B D' F)\n"
+ "(D' R' B' D' F)\n"
+ "(R B D R' F)\n"
+ "(R B R' D F)\n"
+ "(R B' D R' F)\n"
+ "(R B' R' D F)\n"
+ "(R2 D' B R F)\n"
+ "(R2 D' B' R F)\n"
+ "(R2 B R D F)\n"
+ "(R2 B' R D F)\n"
+ "(D F D' R B)\n"
+ "(D F R D' B)\n"
+ "(D F' D' R B)\n"
+ "(D F' R D' B)\n"
+ "(D2 R' F D B)\n"
+ "(D2 R' F' D B)\n"
+ "(D2 F D R B)\n"
+ "(D2 F' D R B)\n"
+ "(R' D' F R' B)\n"
+ "(R' D' F' R' B)\n"
+ "U B' D2 F (F)\n"
+ "U' F (D R' F)\n"
+ "U' F (R' D F)\n"
+ "U' D2 F (D F)\n"
+ "U' B' D2 F (F)\n"
+ "D2 F (U2 D F)\n"
+ "R' L' F (R B)\n"
+ "L' F (R L B)\n"
+ "F (U D R' F)\n"
+ "F (U R' D F)\n"
+ "F (D R' U2 F)\n"
+ "F (R' U2 D F)\n"
+ "F (D' R L2 B)\n"
+ "F (R D' L2 B)\n"
+ "F (R L D' B)\n"
+ "F (L D' R B)\n"
+ "U F' R2 B (F)\n"
+ "U' R' B (F B)\n"
+ "U' F' R2 B (F)\n"
+ "R B (F R' B)\n"
+ "R B (F' R' B)\n"
+},
+[16] = {
+ .scramble = "D F2 R L B D' F' R' B L' D2 L' U2 R U2 B2 L F2 L2 B2",
+ .solutions =
+ "R F B (B)\n"
+ "R' F B (B)\n"
+},
+[17] = {
+ .scramble = "R U2 F' L B' R' D2 L' F' D' R2 D' R2 D' F2 R2 F2 D R2",
+ .solutions =
+ "R' F (L B)\n"
+},
+[18] = {
+ .scramble = "B' R2 B2 R D' R U' F2 U2 D L2 F' D2 R2 F2 D2 R2 L2 B' D2 B",
+ .solutions =
+ "B' U' D2 F\n"
+ "(U2 B' R2 F)\n"
+ "(R2 B U2 F)\n"
+ "(U2 F' U2 B)\n"
+ "(R2 F R2 B)\n"
+ "F D2 F (B)\n"
+ "B R2 B (B)\n"
+},
+[19] = {
+ .scramble = "B L U' R2 D2 F B L U2 F' R2 F2 R2 L2 D' B2 L2 D2 L2 D' L2",
+ .solutions =
+ "U L' B D2 F\n"
+ "U B D L' F\n"
+ "U B L' D2 F\n"
+ "U' L' B D2 F\n"
+ "U' B D L' F\n"
+ "U' B L' D2 F\n"
+ "U L' F L2 B\n"
+ "U' L' F L2 B\n"
+ "F' U F L B\n"
+ "F' U F' L B\n"
+ "F' U' F L B\n"
+ "F' U' F' L B\n"
+ "F' L' U F B\n"
+ "F' L' U' F B\n"
+ "(R' L B U2 F)\n"
+ "(R' L' B U2 F)\n"
+ "(L B U R' F)\n"
+ "(L B R' U2 F)\n"
+ "(L' B U R' F)\n"
+ "(L' B R' U2 F)\n"
+ "(R' L F R2 B)\n"
+ "(R' L' F R2 B)\n"
+ "(F L F R B)\n"
+ "(F L F' R B)\n"
+ "(F L' F R B)\n"
+ "(F L' F' R B)\n"
+ "(R F L F B)\n"
+ "(R F L' F B)\n"
+},
+};
diff --git a/tools/401_solvetest_opt0_EO_FB/solvetest.c b/tools/401_solvetest_opt0_EO_FB/solvetest.c
@@ -0,0 +1,8 @@
+#define NISSFLAG NISSY_NISSFLAG_ALL
+#define MINMOVES 0
+#define MAXMOVES 20
+#define MAXSOLUTIONS 500
+#define OPTIMAL 0
+
+#include "scrambles.h"
+#include "../solvetest.h"
diff --git a/tools/solvetest.h b/tools/solvetest.h
@@ -0,0 +1,98 @@
+#include "tool.h"
+
+#define SOL_BUFFER_LEN 100000
+
+char *solver;
+int64_t size = 0;
+unsigned char *buf;
+
+bool check_one(char *actual, char *expected) {
+ unsigned i;
+ size_t l_actual, l_expected;
+
+ for (l_actual = 0; actual[l_actual] != '\n'; l_actual++) ;
+ l_expected = strlen(expected);
+ if (l_actual > l_expected)
+ return false;
+ for (i = 0; i < l_expected; i++) {
+ if (!strncmp(actual, &expected[i], l_actual))
+ return true;
+ while(expected[i] != '\n') i++;
+ }
+ return false;
+}
+
+bool check_all(char *actual, char *expected) {
+ unsigned i, found, n_expected;
+ size_t l_actual;
+
+ l_actual = strlen(actual);
+ if (l_actual != strlen(expected))
+ return false;
+
+ for (i = 0, n_expected = 0; expected[i]; i++)
+ n_expected += expected[i] == '\n';
+
+ for (i = 0, found = 0; i < l_actual; i++)
+ if (i == 0 || actual[i-1] == '\n')
+ found += check_one(&actual[i], expected);
+
+ return found == n_expected;
+}
+
+void run(void) {
+ int i;
+ int64_t n;
+ long long stats[NISSY_SIZE_SOLVE_STATS];
+ char sol[SOL_BUFFER_LEN], cube[NISSY_SIZE_CUBE];
+
+ for (i = 0; s[i].scramble[0]; i++) {
+ printf("\n%d. %s\n", i, s[i].scramble);
+
+ /* Multiple solutions */
+ if (nissy_applymoves(NISSY_SOLVED_CUBE, s[i].scramble, cube)
+ == -1) {
+ printf("Invalid scramble\n");
+ continue;
+ }
+ n = nissy_solve(cube, solver,
+ NISSFLAG, MINMOVES, MAXMOVES, MAXSOLUTIONS, OPTIMAL,
+ 0, size, buf, SOL_BUFFER_LEN, sol, stats,
+ NULL, NULL);
+ if (check_all(sol, s[i].solutions)) {
+ printf("All solutions are correct\n");
+ } else {
+ printf("Error!\n");
+ printf("Found solution(s):\n%s", sol);
+ printf("Valid solution(s):\n%s", s[i].solutions);
+ return;
+ }
+ }
+
+ printf("\nAll scrambles solved correctly\n");
+}
+
+int main(int argc, char **argv) {
+ char filename[255], dataid[NISSY_SIZE_DATAID];
+
+ if (argc < 2) {
+ printf("Error: not enough arguments. "
+ "A solver must be given.\n");
+ return 1;
+ }
+
+ solver = argv[1];
+ srand(time(NULL));
+ nissy_setlogger(log_stderr, NULL);
+
+ sprintf(filename, "tables/%s", solver);
+ if (getdata(solver, &buf, filename) != 0)
+ return 1;
+
+ size = nissy_solverinfo(solver, dataid);
+
+ timerun(run);
+
+ free(buf);
+ return 0;
+}
diff --git a/utils/solvetest_gen.sh b/utils/solvetest_gen.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+args="$@"
+
+getsolutions() {
+ nissy solve -p $args "$1" |
+ while read -r solution; do
+ printf '\t\t"%s\\n"\n' "$solution"
+ done
+}
+
+printf "struct {\n\tchar *scramble;\n\tchar *solutions;\n} s[] = {\n"
+
+i=0
+while read -r scramble; do
+ solutions="$(getsolutions "$scramble")"
+ printf '[%s] = {\n\t.scramble = "%s",\n' "$i" "$scramble"
+ printf '\t.solutions =\n%s\n' "$solutions"
+ printf '},\n'
+ i=$((i+1))
+done
+
+printf "};\n"