{"id":44947771,"url":"https://github.com/phoenixsmaug/str8ts","last_synced_at":"2026-02-18T10:01:04.464Z","repository":{"id":294877744,"uuid":"970000048","full_name":"PhoenixSmaug/Str8ts","owner":"PhoenixSmaug","description":"A collection of combinatorial solvers for the Sudoku variant Str8ts.","archived":false,"fork":false,"pushed_at":"2025-05-22T13:28:25.000Z","size":36,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-11-16T02:33:35.683Z","etag":null,"topics":["combinatorial-search","sat-solving","str8ts"],"latest_commit_sha":null,"homepage":"","language":"Julia","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PhoenixSmaug.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2025-04-21T09:41:06.000Z","updated_at":"2025-05-22T13:28:28.000Z","dependencies_parsed_at":"2025-05-22T14:51:16.176Z","dependency_job_id":"bc03ce2c-16c1-4670-8bee-63727c817844","html_url":"https://github.com/PhoenixSmaug/Str8ts","commit_stats":null,"previous_names":["phoenixsmaug/str8ts"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/PhoenixSmaug/Str8ts","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PhoenixSmaug%2FStr8ts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PhoenixSmaug%2FStr8ts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PhoenixSmaug%2FStr8ts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PhoenixSmaug%2FStr8ts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PhoenixSmaug","download_url":"https://codeload.github.com/PhoenixSmaug/Str8ts/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PhoenixSmaug%2FStr8ts/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29575343,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-18T08:38:15.585Z","status":"ssl_error","status_checked_at":"2026-02-18T08:38:14.917Z","response_time":162,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["combinatorial-search","sat-solving","str8ts"],"created_at":"2026-02-18T10:00:52.696Z","updated_at":"2026-02-18T10:01:04.444Z","avatar_url":"https://github.com/PhoenixSmaug.png","language":"Julia","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Solving Str8ts puzzles with a SAT solver\n\n## Legal Disclaimer\n\nThis project is an independent solver for the puzzle game **Str8ts**, developed purely for educational and recreational purposes. **Str8ts** is a registered trademark of **Syndicated Puzzles Inc**. All rights to the name, branding, and associated intellectual property belong to them. The author of this project is **not affiliated, associated, authorized, endorsed by, or in any way officially connected with Syndicated Puzzles Inc.**, or any of its subsidiaries or affiliates.\n\nThe only Str8ts puzzle included in this repository is ''Str8ts9x9 Very Hard PUZ.png'' by AndrewCStuart from [the German Wikipedia page](https://de.wikipedia.org/wiki/Str8ts#/media/Datei:Str8ts9x9_Very_Hard_PUZ.png), and is licensed under the [Creative Commons Attribution-ShareAlike 3.0 Unported License (CC BY-SA 3.0)](https://creativecommons.org/licenses/by-sa/3.0/). This puzzle is used **solely as an example** to demonstrate the solver algorithm and is **not** licensed under the MIT License like the rest of the code in this repository. For full licensing details, refer to the `LICENSE` file.\n\n## Introduction\n\n### Rules\n\nA Str8ts puzzle consists of a 9x9 board that must be filled according to the following rules:\n\n1. Each white cell must be filled with a number between 1 and 9, so that each number appears at most once in each row and column.\n2. Each compartment (a connected vertical or horizontal group of white cells) must contain a consecutive sequence of numbers in any order. For example, $4,2,5,3$ would be a valid solution for a compartment with four cells, while $4,2,5,1$ would not be.\n3. Black cells do not have to be filled with a number. If a black cell contains a number at the beginning, this number cannot appear in a white cell in the row or column.\n\nTo summarize, Str8ts is a Sudoku modification where some cells are black and do not need to be filled and the block constraints are replaced by compartment constraints. The [German Wikipedia page](https://de.wikipedia.org/wiki/Str8ts) gives two example puzzles and their solution, which can illustrate the initially somewhat confusing rules of Str8ts.\n\n### NP-Completeness\n\nStr8ts generalized on an $n \\times n$ board is an NP-complete problem by the following argument: For a given solution, we can verify that the three rules hold in polynomial time, so the problem is in NP. And the special case that a Str8ts puzzle contains no black cells is equivalent to a simple Latin square, where we fill each cell so that each number appears exactly once in each row and column. As proven in [“The complexity of completing partial Latin squares”](https://doi.org/10.1016/0166-218X(84)90075-1), solving a Latin square is an NP-complete problem and thus also the Str8ts problem.\n\n### SAT Encoding\n\nIn the standard encoding of a Sudoku puzzle into SAT we have variables $x_{i, j, n}$, which are true if and only if the cell in the $i$-th row and $j$-th column contains the number $n$. Copying this approach, the rules 1 and 3 can then encoded using the following constraints:\n\n(A) Each white cell has at least one number, an empty black cell does not have a number\n```math\n\\forall i \\in \\{1, \\ldots, 9\\} : \\forall j \\in \\{1, \\ldots, 9\\} : \\begin{cases} \\bigvee_{n = 1}^9 x_{i, j, n} \u0026 \\text{if cell } (i, j) \\text{ is white}, \\\\ \\bigwedge_{n = 1}^9 \\overline{x}_{i, j, n} \u0026 \\text{if cell } (i, j) \\text{ is black and empty.} \\end{cases} \n```\n\n(B) Each number appears at most once per column/row\n```math\n\\forall n \\in \\{1, \\ldots, 9\\} : \\forall i \\in \\{1, \\ldots, 9\\} : \\bigwedge_{j, j^{\\prime} \\in \\{1, \\ldots, 9\\}, j \\neq j^{\\prime}} \\overline{x}_{i, j, n} \\lor \\overline{x}_{i, j^{\\prime}, n}\n```\n```math\n\\forall n \\in \\{1, \\ldots, 9\\} : \\forall j \\in \\{1, \\ldots, 9\\} : \\bigwedge_{i, i^{\\prime} \\in \\{1, \\ldots, 9\\}, i \\neq i^{\\prime}} \\overline{x}_{i, j, n} \\lor \\overline{x}_{i^{\\prime}, j, n}\n```\n\nThe big challenge is the encoding of rule 2, as the requirement for consecutive numbers in arbitrary order is very hard to translate into pure boolean logic. We will side-step this problem by introducing the alternative rule 2', proving the equivalence to rule 2 and then encode the former into SAT.\n\n2'. If a compartment of length $t$ contains the number $n$, it contains no numbers $\\geq n + t$ and $\\leq n - t$.\n\nProof that rule 2 implies 2': If a compartment contains $t$ consecutive numbers, all difference between any two entries is at most $t - 1$. Thus it can't contain $n$ and another entry $\\geq n + t$ or $\\leq n - t$ and so rule 2' is satisfied.\n\nProof that rule 2' implies 2: We choose $n$ as the smallest number contained in the compartment, meaning all other entries are larger than $n$. Since they the entries follow rule 2', we know that the remaining numbers $\\{m_1, m_2, \\ldots, m_{t - 1}\\}$ all fulfill $n \u003c m_i \u003c n + t$. But there are only $t - 1$ integers $\u003e n$ and $\u003c n + t$, and by rule 1 all entries are pairwise distinct. This means that the remaining numbers must be exactly those integers and so form a consecutive sequence with $n$, fulfilling rule 2.\n\nNow we encode rule 2':\n\n(C) Compartment constraints are satisfied\n\nFor all compartments $C_m = \\\\{(i_{m_1}, j_{m_1}), \\ldots, (i_{m_t}, j_{m_t})\\\\}$ we add:\n```math\n\\forall (i, j), (i^{\\prime}, j^{\\prime}) \\in C_m \\text{ with } (i, j) \\neq (i^{\\prime}, j^{\\prime}): \\forall n \\in \\{1, \\ldots, 9\\} : \\bigwedge_{n^\\prime = n + t}^{9} \\overline{x}_{i, j, n} \\lor \\overline{x}_{i^{\\prime}, j^{\\prime}, n^{\\prime}}\n```\n```math\n\\forall (i, j), (i^{\\prime}, j^{\\prime}) \\in C_m \\text{ with } (i, j) \\neq (i^{\\prime}, j^{\\prime}): \\forall n \\in \\{1, \\ldots, 9\\} : \\bigwedge_{n^\\prime = 1}^{n - t} \\overline{x}_{i, j, n} \\lor \\overline{x}_{i^{\\prime}, j^{\\prime}, n^{\\prime}}\n```\n\nThen finally we ensure that the already placed numbers are accepted:\n\n(D) Respect hints\n```math\n\\forall i \\in \\{1, \\ldots, 9\\} : \\forall j \\in \\{1, \\ldots, 9\\} : \\begin{cases} x_{i, j, n} \u0026 \\text{if cell } (i, j) \\text{ starts with number } n, \\\\  \u0026 \\text{otherwise.} \\end{cases} \n```\n\n## Code\n\nStr8ts puzzles are inputed as a 81 character string, mapping the 81 cells starting from the top left corner to the bottom right corner. A white cell with number $n$ is simply denoted as \"n\", if it is empty we denote it with \".\". Black cells with number $n$ are denoted as the $n$-th letter in the alphabet, so $4$ would be encoded as \"d\" and empty black cells are denoted with \"#\". In `main.jl` we give the string representation for a diabolic Str8ts puzzle as an example.\n\nThe user can use `solveSAT!(s::Str8ts)`, to encode the given Str8ts puzzle into pure SAT like described in the previous section and solve it with the [PicoSAT](https://fmv.jku.at/picosat/) SAT solver. Alternatively we provide `solveSimple!(s::Str8ts)`, which is a 70 line backtracking solver again using rule 2'. While in general the more complicated SAT approach is far faster, both algorithms solve even diabolic Str8ts in a few millseconds as demonstrated in `main.jl`.\n\n(c) Mia Müßig\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphoenixsmaug%2Fstr8ts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphoenixsmaug%2Fstr8ts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphoenixsmaug%2Fstr8ts/lists"}