{"id":31829477,"url":"https://github.com/hactarce/robodoan","last_synced_at":"2026-07-22T19:31:46.353Z","repository":{"id":314850071,"uuid":"1056717765","full_name":"HactarCE/robodoan","owner":"HactarCE","description":"Experimental blockbuilding-based search program for 3D and 4D Rubik's cubes","archived":false,"fork":false,"pushed_at":"2026-01-10T08:17:38.000Z","size":331,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-11T01:20:24.722Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/HactarCE.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-14T17:01:51.000Z","updated_at":"2025-09-24T04:39:11.000Z","dependencies_parsed_at":"2025-09-18T08:16:21.372Z","dependency_job_id":"2d6e5d25-11e1-44e2-8034-0aee8a5e530d","html_url":"https://github.com/HactarCE/robodoan","commit_stats":null,"previous_names":["hactarce/blockybuildy","hactarce/robodoan"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/HactarCE/robodoan","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HactarCE%2Frobodoan","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HactarCE%2Frobodoan/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HactarCE%2Frobodoan/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HactarCE%2Frobodoan/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/HactarCE","download_url":"https://codeload.github.com/HactarCE/robodoan/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HactarCE%2Frobodoan/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35775330,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"online","status_checked_at":"2026-07-22T02:00:06.236Z","response_time":124,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-10-11T20:24:03.001Z","updated_at":"2026-07-22T19:31:46.348Z","avatar_url":"https://github.com/HactarCE.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# robodoan\n\nExperimental blockbuilding-based search program for a [4D Rubik's cube](https://hypercubing.xyz/puzzles/3x3x3x3/)\n\nCurrently, this solver is only able to complete F2L. I plan on adding OLC and PLC solvers in the future.\n\n## Performance\n\nOn an M2 Max Macbook Pro, here is how the F2L solver performed on 10 random scrambles of a 4-dimensional 3×3×3×3 Rubik's cube.\n\nThese are solutions to F2L, not the whole puzzle.\n\nMove count is approximately STM except for very rare cases where two sequential moves use the same grip, in which case STM would be slightly lower than ETM.\n\nThere are two profiles: \"fast\" and \"short.\"\n\n### Fast profile\n\n```\n69 ETM in 8.97840925s\n70 ETM in 7.331832625s\n67 ETM in 7.840537417s\n68 ETM in 7.571879958s\n71 ETM in 9.166809125s\n68 ETM in 7.999356833s\n68 ETM in 7.219549042s\n70 ETM in 8.134437291s\n69 ETM in 8.066849666s\n68 ETM in 8.181445167s\n\nmean movecount: 68.8 ETM\nmean time: 8.049 seconds\n```\n\n### Short profile\n\n```\n66 ETM in 17.397143792s\n65 ETM in 17.069599208s\n67 ETM in 16.124495667s\n64 ETM in 16.10172325s\n66 ETM in 19.68221025s\n65 ETM in 18.024998208s\n67 ETM in 17.205043041s\n64 ETM in 15.573559166s\n66 ETM in 18.377754833s\n64 ETM in 13.521910042s\n\nmean movecount: 65.4 ETM\nmean time: 16.908 seconds\n```\n\n## Solving strategy\n\n### F2L\n\n#### Stages\n\nF2L is solved in 6 stages of blockbuilding:\n\n| Superstage         | Stage                               | Options | Additional pieces | Initial blocks | Target blocks |\n| ------------------ | ----------------------------------- | :-----: | :---------------: | :------------: | :-----------: |\n| Mid + left         | 2×2×2×2 (initial)                   |   16    |   2×2×2×2 = 16    |       16       |       1       |\n|                    | 2×2×3×2 (extend Y)                  |    4    |    2×2×1×2 = 8    |       9        |       1       |\n|                    | 2×3×3×2 (extend Z)                  |    3    |   2×1×3×2 = 12    |       13       |       1       |\n| Right (mid + back) | 1×2×2×2 (intial)                    |    8    |    2×2×2×1 = 8    |       9        |       2       |\n|                    | 1×2×3×2 (extend Y)                  |    2    |    2×2×1×1 = 4    |       6        |       2       |\n| End                | 3×3×3×2 (F2L)                       |    1    |    1×3×1×2 = 2    |       5        |       1       |\n\n- Note 1: The XYZW axes in this table roughly correspond to the XYZW axes of the [3-Block](https://hypercubing.xyz/methods/3x3x3x3/3block/) solving method.\n- Note 2: Each stage has multiple options due to the symmetry of the puzzle.\n\nThese stages are selected to avoid dead ends while blockbuilding, where the blocks that have already been built get in the way of forming new ones.\n\n#### Search algorithm\n\nTo find a solution to a stage, we use [iterative deepening depth-first search](https://en.wikipedia.org/wiki/Iterative_deepening_depth-first_search) up to a maximum depth (currently 4) to get to the target block count.\n\nIf we cannot reach the target block count, we increase the target block count by 1 and run the search again. If we are unable to find a solution that increases the block count at all, we increase the maximum depth and restart with the original target block count.\n\nAfter we find a partial solution that solves some number of blocks, we re-run the search starting from the partial solution with the original target block count and maximum depth.\n\n#### Pruning heuristics\n\nThe depth-first search rejects branches where the probability of forming enough blocks to meet the target is zero (using `Heuristic::Correct`) or very low (using `Heuristic::Fast`).\n\nIn practice, the faster heuristics lead to shorter solutions because even though some possibilities are discounted, we are able to search to a greater depth.\n\n##### Correct heuristics\n\n- **Combinatoric limit:** At most `2^remaining_moves * target_blocks` block pairings can be completed in the remaining moves.\n- **Grip-theoretic limit:**\n  - For each unordered pair of blocks `(b1, b2)`:\n    - Let `m` be the grip along which they will differ when solved.\n    - Let `m1 = b1.attitude * m` and `m2 = b2.attitude * m`.\n    - Iff `m1 = m2`, then the blocks can be paired in 1 move. Assume that each subsequent move also creates one pairing; add `remaining_moves` to `max_blocks_solvable`.\n    - Let the \"free grips\" be the intersection of the inactive grip sets of `b1` and `b2`.\n    - Iff there is a twist of one of the free grips that takes `m1` to `m2` (equivalently: whose inverse takes `m2` to `m1`) then the blocks can be paired in 2 moves. Assume that each subsequent move also creates one pairing; add `remaining_moves - 1` to `max_blocks_solvable`.\n    - Otherwise, the block can be paired in 3 moves. Assume that each subsequent move also creates one pairing; add `remaining_moves - 2` to `max_blocks_solvable`.\n  - At most `max_blocks_solvable` block pairings can be completed in the remaining moves.\n\n##### Fast heuristics\n\n- **Combinatoric limit:** At most `2^n` block pairings can be completed in `n` moves.\n- **Grip-theoretic limit:** Same as correct heuristic.\n\n#### Representation\n\nThe puzzle state is represented using a stack-allocated list of blocks with a maximum length determined by a compile-time constant.\n\nEach block is represented using 3 bytes:\n\n- 2 bytes for a layer mask (3 bits × 4 axes)\n- 1 byte for the attitude (ID from 0 to 191 inclusive)\n\nSince each block is represented using 3 bytes, we're able to fit a puzzle state containing **21** blocks (63 bytes) + length (1 byte) in exactly 64 bytes.\n\n### OLC + 2cPLC\n\nI haven't started work on this yet.\n\n### RKT PLC\n\nI haven't started work on this yet.\n\n## Representation\n\n## History\n\nThis program is named after Charles Doan, the 3^4 FMC (fewest-moves challenge) world record holder at the time this program was developed. As of September 2024, Charles Doan holds both the computer-assisted and non-computer-assisted FMC records for the 3×3×3×3 puzzle, and in fact his submission for non-computer-assisted is even shorter than the computer-assisted solution.\n\nI'm writing this program to give the computer-assisted category some much-needed love.\n\n## Optimizations (to-do)\n\n- [x] search multiple routes at once / meta search over block extensions\n- [x] don't move the same grip twice within one search\n- [x] indistinguishable attitudes\n- [x] prune based on optimistic block formation heuristics\n- [x] dynamically adjust goal based on depth\n- [ ] NISS\n- [ ] don't search duplicates (only consider pieces for current stage)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhactarce%2Frobodoan","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhactarce%2Frobodoan","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhactarce%2Frobodoan/lists"}