diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2023-11-06 22:59:21 +0100 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2023-11-06 22:59:21 +0100 |
| commit | 7b48583d629d33971e9f1d5e7aa4ca7f11d8a032 (patch) | |
| tree | 2c60880a6e754bf5ce813a89c2d7255bb6d0af6a | |
| parent | d1aaa9264089fa64a98eecef09aa4a5d9773e345 (diff) | |
| download | nissy-core-7b48583d629d33971e9f1d5e7aa4ca7f11d8a032.tar.gz nissy-core-7b48583d629d33971e9f1d5e7aa4ca7f11d8a032.zip | |
Started working on solve
| -rw-r--r-- | README.md | 12 | ||||
| -rwxr-xr-x | benchmark/bench.sh | 2 | ||||
| -rw-r--r-- | cube.c | 107 | ||||
| -rw-r--r-- | cube.h | 3 | ||||
| -rwxr-xr-x | test/test.sh | 2 |
5 files changed, 97 insertions, 29 deletions
| @@ -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 | ||
| 3 | CC="cc -std=c99 -pthread -O3 -D$CUBETYPE" | 3 | CC="cc -std=c99 -O3 -D$CUBETYPE" |
| 4 | if [ "$CUBETYPE" = "CUBE_AVX2" ]; then | 4 | if [ "$CUBETYPE" = "CUBE_AVX2" ]; then |
| 5 | CC="$CC -mavx2" | 5 | CC="$CC -mavx2" |
| 6 | fi | 6 | fi |
| @@ -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 | ||
| 2160 | static cube_t _arraytocube(cube_array_t); | 2160 | static cube_t _arraytocube(cube_array_t); |
| 2161 | static void _cubetoarray(cube_t, cube_array_t *); | 2161 | static 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 | /****************************************************************************** | ||
| 3733 | Section: solvers | ||
| 3734 | |||
| 3735 | This is a continuation of the generic methods section. Here you can find the | ||
| 3736 | implementation of all the solving algorithms. | ||
| 3737 | ******************************************************************************/ | ||
| 3738 | |||
| 3739 | typedef 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 | |||
| 3749 | int | ||
| 3750 | solve_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 | |||
| 3766 | int | ||
| 3767 | solve_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 | } | ||
| @@ -33,3 +33,6 @@ cube_t compose(cube_t, cube_t); | |||
| 33 | cube_t transform(cube_t, trans_t); | 33 | cube_t transform(cube_t, trans_t); |
| 34 | 34 | ||
| 35 | int16_t coord_eo(cube_t); | 35 | int16_t coord_eo(cube_t); |
| 36 | |||
| 37 | /* Solvers return -1 in case of error, the number of solutions otherwise */ | ||
| 38 | int 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 | ||
| 3 | re="${TEST:-$@}" | 3 | re="${TEST:-$@}" |
| 4 | 4 | ||
| 5 | CC="cc -DDEBUG -std=c99 -pthread -pedantic -Wall -Wextra \ | 5 | CC="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" |
| 7 | if [ "$CUBETYPE" = "CUBE_AVX2" ]; then | 7 | if [ "$CUBETYPE" = "CUBE_AVX2" ]; then |
| 8 | CC="$CC -mavx2" | 8 | CC="$CC -mavx2" |
