<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ sudoku - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ sudoku - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Tue, 28 Jul 2026 03:52:55 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/sudoku/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How I came back to an old problem and finally wrote a Sudoku-solving algorithm ]]>
                </title>
                <description>
                    <![CDATA[ By Ali Spittel This article will be part technical, part personal story, and part cultural critique. If you are just here for the code and explanation, jump to the The Initial Approach header! This story starts a few years ago in a college computer s... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/coming-back-to-old-problems-how-i-finally-wrote-a-sudoku-solving-algorithm-3b371e6c63bd/</link>
                <guid isPermaLink="false">66c34793d48c8b932b406b33</guid>
                
                    <category>
                        <![CDATA[ algorithms ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Computer Science ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                    <category>
                        <![CDATA[ sudoku ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 27 Jun 2018 13:45:12 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*ERYVo0W3nlPCEQGOHul6Rw.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ali Spittel</p>
<p>This article will be part technical, part personal story, and part cultural critique. If you are just here for the code and explanation, jump to the <strong>The Initial Approach</strong> header!</p>
<p>This story starts a few years ago in a college computer science classroom. I had an untraditional path to writing code — I randomly enrolled in a computer science class during my sophomore year of college, because I had an extra credit hour and I was curious what it was about. I thought we would learn how to use Microsoft Word and Excel — I genuinely had no idea what code was.</p>
<p>My high school definitely did not have any coding classes, they barely had functioning computers! I didn’t play video games or engage in activities that traditionally lead to kids learning how to code, either. So coding was brand new to me when I took that Python class in college.</p>
<p>As soon as I walked into the classroom, they had us type Python code into Idle, a text editor that comes with the Python language. They had printed the code and just had us type it in and run it — I was immediately hooked. Over the course of that class, I built a Tic Tac Toe script with a GUI to input pieces and a Flappy Bird clone. It honestly came pretty easily to me, and I had a ton of fun. I quickly decided to minor in computer science, and I just wanted to write more code.</p>
<p>The next semester, I enrolled in a Data Structures and Algorithms course which was next in the computer science sequence. The class was taught in C++, which, unbeknownst to me, was supposed to be learned over the summer before the class. It quickly became obvious that the professors were trying to use the class to filter out students — around 50% of the enrollees on day one made it through the semester. We even changed classrooms from a lecture hall to a break out room. My pride was the only thing keeping me in the class. I felt completely lost in pretty much every lesson. I spent many all-nighters working on projects and studying for the exams.</p>
<p>One problem in particular really got me — we were supposed to build a program in C++ that would solve any Sudoku problem. Again, I spent countless hours on the assignment trying to get the code working. By the time the project was due, my solution worked for some of the test cases but not all of them. I ended up getting a C+ on my assignment — one of my worst grades in all of college.</p>
<p>After that semester, I abandoned my idea of minoring in computer science, completely quit coding, and stuck to what I thought I was good at — writing and politics.</p>
<p>Of course, funny things happen in life and I obviously started coding again, but it took me a long time to feel like I was a competent programmer.</p>
<p>All that being said, a few years later into my programming journey, I decided to retry implementing the Sudoku solving algorithm to prove to myself that I could implement it now. The code isn’t perfect, but it will solve pretty much any Sudoku puzzle. Let’s walk through the algorithm and then the implementation.</p>
<h3 id="heading-sudoku-puzzles">Sudoku Puzzles</h3>
<p><img src="https://cdn-media-1.freecodecamp.org/images/NGyo6kOiNfPdOzeV5RfN8K4SUw0Jxw0LOraz" alt="Image" width="305" height="300" loading="lazy"></p>
<p>In case you haven’t played Sudoku puzzles before, they are number puzzles in which each row, column, and 3x3 square in the puzzle must have the numbers 1–9 represented exactly once. There are lots of approaches to solving these puzzles, many of which can be replicated by a computer instead of a person. Usually, when we solve them using a computer, we will use nested arrays to represent the Sudoku board like so:</p>
<pre><code>puzzle = [[<span class="hljs-number">5</span>, <span class="hljs-number">3</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">7</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>],          [<span class="hljs-number">6</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">9</span>, <span class="hljs-number">5</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>],          [<span class="hljs-number">0</span>, <span class="hljs-number">9</span>, <span class="hljs-number">8</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">6</span>, <span class="hljs-number">0</span>],          [<span class="hljs-number">8</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">6</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">3</span>],          [<span class="hljs-number">4</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">8</span>, <span class="hljs-number">0</span>, <span class="hljs-number">3</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">1</span>],          [<span class="hljs-number">7</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">6</span>],          [<span class="hljs-number">0</span>, <span class="hljs-number">6</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">2</span>, <span class="hljs-number">8</span>, <span class="hljs-number">0</span>],          [<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">4</span>, <span class="hljs-number">1</span>, <span class="hljs-number">9</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">5</span>],          [<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">8</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">7</span>, <span class="hljs-number">9</span>]]
</code></pre><p>When solved, the zeros will be filled in with actual numbers:</p>
<pre><code>solution = [[<span class="hljs-number">5</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">6</span>, <span class="hljs-number">7</span>, <span class="hljs-number">8</span>, <span class="hljs-number">9</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>],            [<span class="hljs-number">6</span>, <span class="hljs-number">7</span>, <span class="hljs-number">2</span>, <span class="hljs-number">1</span>, <span class="hljs-number">9</span>, <span class="hljs-number">5</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">8</span>],            [<span class="hljs-number">1</span>, <span class="hljs-number">9</span>, <span class="hljs-number">8</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">2</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>, <span class="hljs-number">7</span>],            [<span class="hljs-number">8</span>, <span class="hljs-number">5</span>, <span class="hljs-number">9</span>, <span class="hljs-number">7</span>, <span class="hljs-number">6</span>, <span class="hljs-number">1</span>, <span class="hljs-number">4</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>],            [<span class="hljs-number">4</span>, <span class="hljs-number">2</span>, <span class="hljs-number">6</span>, <span class="hljs-number">8</span>, <span class="hljs-number">5</span>, <span class="hljs-number">3</span>, <span class="hljs-number">7</span>, <span class="hljs-number">9</span>, <span class="hljs-number">1</span>],            [<span class="hljs-number">7</span>, <span class="hljs-number">1</span>, <span class="hljs-number">3</span>, <span class="hljs-number">9</span>, <span class="hljs-number">2</span>, <span class="hljs-number">4</span>, <span class="hljs-number">8</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>],            [<span class="hljs-number">9</span>, <span class="hljs-number">6</span>, <span class="hljs-number">1</span>, <span class="hljs-number">5</span>, <span class="hljs-number">3</span>, <span class="hljs-number">7</span>, <span class="hljs-number">2</span>, <span class="hljs-number">8</span>, <span class="hljs-number">4</span>],            [<span class="hljs-number">2</span>, <span class="hljs-number">8</span>, <span class="hljs-number">7</span>, <span class="hljs-number">4</span>, <span class="hljs-number">1</span>, <span class="hljs-number">9</span>, <span class="hljs-number">6</span>, <span class="hljs-number">3</span>, <span class="hljs-number">5</span>],            [<span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">2</span>, <span class="hljs-number">8</span>, <span class="hljs-number">6</span>, <span class="hljs-number">1</span>, <span class="hljs-number">7</span>, <span class="hljs-number">9</span>]]
</code></pre><h3 id="heading-the-initial-approach">The Initial Approach</h3>
<p>Because I didn’t feel like writing a full test suite with different puzzles, I used the challenges on <a target="_blank" href="https://www.codewars.com/">CodeWars</a> to test myself. The first problem I tried was <a target="_blank" href="https://www.codewars.com/kata/sudoku-solver">this</a> — where all of the puzzles were “easy” Sudokus that could be solved without a more complex algorithm.</p>
<p>I decided to try and solve the Sudokus in the way I personally do — where I would find the possible numbers for a space, keep track of them, and if there is only one possible number, plug it into that spot. Since these were easier Sudokus, this approach worked fine for this Kata, and I passed.</p>
<p>Here’s my (uncleaned) code!</p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SudokuSolver</span>:    <span class="hljs-title">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-title">self</span>, <span class="hljs-title">puzzle</span>):        <span class="hljs-title">self</span>.<span class="hljs-title">puzzle</span> </span>= puzzle        self.box_size = <span class="hljs-number">3</span>
</code></pre><pre><code>    def find_possibilities(self, row_number, column_number):        possibilities = set(range(<span class="hljs-number">1</span>, <span class="hljs-number">10</span>))        row = self.get_row(row_number)        column = self.get_column(column_number)        box = self.get_box(row_number, column_number)        <span class="hljs-keyword">for</span> item <span class="hljs-keyword">in</span> row + column + box:            <span class="hljs-keyword">if</span> not isinstance(item, list)and item <span class="hljs-keyword">in</span> possibilities:                possibilities.remove(item)        <span class="hljs-keyword">return</span> possibilities
</code></pre><pre><code>    def get_row(self, row_number):        <span class="hljs-keyword">return</span> self.puzzle[row_number]
</code></pre><pre><code>    def get_column(self, column_number):        <span class="hljs-keyword">return</span> [row[column_number] <span class="hljs-keyword">for</span> row <span class="hljs-keyword">in</span> self.puzzle]
</code></pre><pre><code>    def get_box(self, row_number, column_number):        start_y = column_number <span class="hljs-comment">// 3 * 3        start_x = row_number // 3 * 3        if start_x &lt; 0:            start_x = 0        if start_y &lt; 0:            start_y = 0        box = []        for i in range(start_x, self.box_size + start_x):            box.extend(self.puzzle[i][start_y:start_y+self.box_size])        return box</span>
</code></pre><pre><code>    def find_spot(self):        unsolved = True        <span class="hljs-keyword">while</span> unsolved:            unsolved = False            <span class="hljs-keyword">for</span> row_number, row <span class="hljs-keyword">in</span> enumerate(self.puzzle):                <span class="hljs-keyword">for</span> column_number, item <span class="hljs-keyword">in</span> enumerate(row):                    <span class="hljs-keyword">if</span> item == <span class="hljs-number">0</span>:                        unsolved = True                        possibilities = self.find_possibilities(                            row_number, column_number)                        <span class="hljs-keyword">if</span> len(possibilities) == <span class="hljs-number">1</span>:                            self.puzzle[row_number][column_number] = list(possibilities)[                                <span class="hljs-number">0</span>]        <span class="hljs-keyword">return</span> self.puzzle
</code></pre><pre><code>def sudoku(puzzle):    sudoku = SudokuSolver(puzzle)    <span class="hljs-keyword">return</span> sudoku.find_spot()
</code></pre><p>Of course, I also wanted to solve more difficult Sudoku puzzles, so I decided to implement a more complex algorithm in order to solve those puzzles.</p>
<h3 id="heading-the-algorithm">The Algorithm</h3>
<p>One algorithm to solve Sudoku puzzles is the backtracking algorithm. Essentially, you keep trying numbers in empty spots until there aren’t any that are possible, then you backtrack and try different numbers in the previous slots.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/XHVFcJhCX-mRMxvSBvuWMQuEw1eipOCxKWBS" alt="Image" width="297" height="297" loading="lazy">
<em>Shoutout to Wikipedia for the awesome visualization!</em></p>
<p>The first thing that I did was continue my “easy” Sudoku solver’s approach of finding the possible values for each square based on which values were already in that square’s row, column, and box. I stored all of these values in a list so that I could quickly refer to them while backtracking or finding which value to use in that square.</p>
<p>Next, I needed to implement the forward moving and backtracking of putting items in each space. I put markers on each non-given space (so the ones that were zeros when the game started) so that those spaces would be included in the backtracking and given spots wouldn’t be. I then iterated through those un-solved spots. I would put the first item of the possible value list in that spot and then move to the next unsolved spot. I would then put the first possible value of that spot in its place. If it conflicted with the value of the previous slot, I would then move to the second item in the list of possible values and then move to the next slot.</p>
<p>That process would continue until there was no possible move for a given spot — that is, the end of the possible value list was reached and none of the values worked in that row, column, or box. Then, the backtracking algorithm kicked in.</p>
<p>Within the backtracking implementation, the code would move back to the last spot that was filled in and move to the next possible value and then start moving forward again. If the last of the possible values was reached at that spot as well, the backtracking algorithm would keep moving backwards until there was a spot that could be incremented.</p>
<p>Once the end of the puzzle was reached with correct values in each square, the puzzle was solved!</p>
<h3 id="heading-my-approach">My Approach</h3>
<p>I like object oriented approaches, so I have two different classes in my solution: one for the cell and one for the Sudoku board. My very imperfect code looks like this:</p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Cell</span>:    """<span class="hljs-title">One</span> <span class="hljs-title">individual</span> <span class="hljs-title">cell</span> <span class="hljs-title">on</span> <span class="hljs-title">the</span> <span class="hljs-title">Sudoku</span> <span class="hljs-title">board</span>"""</span>
</code></pre><pre><code>    def __init__(self, column_number, row_number, number, game):        # Whether or not to include the cell <span class="hljs-keyword">in</span> the backtracking        self.solved = True <span class="hljs-keyword">if</span> number &gt; <span class="hljs-number">0</span> <span class="hljs-keyword">else</span> False        self.number = number  # the current value <span class="hljs-keyword">of</span> the cell        # Which numbers the cell could potentially be        self.possibilities = set(range(<span class="hljs-number">1</span>, <span class="hljs-number">10</span>)) <span class="hljs-keyword">if</span> not self.solved <span class="hljs-keyword">else</span> []        self.row = row_number  # the index <span class="hljs-keyword">of</span> the row the cell is <span class="hljs-keyword">in</span>        self.column = column_number  # the index <span class="hljs-keyword">of</span> the column the cell is <span class="hljs-keyword">in</span>        self.current_index = <span class="hljs-number">0</span>  # the index <span class="hljs-keyword">of</span> the current possibility        self.game = game  # the sudoku game the cell belongs to        <span class="hljs-keyword">if</span> not self.solved:  # runs the possibility checker            self.find_possibilities()
</code></pre><pre><code>    def check_area(self, area):        <span class="hljs-string">""</span><span class="hljs-string">"Checks to see if the cell's current value is a valid sudoku move"</span><span class="hljs-string">""</span>        values = [item <span class="hljs-keyword">for</span> item <span class="hljs-keyword">in</span> area <span class="hljs-keyword">if</span> item != <span class="hljs-number">0</span>]        <span class="hljs-keyword">return</span> len(values) == len(set(values))
</code></pre><pre><code>    def set_number(self):        <span class="hljs-string">""</span><span class="hljs-string">"changes the number attribute and also changes the cell's value in the larger puzzle"</span><span class="hljs-string">""</span>        <span class="hljs-keyword">if</span> not self.solved:            self.number = self.possibilities[self.current_index]            self.game.puzzle[self.row][self.column] = self.possibilities[self.current_index]
</code></pre><pre><code>    def handle_one_possibility(self):        <span class="hljs-string">""</span><span class="hljs-string">"If the cell only has one possibility, set the cell to that value and mark it as solved"</span><span class="hljs-string">""</span>        <span class="hljs-keyword">if</span> len(self.possibilities) == <span class="hljs-number">1</span>:            self.solved = True            self.set_number()
</code></pre><pre><code>    def find_possibilities(self):        <span class="hljs-string">""</span><span class="hljs-string">"filter the possible values for the cell"</span><span class="hljs-string">""</span>        <span class="hljs-keyword">for</span> item <span class="hljs-keyword">in</span> self.game.get_row(self.row) + self.game.get_column(self.column) + self.game.get_box(self.row, self.column):            <span class="hljs-keyword">if</span> not isinstance(item, list) and item <span class="hljs-keyword">in</span> self.possibilities:                self.possibilities.remove(item)        self.possibilities = list(self.possibilities)        self.handle_one_possibility()
</code></pre><pre><code>    def is_valid(self):        <span class="hljs-string">""</span><span class="hljs-string">"checks to see if the current number is valid in its row, column, and box"</span><span class="hljs-string">""</span>        <span class="hljs-keyword">for</span> unit <span class="hljs-keyword">in</span> [self.game.get_row(self.row), self.game.get_column(self.column), self.game.get_box(self.row, self.column)]:            <span class="hljs-keyword">if</span> not self.check_area(unit):                <span class="hljs-keyword">return</span> False        <span class="hljs-keyword">return</span> True
</code></pre><pre><code>    def increment_value(self):        <span class="hljs-string">""</span><span class="hljs-string">"move number to the next possibility while the current number is invalid and there are possibilities left"</span><span class="hljs-string">""</span>        <span class="hljs-keyword">while</span> not self.is_valid() and self.current_index &lt; len(self.possibilities) - <span class="hljs-number">1</span>:            self.current_index += <span class="hljs-number">1</span>            self.set_number()
</code></pre><pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SudokuSolver</span>:    """<span class="hljs-title">contains</span> <span class="hljs-title">logic</span> <span class="hljs-title">for</span> <span class="hljs-title">solving</span> <span class="hljs-title">a</span> <span class="hljs-title">sudoku</span> <span class="hljs-title">puzzle</span> -- <span class="hljs-title">even</span> <span class="hljs-title">very</span> <span class="hljs-title">difficult</span> <span class="hljs-title">ones</span> <span class="hljs-title">using</span> <span class="hljs-title">a</span> <span class="hljs-title">backtracking</span> <span class="hljs-title">algorithm</span>"""</span>
</code></pre><pre><code>    def __init__(self, puzzle):        self.puzzle = puzzle  # the <span class="hljs-number">2</span>d list <span class="hljs-keyword">of</span> spots on the board        self.solve_puzzle = []  # <span class="hljs-number">1</span>d list <span class="hljs-keyword">of</span> the Cell objects        # the size <span class="hljs-keyword">of</span> the boxes within the puzzle -- <span class="hljs-number">3</span> <span class="hljs-keyword">for</span> a typical puzzle        self.box_size = int(len(self.puzzle) ** <span class="hljs-number">.5</span>)        self.backtrack_coord = <span class="hljs-number">0</span>  # what index the backtracking is currently at
</code></pre><pre><code>    def get_row(self, row_number):        <span class="hljs-string">""</span><span class="hljs-string">"Get the full row from the puzzle based on the row index"</span><span class="hljs-string">""</span>        <span class="hljs-keyword">return</span> self.puzzle[row_number]
</code></pre><pre><code>    def get_column(self, column_number):        <span class="hljs-string">""</span><span class="hljs-string">"Get the full column"</span><span class="hljs-string">""</span>        <span class="hljs-keyword">return</span> [row[column_number] <span class="hljs-keyword">for</span> row <span class="hljs-keyword">in</span> self.puzzle]
</code></pre><pre><code>    def find_box_start(self, coordinate):        <span class="hljs-string">""</span><span class="hljs-string">"Get the start coordinate for the small sudoku box"</span><span class="hljs-string">""</span>        <span class="hljs-keyword">return</span> coordinate <span class="hljs-comment">// self.box_size * self.box_size</span>
</code></pre><pre><code>    def get_box_coordinates(self, row_number, column_number):        <span class="hljs-string">""</span><span class="hljs-string">"Get the numbers of the small sudoku box"</span><span class="hljs-string">""</span>        <span class="hljs-keyword">return</span> self.find_box_start(column_number), self.find_box_start(row_number)
</code></pre><pre><code>    def get_box(self, row_number, column_number):        <span class="hljs-string">""</span><span class="hljs-string">"Get the small sudoku box for an x and y coordinate"</span><span class="hljs-string">""</span>        start_y, start_x = self.get_box_coordinates(row_number, column_number)        box = []        <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(start_x, self.box_size + start_x):            box.extend(self.puzzle[i][start_y:start_y+self.box_size])        <span class="hljs-keyword">return</span> box
</code></pre><pre><code>    def initialize_board(self):        <span class="hljs-string">""</span><span class="hljs-string">"create the Cells for each item in the puzzle and get its possibilities"</span><span class="hljs-string">""</span>        <span class="hljs-keyword">for</span> row_number, row <span class="hljs-keyword">in</span> enumerate(self.puzzle):            <span class="hljs-keyword">for</span> column_number, item <span class="hljs-keyword">in</span> enumerate(row):                self.solve_puzzle.append(                    Cell(column_number, row_number, item, self))
</code></pre><pre><code>    def move_forward(self):        <span class="hljs-string">""</span><span class="hljs-string">"Move forwards to the next cell"</span><span class="hljs-string">""</span>        <span class="hljs-keyword">while</span> self.backtrack_coord &lt; len(self.solve_puzzle) - <span class="hljs-number">1</span> and self.solve_puzzle[self.backtrack_coord].solved:            self.backtrack_coord += <span class="hljs-number">1</span>
</code></pre><pre><code>    def backtrack(self):        <span class="hljs-string">""</span><span class="hljs-string">"Move forwards to the next cell"</span><span class="hljs-string">""</span>        self.backtrack_coord -= <span class="hljs-number">1</span>        <span class="hljs-keyword">while</span> self.solve_puzzle[self.backtrack_coord].solved:            self.backtrack_coord -= <span class="hljs-number">1</span>
</code></pre><pre><code>    def set_cell(self):        <span class="hljs-string">""</span><span class="hljs-string">"Set the current cell to work on"</span><span class="hljs-string">""</span>        cell = self.solve_puzzle[self.backtrack_coord]        cell.set_number()        <span class="hljs-keyword">return</span> cell
</code></pre><pre><code>    def reset_cell(self, cell):        <span class="hljs-string">""</span><span class="hljs-string">"set a cell back to zero"</span><span class="hljs-string">""</span>        cell.current_index = <span class="hljs-number">0</span>        cell.number = <span class="hljs-number">0</span>        self.puzzle[cell.row][cell.column] = <span class="hljs-number">0</span>
</code></pre><pre><code>    def decrement_cell(self, cell):        <span class="hljs-string">""</span><span class="hljs-string">"runs the backtracking algorithm"</span><span class="hljs-string">""</span>        <span class="hljs-keyword">while</span> cell.current_index == len(cell.possibilities) - <span class="hljs-number">1</span>:            self.reset_cell(cell)            self.backtrack()            cell = self.solve_puzzle[self.backtrack_coord]        cell.current_index += <span class="hljs-number">1</span>
</code></pre><pre><code>    def change_cells(self, cell):        <span class="hljs-string">""</span><span class="hljs-string">"move forwards or backwards based on the validity of a cell"</span><span class="hljs-string">""</span>        <span class="hljs-keyword">if</span> cell.is_valid():            self.backtrack_coord += <span class="hljs-number">1</span>        <span class="hljs-keyword">else</span>:            self.decrement_cell(cell)
</code></pre><pre><code>    def solve(self):        <span class="hljs-string">""</span><span class="hljs-string">"run the other functions necessary for solving the sudoku puzzle"</span><span class="hljs-string">""</span>        self.move_forward()        cell = self.set_cell()        cell.increment_value()        self.change_cells(cell)
</code></pre><pre><code>    def run_solve(self):        <span class="hljs-string">""</span><span class="hljs-string">"runs the solver until we are at the end of the puzzle"</span><span class="hljs-string">""</span>        <span class="hljs-keyword">while</span> self.backtrack_coord &lt;= len(self.solve_puzzle) - <span class="hljs-number">1</span>:            self.solve()
</code></pre><pre><code>def solve(puzzle):    solver = SudokuSolver(puzzle)    solver.initialize_board()    solver.run_solve()    <span class="hljs-keyword">return</span> solver.puzzle
</code></pre><p><a target="_blank" href="https://www.codewars.com/kata/hard-sudoku-solver">Hard Sudoku Solver</a></p>
<h3 id="heading-my-takeaways">My Takeaways</h3>
<p>Sometimes it just takes time and practice. The Sudoku solver I spent countless college hours on took me less than an hour a few years later.</p>
<p>I will say that computer science programs don’t tend to start in a way that allows people who didn’t write code earlier in life to participate. In a few years, computer science education policies may change. But for now, this eliminates people who grew up in small towns, who weren’t interested in coding growing up, or who went to weaker high schools.</p>
<p>In part, this definitely contributes to the success of coding bootcamps which start with the fundamentals and teach the less conceptual web development skills rather than heavy algorithms.</p>
<p>I can now write the Sudoku solving algorithm, but I don’t think it’s a necessary skill for developers to have — I still became a successful software engineer shortly after that time when I couldn’t implement the Sudoku solver.</p>
<p>I do think that some computer science fundamentals can be very helpful, even for new developers. For example, the concepts behind Big-O notation can be really helpful for deciding between approaches. That being said, most data structures and algorithms aren’t used on a day to day basis, so why are they the basis for interviews and computer science classes instead of the more important things used every day?</p>
<p>I’m happy to see my own personal growth in coding; however, I can’t wait for a day when developers aren’t jumping through imaginary hoops to prove themselves, and when learning environments are much more constructive.</p>
<p>_If you liked this article, please <a target="_blank" href="https://tinyletter.com/ali_writes_code">subscribe</a> to my weekly newsletter where you’ll receive my favorite links from the week and my latest articles._</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
