Sudoku in Different Programming Languages
Writing Sudoku in different programming languages is a fast way to feel each language's personality, because the algorithm stays fixed while the style around it changes completely.
One algorithm, many dialects
The core of almost every Sudoku solver is the same: find an empty cell, try each legal digit, recurse, and undo on failure. That backtracking skeleton does not change when you switch languages. What changes is how each language expresses the grid, the recursion, and the candidate set. Studying Sudoku in different programming languages is therefore a clean experiment, because you hold the algorithm constant and observe only the idioms. It is one of the most instructive small projects a developer can repeat across a career.
Python: readable and expressive
Python tends to produce the shortest, most readable version. A grid is a list of lists, recursion is natural, and sets make candidate computation almost read like the rules themselves: the allowed digits are the full set minus those already in the row, column, and box. The tradeoff is speed, since interpreted Python is slower than compiled languages, though a bitmask version narrows the gap. For learning and for clearly communicating the algorithm, Python is hard to beat.
JavaScript: runs everywhere
JavaScript's great advantage is reach: the same solver runs in any browser and on the server through a runtime like Node. Arrays and simple functions carry the algorithm, and modern engines optimize hot loops well. The main things to watch are recursion depth on pathological inputs and keeping heavy work off the main thread so the interface stays responsive. A web-based Sudoku tool is often written in JavaScript for exactly this portability.
Java and C-sharp: verbose but fast
Statically typed and JIT-compiled, Java and C-sharp sit in a comfortable middle. The code is more ceremonious, with explicit types and int arrays, but that structure pays off on larger projects, and the just-in-time compiler makes the solver quick once it warms up. Both languages support the same bit tricks as C, so a candidate mask stored in an int behaves identically. Expect more lines than Python but noticeably better throughput.
C, C-plus-plus, and Rust: close to the metal
For raw speed, the systems languages lead. Fixed-size arrays, tight loops, and 9-bit candidate masks let the solver fly, and there is no interpreter overhead. C gives you full control and full responsibility for memory. Rust adds compile-time safety guarantees while keeping the performance, which makes it a favorite for people who want a fast solver without the footguns. These are the languages you reach for when you intend to solve millions of grids.
Functional takes: Haskell and friends
Functional languages express the search declaratively. In Haskell, the list monad models nondeterministic choice so beautifully that the solver can read almost like a description of trying every candidate and keeping the ones that work. Immutability means you never mutate the board; you produce new grids. The result can be strikingly elegant, and it reframes backtracking as composition rather than as an explicit loop with undo.
What stays the same everywhere
- Represent the grid as a 9 by 9 structure of digits and blanks.
- Find an empty cell, ideally the one with the fewest candidates.
- Try each legal digit in turn and recurse.
- Undo the move when a branch fails, and report success when the grid is full.
Seeing Sudoku in different programming languages side by side reveals that the hard part was never the syntax; it was the idea. Once the backtracking pattern is in your head, you can carry it anywhere. The solver behind shapedoku.com uses these same principles, and because each glowing shape simply stands for a digit from 1 to 9, the logic ports as easily between shapes and numbers as it does between languages. Try the shape version yourself at app.shapedoku.com.
Ready to put it into practice?
Play Shapedoku free in your browser. No download, no login, just colorful shape Sudoku.
Play the Web App