diff options
Diffstat (limited to '')
| -rw-r--r-- | README.md | 215 |
1 files changed, 199 insertions, 16 deletions
| @@ -1,46 +1,229 @@ | |||
| 1 | # Prototype for a new optimal solver | 1 | # H48: prototype for a new optimal solver and nissy backend |
| 2 | 2 | ||
| 3 | Work in progress. Everything is in a state of flux and can change without | 3 | **Warning**: this library is work in progress, breaking changes can |
| 4 | notice. | 4 | happen without notice. |
| 5 | 5 | ||
| 6 | ## Building and running tests | 6 | H48 is an experimental Rubik's cube solver. The main goal is experimenting |
| 7 | with various optimal solving methods and pruning tables, with | ||
| 8 | [nxopt](https://github.com/rokicki/cube20src/blob/master/nxopt.md) and | ||
| 9 | [vcube](https://github.com/Voltara/vcube) as inspiration and benchmark | ||
| 10 | reference. | ||
| 7 | 11 | ||
| 8 | First run | 12 | In the future this project may evolve as a new "back-end" for the classic |
| 13 | [nissy](https://github.com/sebastianotronto/nissy-classic). | ||
| 14 | |||
| 15 | ## Building | ||
| 16 | |||
| 17 | First run the configuration script to detect the system | ||
| 18 | configuration. This is going to select a C compiler and | ||
| 19 | architecture-specific optimizations. | ||
| 9 | 20 | ||
| 10 | ``` | 21 | ``` |
| 11 | $ ./configure.sh | 22 | $ ./configure.sh |
| 12 | ``` | 23 | ``` |
| 13 | 24 | ||
| 14 | or `TYPE=AVX2 ./configure.sh` if you want to use AVX2 instructions. | 25 | These settings can be overridden, for example: |
| 26 | |||
| 27 | ``` | ||
| 28 | $ CC=clang ./configure.sh # Force use of clang instead of default cc | ||
| 29 | ``` | ||
| 30 | |||
| 31 | The support for ARM-specific optimizations (NEON instructions) is | ||
| 32 | incomplete. To compile correctly on these processors (e.g. Mac M1/M2/M3) | ||
| 33 | you need to manually disable optimizations: | ||
| 34 | |||
| 35 | ``` | ||
| 36 | $ TYPE="" ./configure.sh # Can be combined with CC=... | ||
| 37 | ``` | ||
| 38 | |||
| 39 | Once the configuration is done, you can build with make | ||
| 15 | 40 | ||
| 16 | Then | 41 | ``` |
| 42 | $ make | ||
| 43 | ``` | ||
| 44 | |||
| 45 | ## Running tests | ||
| 46 | |||
| 47 | This project includes a suite of "unit" test. They can be run with: | ||
| 17 | 48 | ||
| 18 | ``` | 49 | ``` |
| 19 | $ make test | 50 | $ make test |
| 20 | ``` | 51 | ``` |
| 21 | 52 | ||
| 22 | to run the tests. You can also run only the tests that match a chosen | 53 | To run only a subset of the tests, set the `TEST` variable to a regular |
| 23 | regex, for example: | 54 | expression that matches only the name of the tests you want to run: |
| 24 | 55 | ||
| 25 | ``` | 56 | ``` |
| 26 | $ TEST=coord make test | 57 | $ TEST=coord make test |
| 27 | ``` | 58 | ``` |
| 28 | 59 | ||
| 29 | Due to ongoing changes, benchmarks are currently broken. | 60 | Each subfolder of the test folder contains a test. A test can consist |
| 61 | of multiple test cases (.in files). Running a test means compiling and | ||
| 62 | running the corresponding test against each test case. When a test case | ||
| 63 | is run, the .in file is read a the output of the program is compared | ||
| 64 | to the corresponding .out filei using diff(1). If the two differ, the | ||
| 65 | difference is printed out and no other test is run. | ||
| 66 | |||
| 67 | The results of the last test case run is saved in test/last.out (standard | ||
| 68 | output, the results compared with the .out files) and test/last.err | ||
| 69 | (standard error). | ||
| 70 | |||
| 71 | Tests are always run in "debug mode": this means that optimizations are | ||
| 72 | disabled and some extra logging is enabled. | ||
| 73 | |||
| 74 | See the test folder and test/test.sh for details. | ||
| 75 | |||
| 76 | ## Running "tools" | ||
| 77 | |||
| 78 | In the tools folder there are some small programs that test various | ||
| 79 | functionality of the H48 library. They work similarly to test, but they | ||
| 80 | are not run in debug mode. | ||
| 81 | |||
| 82 | To run a tool you must select it with the environment variable `TOOL`. | ||
| 83 | For example the command: | ||
| 84 | |||
| 85 | ``` | ||
| 86 | TOOL=stats make tool | ||
| 87 | ``` | ||
| 88 | |||
| 89 | Will run the stats_tables_h48 tool. Like for tests, the value of the | ||
| 90 | `TOOL` variable can be any regular expression matching the name of the | ||
| 91 | tool. Unlike tests, one and only one tool will be selected for each run. | ||
| 92 | |||
| 93 | Each tool run is automatically timed, so these tools can be used as | ||
| 94 | benchmark. The output as well as the time of the run are saved to a | ||
| 95 | file in the tools/results folder. | ||
| 30 | 96 | ||
| 31 | ## Solving | 97 | ## Running commands manually |
| 32 | 98 | ||
| 33 | Notes for myself while this is work in progress | 99 | This project also includes a rudimentary shell that can be used to run |
| 100 | commands manually. To build the shell use: | ||
| 34 | 101 | ||
| 35 | ``` | 102 | ``` |
| 36 | $ make shell | 103 | $ make shell |
| 37 | $ ./run frommoves -moves (scramble) | ||
| 38 | ``` | 104 | ``` |
| 39 | 105 | ||
| 40 | copy the result, then | 106 | This will create an executable called `run`. Then you can for example |
| 107 | get a cube from a sequence of moves: | ||
| 108 | |||
| 109 | ``` | ||
| 110 | $ ./run frommoves -moves "R' U' F" | ||
| 111 | JLQWSVUH=ZLCUABGIVTKH | ||
| 112 | ``` | ||
| 113 | |||
| 114 | Or you can get a random cube | ||
| 115 | |||
| 116 | ``` | ||
| 117 | $ ./run randomcube | ||
| 118 | WDSQREVX=VBKYDUCJXWAb | ||
| 119 | ``` | ||
| 120 | |||
| 121 | If you don't like this format, you can convert it: | ||
| 122 | |||
| 123 | ``` | ||
| 124 | $ ./run convert -fin B32 -fout H48 -cubestr "WDSQREVX=VBKYDUCJXWAb" | ||
| 125 | UL1 UB0 BL0 FR1 DF0 UR1 DB0 FL0 DR1 DL1 UF0 BR1 DFR2 DBR0 DFL2 UFR2 UBL2 UFL0 UBR2 DBL2 | ||
| 126 | ``` | ||
| 127 | |||
| 128 | To solve a cube (experimental) you can use: | ||
| 41 | 129 | ||
| 42 | ``` | 130 | ``` |
| 43 | $ ./run solve -solver "H48" -options "2;20" -n 1 -M 10 -cube (paste here) | 131 | $ ./run solve -solver "h48" -options "0;20" -n 1 -M 4 -cube "JLQWSVUH=ZLCUABGIVTKH" |
| 132 | Found 0 solutions, searching at depth 0 | ||
| 133 | Found 0 solutions, searching at depth 1 | ||
| 134 | Found 0 solutions, searching at depth 2 | ||
| 135 | Found 0 solutions, searching at depth 3 | ||
| 136 | Solution found: F' U R | ||
| 137 | F' U R | ||
| 44 | ``` | 138 | ``` |
| 45 | 139 | ||
| 46 | Options can be changed from `2;20` to `n;20` for larger tables. | 140 | For a full list of available command, use `run help`. |
| 141 | |||
| 142 | ## Cube formats | ||
| 143 | |||
| 144 | The cube is represented as a string in one of the following formats, | ||
| 145 | all explained below: | ||
| 146 | |||
| 147 | * H48 | ||
| 148 | * LST | ||
| 149 | * B32 (the default) | ||
| 150 | |||
| 151 | In all of the formats, the permutation of the center pieces is not | ||
| 152 | stored. This means that the cube is assumed to be in a fixed orientation. | ||
| 153 | |||
| 154 | More formats will become available in the future. | ||
| 155 | |||
| 156 | ### Cube format: H48 | ||
| 157 | |||
| 158 | In the H48 format, each edge is represented by two letters denoting the | ||
| 159 | sides it belongs to and one number denoting its orientation (0 oriented, 1 | ||
| 160 | mis-oriented). Similarly, each corner is represented by three letters and | ||
| 161 | a number (0 oriented, 1 twisted clockwise, 2 twisted counter-clockwise). | ||
| 162 | |||
| 163 | The solved cube looks like this: | ||
| 164 | |||
| 165 | ``` | ||
| 166 | UF0 UB0 DB0 DF0 UR0 UL0 DL0 DR0 FR0 FL0 BL0 BR0 UFR0 UBL0 DFL0 DBR0 UFL0 UBR0 DFR0 DBL0 | ||
| 167 | ``` | ||
| 168 | |||
| 169 | The cube after the move F looks like this: | ||
| 170 | |||
| 171 | ``` | ||
| 172 | FL1 UB0 DB0 FR1 UR0 UL0 DL0 DR0 UF1 DF1 BL0 BR0 UFL1 UBL0 DFR1 DBR0 DFL2 UBR0 UFR2 DBL0 | ||
| 173 | ``` | ||
| 174 | |||
| 175 | Whitespace (including newlines) between pieces is ignored when reading the | ||
| 176 | cube. A single whitespace character is added between pieces when writing. | ||
| 177 | |||
| 178 | You can find more examples of this format in the utils/cubes folder. | ||
| 179 | |||
| 180 | ## Cube format: LST | ||
| 181 | |||
| 182 | In the LST format, a cube is represented by a comma-separated list of | ||
| 183 | integers. Each piece is represented by an (unsigned) 8-bit integer. The 4 | ||
| 184 | least-significant bits determine which piece it is, the other 4 determine | ||
| 185 | the orientation. | ||
| 186 | |||
| 187 | Edges are numbered as follows (see also constants.h): | ||
| 188 | |||
| 189 | UF=0 UB=1 DB=2 DF=3 UR=4 UL=5 DL=6 DR=7 FR=8 FL=9 BL=10 BR=11 | ||
| 190 | |||
| 191 | Corners are numbered as follows: | ||
| 192 | |||
| 193 | UFR=0 UBL=1 DFL=2 DBR=3 UFL=4 UBR=5 DFR=6 DBL=7 | ||
| 194 | |||
| 195 | The orientation of the edges is with respect to F/B, the orientation of | ||
| 196 | corners is with respect to U/D. | ||
| 197 | |||
| 198 | In this format, the solved cube looks like this: | ||
| 199 | |||
| 200 | ``` | ||
| 201 | 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 | ||
| 202 | ``` | ||
| 203 | |||
| 204 | The cube after the move F looks like this: | ||
| 205 | |||
| 206 | ``` | ||
| 207 | 36, 1, 38, 3, 66, 5, 64, 7, 25, 1, 2, 24, 4, 5, 6, 7, 16, 19, 10, 11 | ||
| 208 | ``` | ||
| 209 | |||
| 210 | ### Cube format: B32 | ||
| 211 | |||
| 212 | This format is a "base 32" encoding of the cube. It is not meant to be | ||
| 213 | human-readable, but it is compact while still being plain text. Each | ||
| 214 | piece, including the orientation value, is encoded as a number from 0 | ||
| 215 | to 31, and this number is then converted to an uppercase letter (0-26) | ||
| 216 | or to a lowercase letter (27-31). Edges and corners are separated by a | ||
| 217 | single = character. | ||
| 218 | |||
| 219 | In this format, the solved cube looks like this: | ||
| 220 | |||
| 221 | ``` | ||
| 222 | ABCDEFGH=ABCDEFGHIJKL | ||
| 223 | ``` | ||
| 224 | |||
| 225 | The cube after the move F looks like this: | ||
| 226 | |||
| 227 | ``` | ||
| 228 | MBODSFQH=ZBCYEFGHQTKL | ||
| 229 | ``` | ||
