commit 30d976107352ecf74c57acc1032bed6032cd3da3
parent f283c08db86777fe77bdf00d3d70687107a376d9
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date: Fri, 19 Dec 2025 07:38:05 +0100
Merge branch 'h48-corner-estimate'
Diffstat:
13 files changed, 144 insertions(+), 2 deletions(-)
diff --git a/doc/solvers.md b/doc/solvers.md
@@ -129,6 +129,17 @@ NISS will not be used.
* Moveset: {U, U', U2, D, D', D2, R2, L2, F2, B2}.
* Data size: 54MB.
+### Solve corners
+
+Solve the corners of the cube. Note: centers are considered fixed,
+this is not the same as solving a 2x2x2 cube.
+
+* Name: `coord_DRFIN_UF`. Other rotations in place of `UF` are allowed,
+ but they are irrelevant to the solver. Provided alias: `corners`.
+* Requisites: none.
+* Moveset: HTM (all 18 basic moves).
+* Data size: 1.2MB.
+
### Undocumented coordinate solvers
There are some coordinate solvers that have not been listed above. These
diff --git a/src/arch/avx2.h b/src/arch/avx2.h
@@ -160,6 +160,16 @@ coord_co(cube_t c)
return ret;
}
+STATIC_INLINE void
+copy_co(cube_t cube[static 1], cube_t co)
+{
+ cube_t coclean;
+
+ coclean = _mm256_and_si256(co, CO2_AVX2);
+ *cube = _mm256_andnot_si256(CO2_AVX2, *cube);
+ *cube = _mm256_or_si256(*cube, coclean);
+}
+
STATIC_INLINE cube_t
invcoord_co(uint64_t coord)
{
@@ -174,7 +184,7 @@ invcoord_co(uint64_t coord)
cc = _mm256_loadu_si256((__m256i *)mem);
cube = SOLVED_CUBE;
- copy_corners(&cube, cc);
+ copy_co(&cube, cc);
return cube;
}
diff --git a/src/arch/common.h b/src/arch/common.h
@@ -35,6 +35,7 @@ STATIC_INLINE cube_t invcoord_epudsep(uint64_t);
STATIC_INLINE bool is_eo_even(cube_t);
STATIC_INLINE void copy_corners(cube_t [static 1], cube_t);
+STATIC_INLINE void copy_co(cube_t [static 1], cube_t);
STATIC_INLINE void copy_edges(cube_t [static 1], cube_t);
STATIC_INLINE void set_eo(cube_t [static 1], uint64_t);
diff --git a/src/arch/neon.h b/src/arch/neon.h
@@ -232,6 +232,16 @@ coord_co(cube_t c)
return ret;
}
+STATIC_INLINE void
+copy_co(cube_t cube[static 1], cube_t co)
+{
+ uint8x8_t coclean;
+
+ coclean = vand_u8(co.corner, CO2_NEON);
+ cube->corner = vbic_u8(cube->corner, CO2_NEON);
+ cube->corner = vorr_u8(cube->corner, coclean);
+}
+
STATIC_INLINE cube_t
invcoord_co(uint64_t coord)
{
diff --git a/src/arch/portable.h b/src/arch/portable.h
@@ -154,6 +154,19 @@ inverse(cube_t cube)
return ret;
}
+STATIC_INLINE void
+copy_co(cube_t cube[static 1], cube_t co)
+{
+ uint8_t c;
+ size_t i;
+
+ for (i = 0; i < 8; i++) {
+ c = cube->corner[i] & COBITS;
+ cube->corner[i] ^= c;
+ cube->corner[i] |= co.corner[i] & COBITS;
+ }
+}
+
STATIC_INLINE uint64_t
coord_co(cube_t c)
{
diff --git a/src/core/cube.h b/src/core/cube.h
@@ -1,3 +1,5 @@
+STATIC bool cube_true(cube_t);
+
STATIC cube_t cubefromarray(uint8_t [static 8], uint8_t [static 12]);
STATIC bool isconsistent(oriented_cube_t);
STATIC bool issolvable(oriented_cube_t);
@@ -19,6 +21,13 @@ STATIC uint8_t b32tocorner(char);
STATIC char edgetob32(uint8_t);
STATIC char cornertob32(uint8_t);
+/* Used e.g. by the CORNERS coordinate, when a function pointer is needed */
+STATIC bool
+cube_true(cube_t cube)
+{
+ return true;
+}
+
STATIC cube_t
cubefromarray(uint8_t c[static 8], uint8_t e[static 12])
{
diff --git a/src/solvers/coord/common.h b/src/solvers/coord/common.h
@@ -14,6 +14,7 @@ STATIC bool coord_is_solved(
STATIC cube_t coordinate_merge_ce(cube_t, cube_t);
STATIC cube_t coordinate_merge_ec(cube_t, cube_t);
+STATIC cube_t coordinate_merge_cpco(cube_t, cube_t);
STATIC uint64_t
coord_coord_generic(
@@ -215,3 +216,14 @@ coordinate_merge_ec(cube_t edges, cube_t corners)
{
return coordinate_merge_ce(corners, edges);
}
+
+STATIC cube_t
+coordinate_merge_cpco(cube_t cp, cube_t co)
+{
+ cube_t merged;
+
+ merged = cp;
+ copy_co(&merged, co);
+
+ return merged;
+}
diff --git a/src/solvers/coord/coord.h b/src/solvers/coord/coord.h
@@ -8,6 +8,7 @@
#include "cpepe.h"
#include "drfin.h"
#include "htr.h"
+#include "corners.h"
#include "list.h"
#include "utils.h"
#include "gendata.h"
diff --git a/src/solvers/coord/corners.h b/src/solvers/coord/corners.h
@@ -0,0 +1,72 @@
+#define CLASSES_CP_48 984
+
+STATIC uint64_t coordinate_corners_coord(const cube_t, const unsigned char *);
+STATIC cube_t coordinate_corners_cube(uint64_t, const unsigned char *);
+STATIC bool coordinate_corners_isnasty(uint64_t, const unsigned char *);
+STATIC size_t coordinate_corners_gendata(unsigned char *);
+
+STATIC coord_t coordinate_corners = {
+ .name = "CORNERS",
+ .coord = &coordinate_corners_coord,
+ .cube = &coordinate_corners_cube,
+ .isnasty = &coordinate_corners_isnasty,
+ .gendata = coordinate_corners_gendata,
+ .max = CLASSES_CP_48 * POW_3_7,
+ .trans_mask = TM_ALLTRANS,
+ .moves_mask_gendata = MM18_ALLMOVES,
+ .moves_mask_solve = MM18_ALLMOVES,
+ .is_admissible = &solution_always_valid,
+ .solution_prune = NULL,
+ .is_solvable = &cube_true,
+ .is_solved = NULL,
+ .allow_niss = false,
+ .pruning_distribution = {
+ [0] = 1,
+ [1] = 2,
+ [2] = 9,
+ [3] = 76,
+ [4] = 708,
+ [5] = 5022,
+ [6] = 28248,
+ [7] = 132076,
+ [8] = 505705,
+ [9] = 1102421,
+ [10] = 375380,
+ [11] = 2360,
+ },
+ .pruning_max = 11,
+ .sym = {
+ .classes = CLASSES_CP_48,
+ .max = FACT_8,
+ .coord = &coord_cp,
+ .cube = &invcoord_cp,
+ .max2 = POW_3_7,
+ .coord2 = &coord_co,
+ .cube2 = &invcoord_co,
+ .merge = &coordinate_merge_cpco,
+ },
+};
+
+STATIC uint64_t
+coordinate_corners_coord(const cube_t cube, const unsigned char *data)
+{
+ return coord_coord_generic(&coordinate_corners, cube, data);
+}
+
+STATIC cube_t
+coordinate_corners_cube(uint64_t i, const unsigned char *data)
+{
+ return coord_cube_generic(&coordinate_corners, i, data);
+}
+
+STATIC bool
+coordinate_corners_isnasty(uint64_t i, const unsigned char *data)
+{
+ return coord_isnasty_generic(&coordinate_corners, i, data);
+}
+
+STATIC size_t
+coordinate_corners_gendata(unsigned char *data)
+{
+ return coord_gendata_generic(&coordinate_corners, data);
+}
diff --git a/src/solvers/coord/list.h b/src/solvers/coord/list.h
@@ -6,6 +6,7 @@ coord_t *all_coordinates[] = {
&coordinate_drslice,
&coordinate_cpepe,
&coordinate_htr,
+ &coordinate_corners,
NULL
};
diff --git a/src/solvers/coord/types_macros.h b/src/solvers/coord/types_macros.h
@@ -30,6 +30,7 @@ typedef struct {
bool (*is_admissible)(const solution_moves_t[static 1]);
bool (*solution_prune)(const solution_moves_t[static 1]);
bool (*is_solvable)(cube_t);
+ /* if is_solved is nulle, coord == 0 is used */
bool (*is_solved)(uint64_t, const unsigned char *);
uint64_t pruning_distribution[INFO_DISTRIBUTION_LEN];
uint8_t pruning_max;
diff --git a/src/solvers/dispatch.h b/src/solvers/dispatch.h
@@ -65,6 +65,7 @@ const char *solver_aliases[][2] = {
{ "htr-drud", "coord_HTR_UF" },
{ "htr-drrl", "coord_HTR_LF" },
{ "htr-drfb", "coord_HTR_BU" },
+ { "corners", "coord_CORNERS_UF" },
{ NULL, NULL }
};
diff --git a/src/solvers/solvers.h b/src/solvers/solvers.h
@@ -3,6 +3,6 @@
#include "tables_types_macros.h"
#include "tables.h"
#include "distribution.h"
-#include "h48/h48.h"
#include "coord/coord.h"
+#include "h48/h48.h"
#include "dispatch.h"