diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2023-05-01 16:33:51 +0200 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2023-05-01 16:33:51 +0200 |
| commit | bf44088d4373a9520e860152c56a958332819c4b (patch) | |
| tree | ea35c847a1d82aa715e1fc1c76e4a24462255051 /README.md | |
| parent | 1a5bfe9b08707b0aef748d7921a419ba4a046fba (diff) | |
| download | nissy-bf44088d4373a9520e860152c56a958332819c4b.tar.gz nissy-bf44088d4373a9520e860152c56a958332819c4b.zip | |
Split nissy in other repos, see README.md
Diffstat (limited to 'README.md')
| -rw-r--r-- | README.md | 130 |
1 files changed, 38 insertions, 92 deletions
| @@ -1,104 +1,50 @@ | |||
| 1 | # WARNING | 1 | # Where is nissy? |
| 2 | 2 | ||
| 3 | I am currently rewriting some important parts of the code | 3 | In April 2023 I have decided to split nissy in 2 separate projects: an |
| 4 | and the git version is not working. | 4 | optimal solver and an FMC assistant. These two projects are not usable |
| 5 | You can download the last stable version from the | 5 | yet, so in the meantime I will keep a third branch where I update the |
| 6 | [download page](https://nissy.tronto.net/download). | 6 | classic version of nissy with bugfixes and minor improvements. |
| 7 | 7 | ||
| 8 | # Nissy | 8 | You can find these three branches at the following pages (also |
| 9 | on github, links below are to my personal git instance): | ||
| 9 | 10 | ||
| 10 | A Rubik's cube solver and FMC assistant. | 11 | * [nissy-classic](https://git.tronto.net/nissy-classic): The stable |
| 11 | For optimal HTM solving Nissy uses techniques from Herbert Kociemba's | 12 | branch, will receive bugfixes and minor improvements but no big |
| 12 | [Cube Explorer](http://kociemba.org/cube.htm) and Tomas Rokicki's | 13 | change. Will eventually be replaced by the other two versions. |
| 13 | [nxopt](https://github.com/rokicki/cube20src/blob/master/nxopt.md). | 14 | * [nissy-fmc](https://git.tronto.net/nissy-fmc): This will focus on |
| 14 | With 4 cores at 2.5GHz and using about 3Gb of RAM, Nissy can find an | 15 | features useful for practicing FMC, for example finding EOs and |
| 15 | optimal solution in about a minute on average. | 16 | DRs (if you do not know what this means, there is a good chance |
| 17 | you don't care). I plan to make a graphical interface for it and | ||
| 18 | make it more usable. It will not be able to find an optimal | ||
| 19 | solution. *Not working at the moment.* | ||
| 20 | * [nissy-nx](https://git.tronto.net/nissy-nx): An optimal solver. | ||
| 21 | For now this is just my playground for implementing complex | ||
| 22 | optimizations, following the ideas of Tomas's Rokicki's | ||
| 23 | [nxopt](https://github.com/rokicki/cube20src/blob/master/nxopt.md). | ||
| 24 | Eventually it will become faster than nissy-classic at optimal | ||
| 25 | solving, but without all other features. *Not working at the moment.* | ||
| 16 | 26 | ||
| 17 | Nissy can also solve many different substeps of Thistlethwaite's algorithm | 27 | # I am a user of nissy, what should I do? |
| 18 | (DR/HTR), and can use NISS (Normal-Inverse Scramble Switch). | ||
| 19 | It can be useful to analyze your DR solves (and more, once I implement more features). | ||
| 20 | 28 | ||
| 21 | You can get Nissy from [nissy.tronto.net](https://nissy.tronto.net). | 29 | If you are happy with using nissy as it is, you can keep using it. |
| 22 | The download links and installation instructions can be found on the | ||
| 23 | [download page](https://nissy.tronto.net/download). | ||
| 24 | 30 | ||
| 25 | ## Structure of the code | 31 | When nissy-fmc and nissy-classic are ready, you can chek them out too. |
| 26 | 32 | ||
| 27 | You can find all the source code in the `src` folder. | 33 | # But I liked that nissy can do both optimal solving! Why did you split it? |
| 28 | I strived to keep it legible but I did not write many comments (barely any at all). | ||
| 29 | I'll try to explain here the main parts of the program. | ||
| 30 | 34 | ||
| 31 | ### Cube, moves and transformations | 35 | Then I encourage you to keep using nissy-classic :-) |
| 32 | 36 | ||
| 33 | There are many ways to represent a cube. In Nissy I use two: | 37 | See |
| 38 | [my blog post](https://sebastiano.tronto.net/blog/2023-04-10-the-big-rewrite/) | ||
| 39 | for some reasons behind this change. | ||
| 34 | 40 | ||
| 35 | * An array representation `CubeArray`: 3 arrays representing the permutation | 41 | # I just want to look at the code, where should I go? |
| 36 | of corners, edges and centers and 2 arrays for the orientation of corners and edges. | ||
| 37 | * An 11-integers representation `Cube`: 3 integers for edge orientation (with respect | ||
| 38 | to the three axes), 3 for corner orientation, and so on. Edge permutation is a bit | ||
| 39 | complicated because encoding 12 factorial as a single number is too large for some | ||
| 40 | practical reasons, so I use 3 integers for that. | ||
| 41 | 42 | ||
| 42 | Moves are easy to apply on the array form, but they are slow. So `moves.c` | 43 | If you want to check out the git repository of the version you are |
| 43 | contains the instructions to create all the transition tables necessary | 44 | running, you probably want nissy-classic. The newer nissy-fmc will |
| 44 | to get the next position for the cube with just 11 lookup operations | 45 | eventually be nicer and easier to read, containing more or less |
| 45 | (one for each of the 11 integers in the second representation). | 46 | the same functionality (except for optimal solving). |
| 46 | These transition tables are saved in the `mtables` file in the | ||
| 47 | `tables` folder in binary format. | ||
| 48 | |||
| 49 | The 11 integers are obviously redundant, but keeping all of them makes it easy | ||
| 50 | to apply transformations. A transformation is a rotation of the whole cube, possibly | ||
| 51 | combined with a mirror operation. Applying a transformation to a cube (say obtained | ||
| 52 | by applying a scramble to the solved cube) means applying the transformation to a | ||
| 53 | solved cube, then the scramble and then the inverse of the transformation | ||
| 54 | (i.e. conjugating by it). | ||
| 55 | |||
| 56 | ### Coordinates and pruning tables | ||
| 57 | |||
| 58 | A *coordinate* consists of a function that takes a cube (in the 11-integer | ||
| 59 | representation) and return an (unsigned, 64-bit) integer. They are used | ||
| 60 | to "linearize" a cube and build pruning tables, which speed up significantly the | ||
| 61 | solving process. To be able to access the pruning table quickly, the function | ||
| 62 | needs to be very fast (e.g. it should not convert between the two representations | ||
| 63 | of the cube if not necessary). | ||
| 64 | |||
| 65 | Some coordinates make use of symmetries to reduce the size of the resulting | ||
| 66 | pruning table. Unfortunately this complicates the code a lot, but it is a huge | ||
| 67 | advantage: it reduces by a factor of about 16 the pruning table size. | ||
| 68 | |||
| 69 | Pruning tables are related to a specific step, a moveset and a coordinate. They | ||
| 70 | contain one value from 0 to 15 (4 bits) for each possible value for the coordinate, | ||
| 71 | which is less or equal than the minimum number of moves required to solve the | ||
| 72 | given step with the given moveset for a cube which has the given coordinate. For example, | ||
| 73 | say the coordinate `neo` gives the number of non-oriented edges (say with respect to | ||
| 74 | F/B). Then the possible values for the coordinate are 0,2,4,...,12. An associated | ||
| 75 | pruning table to solving EO with HTM moveset and this coordinate would have values 0 | ||
| 76 | (for `neo=0`), 3 (for `neo=2`), 1 (for `neo=4`)... | ||
| 77 | |||
| 78 | The values for most pruning tables are memorized modulo 16, so they only occupy | ||
| 79 | 4 bits per entry, and values larger than 15 are saved as 15. This is good enough | ||
| 80 | for most applications. | ||
| 81 | Some large tables are memorized in compact form using only 2 bits, similarly | ||
| 82 | to what [nxopt](https://github.com/rokicki/cube20src/blob/master/nxopt.md) does: | ||
| 83 | a base value `b` is picked and a value of `n` is saved as `MIN(3,MAX(0,n-b))`. | ||
| 84 | When a value of `v=1,2,3` is read it is simply returned as `v+b`, while if | ||
| 85 | `0` is a successive lookup to a fallback table is performed. The base value `b` | ||
| 86 | is picked to maximize the sum frequency of the values `1,2,3`. | ||
| 87 | |||
| 88 | In order to generate the pruning tables, it is necessary to be able to move | ||
| 89 | a transform a coordinate; it is possible to do so without passing through a | ||
| 90 | complete cube representations, in a way similar to what Cube Explorer does. | ||
| 91 | This used to be different before version 2.1 (June 2022). | ||
| 92 | |||
| 93 | More documentation on this and on the different types of coordinates (base | ||
| 94 | vs composed) is work in progress. | ||
| 95 | |||
| 96 | ### Solving | ||
| 97 | |||
| 98 | Solving is implemented as a generic function that takes both a step and | ||
| 99 | a (scrambled) cube as input, as well as some extra parameters that say e.g. | ||
| 100 | how many solution one wants. A step consists, among other things, of | ||
| 101 | an estimator function that, given a cube, gives a lower bound for the number | ||
| 102 | of moves needed to complete the step. Many of these estimators simply | ||
| 103 | look up the corresponding values in the appropriate pruning table. | ||
| 104 | 47 | ||
| 48 | If you want to follow my progress on an advanced optimal Rubik's | ||
| 49 | cube solver, you can check out nissy-nx - just remember that it | ||
| 50 | does not work yet! | ||
