commit 0550a16c1cce868bbc3f3b5ad59f80e35cf2a6cd
parent ab95e3801f6659aa6b25ebd9a69b2e23dded130e
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date: Wed, 19 Mar 2025 17:16:41 +0100
Filter solutions for coordinate solver and fix ordering
Diffstat:
5 files changed, 35 insertions(+), 18 deletions(-)
diff --git a/TODO_COORDINATES b/TODO_COORDINATES
@@ -1,15 +0,0 @@
-- filter solutions
- - allow not showing repeated solutions like R2 F and R2 F' for EO
- - avoid B2 F as an EO
-- in nissy.c, check for minmoves, maxmoves and nissflag (must be in range)
-- add a dispatcher in solvers.h?
-- test solver for EO (with unit test or tool)
-- add NISS (and add tests for NISS EO)
-- make solve parallelized
-- other coordinates
- - gendata must handle symmetry
-- make gendata parallelized
-
-- refactor common parts of coord and h48 solvers
-- move parse_h48 to h48 module?
- then maybe do like for coordinate and exclude the "h48" part
diff --git a/src/core/moves.h b/src/core/moves.h
@@ -6,6 +6,8 @@ STATIC_INLINE uint32_t allowednextmove_mask(uint8_t *, uint8_t);
STATIC_INLINE uint8_t movebase(uint8_t);
STATIC_INLINE uint8_t moveaxis(uint8_t);
+STATIC_INLINE bool isbase(uint8_t);
+STATIC_INLINE bool parallel(uint8_t, uint8_t);
STATIC_INLINE uint32_t disable_moves(uint32_t, uint8_t);
STATIC cube_t move(cube_t, uint8_t);
@@ -13,6 +15,7 @@ STATIC cube_t premove(cube_t, uint8_t);
STATIC uint8_t inverse_move(uint8_t);
STATIC void invertmoves(uint8_t *, uint8_t, uint8_t *);
STATIC void sortparallel(uint8_t *, uint8_t);
+STATIC bool are_lastmoves_singlecw(int n, uint8_t [n]);
STATIC int readmoves(const char *, int, uint8_t *);
STATIC cube_t applymoves(cube_t, const char *);
@@ -91,6 +94,18 @@ moveaxis(uint8_t move)
return move / 6;
}
+STATIC_INLINE bool
+isbase(uint8_t move)
+{
+ return move == 3 * movebase(move);
+}
+
+STATIC_INLINE bool
+parallel(uint8_t m1, uint8_t m2)
+{
+ return moveaxis(m1) == moveaxis(m2);
+}
+
STATIC_INLINE uint8_t
moveopposite(uint8_t move)
{
@@ -241,6 +256,19 @@ sortparallel(uint8_t *moves, uint8_t n)
SWAP(moves[i], moves[i+1]);
}
+STATIC bool
+are_lastmoves_singlecw(int n, uint8_t moves[n])
+{
+ bool two;
+
+ if (n == 0)
+ return true;
+
+ two = n > 1 && parallel(moves[n-1], moves[n-2]);
+
+ return isbase(moves[n-1]) && (!two || isbase(moves[n-2]));
+}
+
STATIC int
readmoves(const char *buf, int max, uint8_t *ret)
{
diff --git a/src/solvers/coord/eo.h b/src/solvers/coord/eo.h
@@ -15,6 +15,7 @@ STATIC coord_t coordinate_eo = {
[AXIS_RL] = TRANS_URr,
[AXIS_FB] = TRANS_UFr,
},
+ .is_admissible = &are_lastmoves_singlecw,
};
STATIC uint64_t
diff --git a/src/solvers/coord/solve.h b/src/solvers/coord/solve.h
@@ -35,15 +35,17 @@ solve_coord_appendsolution(dfsarg_solve_coord_t *arg)
char *m;
if (*arg->nsols >= arg->maxsolutions ||
- arg->nmoves > *arg->shortest_sol + arg->optimal)
+ arg->nmoves > *arg->shortest_sol + arg->optimal ||
+ (arg->coord->is_admissible != NULL &&
+ !arg->coord->is_admissible(arg->nmoves, arg->moves)))
return 0;
- sortparallel(arg->moves, arg->nmoves);
-
t = inverse_trans(arg->trans);
for (i = 0; i < arg->nmoves; i++)
tmoves[i] = transform_move(arg->moves[i], t);
+ sortparallel(tmoves, arg->nmoves);
+
l = arg->solutions_size - *arg->solutions_used;
m = *arg->solutions + *arg->solutions_used;
strl = writemoves(tmoves, arg->nmoves, l, m);
diff --git a/src/solvers/coord/types_macros.h b/src/solvers/coord/types_macros.h
@@ -11,4 +11,5 @@ typedef struct {
uint32_t moves_mask;
uint64_t trans_mask;
uint8_t axistrans[3];
+ bool (*is_admissible)(int n, uint8_t [n]);
} coord_t;