{"id":23802702,"url":"https://github.com/aritrakar/sudoku-csp","last_synced_at":"2026-04-16T04:02:04.910Z","repository":{"id":221855074,"uuid":"755286827","full_name":"aritrakar/sudoku-csp","owner":"aritrakar","description":"🎲Sudoku solver with different algorithms in C++ and Python.","archived":false,"fork":false,"pushed_at":"2024-06-04T01:31:32.000Z","size":143,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-11-11T04:31:46.700Z","etag":null,"topics":["cpp","python","sudoku-solver"],"latest_commit_sha":null,"homepage":"","language":"Jupyter Notebook","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aritrakar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2024-02-09T20:13:34.000Z","updated_at":"2024-06-04T01:33:25.000Z","dependencies_parsed_at":"2024-02-20T16:41:29.171Z","dependency_job_id":"8408ff36-baf1-49e7-bfca-99bb2854c595","html_url":"https://github.com/aritrakar/sudoku-csp","commit_stats":null,"previous_names":["aritrakar/sudoku-csp"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/aritrakar/sudoku-csp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aritrakar%2Fsudoku-csp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aritrakar%2Fsudoku-csp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aritrakar%2Fsudoku-csp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aritrakar%2Fsudoku-csp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aritrakar","download_url":"https://codeload.github.com/aritrakar/sudoku-csp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aritrakar%2Fsudoku-csp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31870516,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-15T15:24:51.572Z","status":"online","status_checked_at":"2026-04-16T02:00:06.042Z","response_time":69,"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":["cpp","python","sudoku-solver"],"created_at":"2025-01-01T22:27:28.391Z","updated_at":"2026-04-16T04:02:04.884Z","avatar_url":"https://github.com/aritrakar.png","language":"Jupyter Notebook","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Sudoku Solver\n\n## Introduction\n\nThis project presents a Sudoku solver implemented in Python, modeled as a Constraint Satisfaction Problem (CSP). Leveraging Python's rich ecosystem for computational problems, this solver demonstrates efficient puzzle solving through backtracking, forward checking, and different heuristics.\n\n## Setup and Execution\n\n### Prerequisites\n\n- C++17 OR\n- Python 3.8+\n\n### Running the Solver\n\n```bash\n# Clone the repository\ngit clone https://\ncd sudoku-csp\n\n# For the C++ solution\n# Compile\ng++ -std=c++17 -03 sudoku_solver.cpp -o sudoku\n./sudoku 2 # Mode 2. See below for details.\n```\n\n## Implementation Details\n\nThere are 2 modes and 3 approaches to solve the Sudoku puzzle. The mode and approach can be specified as command-line arguments. The approahces are:\n\n- Backtracking (1): `b`\n- Backtracking + Forward Checking (2): `btfc`\n- Backtracking + Forward Checking + Heuristics (3): `btfch`\n\nThe modes are:\n\n- Mode 1: Solve a single puzzle with a specified approach.\n\n  ```bash\n      ./sudoku 1 \u003cpuzzle\u003e \u003capproach\u003e\n  ```\n\n- Mode 2: Solve a single puzzle with all approaches and compare the results. By default, it'll search in the `etc` directory.\n  ```bash\n      ./sudoku 2 \u003cpuzzle\u003e\n  ```\n\n### Modeling Sudoku as a CSP\n\nBefore diving into each technique, let's first model sudoku as a constraint satisfaction problem (CSP) as follows:\n\n- **Variables (V):** Each cell in the grid is a variable. For a standard 9x9 Sudoku, there are 81 variables. $$V = \\{v_1, v_2, \\ldots, v_{81}\\} \\quad \\text{or} \\quad V = \\{v_{ij}: i, j \\in [1, 9]\\}$$\n- **Domain (D):** The domain of each variable is the set of possible values that can be assigned to it. For a standard 9x9 Sudoku, the domain of each variable is {1, 2, 3, 4, 5, 6, 7, 8, 9}.\n- **Constraints (C):** The constraints are the rules of Sudoku. No two cells in the same row, column, or 3x3 subgrid can contain the same value.\n\n### Backtracking for sudoku\n\nBacktracking is a brute-force search algorithm that systematically searches for a solution to a problem. It explores all possible paths to find a solution. If a path leads to a dead end, the algorithm backtracks and tries a different path.\n\nBacktracking is not efficient for solving Sudoku, but it is a good starting point to understand the problem and the solution space.\n\nNote: There is a major difference between a standard backtracking approach and the approach used in my solution. A standard backtracking solution would fill cells sequentially, starting from the top-left corner and in the domain order (i.e. from 1 to 9). However, my solution uses **randomizes** the order for both of these. Certain puzzles can be solved by backtracking using the traditional approach due to the ordering of the cells and the domain. However, randomizing the order of the cells and the domain makes the problem more challenging.\n\n\u003c!-- The backtracking function can be found [here](). --\u003e\n\n### Backtracking + Forward Checking for sudoku\n\nSince backtracking is not efficient for solving Sudoku, we can use forward checking to improve the efficiency.\n\nForward checking is a simple and efficient _constraint propagation_ technique that eliminates values from the domain of variables that have been assigned a value. It is a way to keep track of remaining legal values for unassigned variables. Whenever a variable is assigned a value, the forward checking algorithm removes that value from the domain of all the variables connected to the variable that was just assigned. This helps in reducing the search space by eliminating values that cannot be part of the solution and checking for failure early.\n\n\u003c!-- The backtracking + forward checking function can be found [here](). --\u003e\n\n### Backtracking + Forward Checking + Heuristics for sudoku\n\nLastly, we can use heuristics to further improve the efficiency of the solver. Heuristics are rules or methods that help in choosing the most promising path. I use the **most constrained variable**, **most constraining variable**, and **least constraining value** heuristics.\n\n- First, the **most constrained variable** heuristic selects the variable that is involved in the largest number of constraints on the remaining variables. This is the variable that is most likely to cause a failure, and it is therefore a good variable to assign a value to early.\n\n- Second, in case of ties in the **most constrained variable** heuristic, the most constraining variable heuristic is used. This heuristic selects the variable that is involved in the largest number of constraints on the remaining variables.\n\n- Lastly, the **least constraining value** heuristic is used to select the value to assign to the variable. This heuristic selects the value that rules out the fewest choices for the neighboring variables in the constraint graph.\n\n## Experiiment results\n\nThe solver was tested on 4 different puzzles difficulties (easy, medium, hard, and evil) for 10 iterations each. Statistics about the time taken to solve each puzzle and the number of nodes expanded in the search tree were recorded. The results are shown below for each approach.\n\nNote:\n\n- The results are not deterministic due to the randomization of the order of cells and domain.\n- The results are presented as the mean ± standard deviation.\n- Initially, I tried running with the Python solution and with a higher number of iterations, but it was taking too long. So, I switched to C++. The C++ solution is much faster than the Python solution.\n\n### Time taken to solve the puzzle in milliseconds\n\n| Difficulty | btfch            | btfc             | b                 |\n| ---------- | ---------------- | ---------------- | ----------------- |\n| Easy       | 1.8 ± 2.13542    | 7.5 ± 20.5098    | 124.6 ± 106.516   |\n| Medium     | 6.7 ± 5.56866    | 9.5 ± 9.46837    | 2417.8 ± 4476.78  |\n| Hard       | 192.9 ± 147.634  | 403.5 ± 389.354  | 77080.3 ± 99295.3 |\n| Evil       | 2068.6 ± 1253.96 | 5229.3 ± 6034.34 | 142869 ± 284326   |\n\n### Number of nodes expanded in the search tree\n\n| Difficulty | btfch             | btfc                      | b                         |\n| ---------- | ----------------- | ------------------------- | ------------------------- |\n| Easy       | 815.1 ± 695.224   | 4565.9 ± 11716.6          | 388242 ± 327441           |\n| Medium     | 2236.2 ± 1701.42  | 5327.6 ± 4810.94          | 7.7055e+06 ± 1.42765e+07  |\n| Hard       | 61352.3 ± 46844.4 | 237808 ± 230248           | 2.44967e+08 ± 3.16293e+08 |\n| Evil       | 645198 ± 389603   | 2.98515e+06 ± 3.47978e+06 | 4.47678e+08 ± 8.88712e+08 |\n\n## Conclusion\n\nThe results show that the `btfch` approach is the most efficient, as expected, in terms of time taken to solve the puzzle and the number of nodes expanded in the search tree. The `btfc` approach is also efficient, but it is not as efficient as the `btfch` approach. The standard backtracking approach is not efficient for solving Sudoku puzzles (at least with randomized order of cells and domain), as expected.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faritrakar%2Fsudoku-csp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faritrakar%2Fsudoku-csp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faritrakar%2Fsudoku-csp/lists"}