aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md12
-rwxr-xr-xbenchmark/bench.sh2
-rw-r--r--cube.c107
-rw-r--r--cube.h3
-rwxr-xr-xtest/test.sh2
5 files changed, 97 insertions, 29 deletions
diff --git a/README.md b/README.md
index 383b50c..505b840 100644
--- a/README.md
+++ b/README.md
@@ -37,6 +37,12 @@ for benchmarks.
37 37
38## TODO: 38## TODO:
39 39
40### Simple solver
41
42* tests
43* finish implementation
44* benchmarks
45
40### Coordinates 46### Coordinates
41 47
42* [done] eo 48* [done] eo
@@ -55,8 +61,10 @@ All solving functions take a cube and some parameters as input.
55 61
56* Depth [uint, <= 20]: all solvers work at fixed depth. The caller 62* Depth [uint, <= 20]: all solvers work at fixed depth. The caller
57 implementation can implement an A* search. 63 implementation can implement an A* search.
58* Full [bool]: if false, stop at first solution found, otherwise 64* max [int]: the maximum number of solutions to find. Set to a negative
59 find all solutions at that depth. 65 value for all solutions.
66* sol [move_t *]: the array for returning the solutions. The caller
67 should make sure that it can hold at least max * depth values.
60* Table [uint8_t *]: table with all the necessare pre-computed info. 68* Table [uint8_t *]: table with all the necessare pre-computed info.
61 The table can be generated with a companion function, but reading 69 The table can be generated with a companion function, but reading
62 from and writing to file is delegated to the caller implementation. 70 from and writing to file is delegated to the caller implementation.
diff --git a/benchmark/bench.sh b/benchmark/bench.sh
index 882c836..ec850f0 100755
--- a/benchmark/bench.sh
+++ b/benchmark/bench.sh
@@ -1,6 +1,6 @@
1#!/bin/sh 1#!/bin/sh
2 2
3CC="cc -std=c99 -pthread -O3 -D$CUBETYPE" 3CC="cc -std=c99 -O3 -D$CUBETYPE"
4if [ "$CUBETYPE" = "CUBE_AVX2" ]; then 4if [ "$CUBETYPE" = "CUBE_AVX2" ]; then
5 CC="$CC -mavx2" 5 CC="$CC -mavx2"
6fi 6fi
diff --git a/cube.c b/cube.c
index 8ca2c72..3a85054 100644
--- a/cube.c
+++ b/cube.c
@@ -2129,33 +2129,33 @@ in the previous section(s) for unsupported architectures.
2129#else 2129#else
2130 2130
2131#define PERM4(r, i, j, k, l) \ 2131#define PERM4(r, i, j, k, l) \
2132 aux = r[i]; \ 2132 aux = r[i]; \
2133 r[i] = r[l]; \ 2133 r[i] = r[l]; \
2134 r[l] = r[k]; \ 2134 r[l] = r[k]; \
2135 r[k] = r[j]; \ 2135 r[k] = r[j]; \
2136 r[j] = aux; 2136 r[j] = aux;
2137#define PERM22(r, i, j, k, l) \ 2137#define PERM22(r, i, j, k, l) \
2138 aux = r[i]; \ 2138 aux = r[i]; \
2139 r[i] = r[j]; \ 2139 r[i] = r[j]; \
2140 r[j] = aux; \ 2140 r[j] = aux; \
2141 aux = r[k]; \ 2141 aux = r[k]; \
2142 r[k] = r[l]; \ 2142 r[k] = r[l]; \
2143 r[l] = aux; 2143 r[l] = aux;
2144#define CO(a, b) \ 2144#define CO(a, b) \
2145 aux = (a & _cobits) + (b & _cobits); \ 2145 aux = (a & _cobits) + (b & _cobits); \
2146 auy = (aux + _ctwist_cw) >> 2U; \ 2146 auy = (aux + _ctwist_cw) >> 2U; \
2147 auz = (aux + auy) & _cobits2; \ 2147 auz = (aux + auy) & _cobits2; \
2148 a = (a & _pbits) | auz; 2148 a = (a & _pbits) | auz;
2149#define CO4(r, i, j, k, l) \ 2149#define CO4(r, i, j, k, l) \
2150 CO(r[i], _ctwist_cw) \ 2150 CO(r[i], _ctwist_cw) \
2151 CO(r[j], _ctwist_cw) \ 2151 CO(r[j], _ctwist_cw) \
2152 CO(r[k], _ctwist_ccw) \ 2152 CO(r[k], _ctwist_ccw) \
2153 CO(r[l], _ctwist_ccw) 2153 CO(r[l], _ctwist_ccw)
2154#define EO4(r, i, j, k, l) \ 2154#define EO4(r, i, j, k, l) \
2155 r[i] ^= _eobit; \ 2155 r[i] ^= _eobit; \
2156 r[j] ^= _eobit; \ 2156 r[j] ^= _eobit; \
2157 r[k] ^= _eobit; \ 2157 r[k] ^= _eobit; \
2158 r[l] ^= _eobit; 2158 r[l] ^= _eobit;
2159 2159
2160static cube_t _arraytocube(cube_array_t); 2160static cube_t _arraytocube(cube_array_t);
2161static void _cubetoarray(cube_t, cube_array_t *); 2161static void _cubetoarray(cube_t, cube_array_t *);
@@ -3728,3 +3728,60 @@ coord_eo(cube_t c)
3728{ 3728{
3729 return _coord_eo(c); 3729 return _coord_eo(c);
3730} 3730}
3731
3732/******************************************************************************
3733Section: solvers
3734
3735This is a continuation of the generic methods section. Here you can find the
3736implementation of all the solving algorithms.
3737******************************************************************************/
3738
3739typedef struct {
3740 cube_t cube;
3741 uint8_t d;
3742 int max;
3743 move_t *sol;
3744 int ns;
3745 int nm;
3746 move_t m[20];
3747} dfs_arg_t;
3748
3749int
3750solve_small_dfs(dfs_arg_t arg)
3751{
3752 if (arg.ns == arg.max)
3753 return 0;
3754
3755 if (issolved(arg.cube)) {
3756 if (arg.nm != arg.d)
3757 return 0;
3758 memcpy(&arg.sol[arg.d*arg.ns], arg.m, arg.d * sizeof(move_t));
3759 return 1;
3760 }
3761
3762 /* TODO: loop over moves and recur */
3763 return 0;
3764}
3765
3766int
3767solve_small(cube_t cube, uint8_t depth, int max, move_t *sol)
3768{
3769 dfs_arg_t arg;
3770
3771 if (!issolvable(cube) || depth > 20)
3772 return -1;
3773
3774 arg = (dfs_arg_t) {
3775 .cube = cube,
3776 .d = depth,
3777 .max = max,
3778 .sol = sol,
3779 .ns = 0,
3780 .nm = 0,
3781 .m = {0}
3782 };
3783
3784 return solve_small_dfs(arg);
3785
3786 return 0;
3787}
diff --git a/cube.h b/cube.h
index 5dc7410..c4effbe 100644
--- a/cube.h
+++ b/cube.h
@@ -33,3 +33,6 @@ cube_t compose(cube_t, cube_t);
33cube_t transform(cube_t, trans_t); 33cube_t transform(cube_t, trans_t);
34 34
35int16_t coord_eo(cube_t); 35int16_t coord_eo(cube_t);
36
37/* Solvers return -1 in case of error, the number of solutions otherwise */
38int solve_small(cube_t, uint8_t, int, move_t *);
diff --git a/test/test.sh b/test/test.sh
index a018401..68b87aa 100755
--- a/test/test.sh
+++ b/test/test.sh
@@ -2,7 +2,7 @@
2 2
3re="${TEST:-$@}" 3re="${TEST:-$@}"
4 4
5CC="cc -DDEBUG -std=c99 -pthread -pedantic -Wall -Wextra \ 5CC="cc -DDEBUG -std=c99 -pedantic -Wall -Wextra \
6 -Wno-unused-parameter -Wno-unused-function -g3 -D$CUBETYPE" 6 -Wno-unused-parameter -Wno-unused-function -g3 -D$CUBETYPE"
7if [ "$CUBETYPE" = "CUBE_AVX2" ]; then 7if [ "$CUBETYPE" = "CUBE_AVX2" ]; then
8 CC="$CC -mavx2" 8 CC="$CC -mavx2"

Generated with cgit - Back to sebastiano.tronto.net