<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Pinku Deb Nath</title>
    <description>The latest articles on DEV Community by Pinku Deb Nath (@prantoran).</description>
    <link>https://dev.to/prantoran</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F37593%2F36c18e9e-1a88-472e-a89e-5fe915fbb1af.jpeg</url>
      <title>DEV Community: Pinku Deb Nath</title>
      <link>https://dev.to/prantoran</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/prantoran"/>
    <language>en</language>
    <item>
      <title>Fixing libdc1394.so.22: cannot open shared object file (ㅠ﹏ㅠ)</title>
      <dc:creator>Pinku Deb Nath</dc:creator>
      <pubDate>Thu, 10 Oct 2024 05:13:55 +0000</pubDate>
      <link>https://dev.to/prantoran/fixing-libdc1394so22-cannot-open-shared-object-file--272k</link>
      <guid>https://dev.to/prantoran/fixing-libdc1394so22-cannot-open-shared-object-file--272k</guid>
      <description>&lt;p&gt;libdc1394.so.22 is a library used for camera access in libraries such as OpenCV and is superseded by libdc1394-dev in Ubuntu 24.04. One quick fix is to install libdc1394-dev and create a symbolic link to libdc1394.so.22.&lt;/p&gt;

&lt;h1&gt;
  
  
  1. Install libdc1394-dev
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;libdc1394-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  2. Locate lib installation path
&lt;/h1&gt;

&lt;p&gt;I am no expert and keep forgetting the basics. So I searched for the install path using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ldconfig &lt;span class="nt"&gt;-p&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;libdc1394
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We might get an output like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    libdc1394.so.25 &lt;span class="o"&gt;(&lt;/span&gt;libc6,x86-64&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; /lib/x86_64-linux-gnu/libdc1394.so.25
    libdc1394.so &lt;span class="o"&gt;(&lt;/span&gt;libc6,x86-64&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; /lib/x86_64-linux-gnu/libdc1394.so
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  3. Create symlink
&lt;/h1&gt;

&lt;p&gt;Usually the linker in Ubuntu searches for .so files in /usr/lib first. So I created a symbolic link in that location:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo ln&lt;/span&gt; &lt;span class="nt"&gt;-sf&lt;/span&gt; /lib/x86_64-linux-gnu/libdc1394.so /usr/lib/libdc1394.so.22
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And voila! The app runs (ಥ◡ಥ)&lt;/p&gt;

</description>
      <category>opencv</category>
      <category>cmake</category>
      <category>ubuntu</category>
      <category>libdc1394</category>
    </item>
    <item>
      <title>Solving Sudoku</title>
      <dc:creator>Pinku Deb Nath</dc:creator>
      <pubDate>Mon, 30 Oct 2023 01:23:36 +0000</pubDate>
      <link>https://dev.to/prantoran/solving-sudoku-142o</link>
      <guid>https://dev.to/prantoran/solving-sudoku-142o</guid>
      <description>&lt;p&gt;While trying to solve LeetCode's &lt;cite&gt;&lt;a href="https://leetcode.com/problems/sudoku-solver" rel="noopener noreferrer"&gt;Sudoku Solver&lt;/a&gt;&lt;/cite&gt;, I stumbled upon a cool general case of similar Exact Cover problems that can be solved (among other ways) with Dr. Donald Knuth's Dancing Links algorithm. In this blog, we will go through first understanding the problem and the algorithm, and finally implement everything in code. This blog is a summary of all the resources I used in the process, i.e. &lt;cite&gt;&lt;a href="https://www.ocf.berkeley.edu/~jchu/publicportal/sudoku/sudoku.paper.html" rel="noopener noreferrer"&gt;ocf.berkeley.edu/~jchu/.../sudoku.paper&lt;/a&gt;&lt;/cite&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exact Cover Problem
&lt;/h2&gt;

&lt;p&gt;Definition: Given a matrix of 1's and 0's, exact cover is a set of rows in which exactly one 1 will appear for each column. &lt;/p&gt;

&lt;p&gt;For example, in Knuth's Dancing Links paper figure 3,&lt;/p&gt;

&lt;blockquote&gt;&lt;code&gt;
0 0 1 0 1 1 0&lt;br&gt;
1 0 0 1 0 0 1&lt;br&gt;
0 1 1 0 0 1 0&lt;br&gt;
1 0 0 1 0 0 0&lt;br&gt;
0 1 0 0 0 0 1&lt;br&gt;
0 0 0 1 1 0 1
&lt;/code&gt;&lt;/blockquote&gt;

&lt;p&gt;Rows 1, 4, 5 (1 indexed) represent the exact cover. &lt;/p&gt;

&lt;p&gt;If we think of the columns as elements and the rows as subsets of the elements then the problem can be seen finding disjoint (non-overlapping) sets (rows) that cover all the elements.&lt;/p&gt;

&lt;p&gt;This represent a variety of applications that need to fill constraints. EC can be adapted to Sudoku as a special case of the problem.&lt;/p&gt;

&lt;p&gt;EC can also be used to describe many real life problems such as making hotel room assignments given a group that has a many specific room requests, and organizing simple flight schedules for airports.&lt;/p&gt;

&lt;p&gt;Finding exact cover is a NP-complete problem and a natural candidate for using backtracking to search for possible solutions.&lt;/p&gt;

&lt;p&gt;A naive backtracking solutions will be the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;If A is empty, the problem is solved; terminate successfully.
Otherwise choose a column, c (deterministically).
Choose a row, r, such that A[r, c] = 1 (nondeterministically).
Include r in the partial solution.
For each j such that A[r, j] = 1,
    delete column j from matrix A;
    for each i such that A[i, j] = 1,
        delete row i from matrix A.
Repeat this algorithm recursively on the reduced matrix A.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;If we find at a sub-problem that there is a column with no &lt;code&gt;1&lt;/code&gt;s then there are no valid smaller sub-problem, and the process backtracks to previous state of the problem.&lt;/li&gt;
&lt;li&gt;At any stage, we should pick the column with the smallest number of &lt;code&gt;1&lt;/code&gt;s in order to reduce branching.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Possible solutions
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Dancing links&lt;/li&gt;
&lt;li&gt;Brute force candidate elimination

&lt;ul&gt;
&lt;li&gt;TLE for hard sudokus which require guessing and backtracking.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Dancing Links Algorithm
&lt;/h2&gt;

&lt;p&gt;The algorithm is based on Dr. Donald Knuth's &lt;cite&gt;&lt;a href="https://www.ocf.berkeley.edu/~jchu/publicportal/sudoku/0011047.pdf" rel="noopener noreferrer"&gt;paper&lt;/a&gt;&lt;/cite&gt;. There is also a recorded &lt;a href="https://www.youtube.com/watch?v=_cR9zDlvP88" rel="noopener noreferrer"&gt;lecture&lt;/a&gt; on the topic. Dancing Links is a backtracking, depth-first algorithm that can find all possible solutions of the problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Core Concept
&lt;/h2&gt;

&lt;p&gt;The name and the core concept of the algorithm depends on using a matrix of doubly-linked lists where the links "dance" or toggle while backtracking possible solutions.&lt;/p&gt;

&lt;p&gt;Say we want to remove object &lt;code&gt;x&lt;/code&gt; from a list, we need only 2 operations: &lt;/p&gt;

&lt;blockquote&gt;&lt;code&gt;
x.getRight().setLeft(x.getLeft())&lt;br&gt;
x.getLeft().setRight(x.getRight())
&lt;/code&gt;&lt;/blockquote&gt;

&lt;p&gt;However, when putting the object back in the list, all is needed is to do the reverse of the operation, given that &lt;code&gt;x&lt;/code&gt;'s pointers remain unchanged.&lt;/p&gt;

&lt;blockquote&gt;&lt;code&gt;
x.getRight().setLeft(x)&lt;br&gt;
x.getLeft().setRight(x)
&lt;/code&gt;&lt;/blockquote&gt;

&lt;p&gt;A key point here is that &lt;code&gt;x&lt;/code&gt;'s pointers are not modified after &lt;code&gt;x&lt;/code&gt; is deleted. We normally avoid such pointers from outside a linked list so that we don't interfere with garbage collection. However, this is useful for searching a valid solutions using backtracking since we can get the next available/valid entry without having to search through the list and recover x into the list when we backtrack to other areas of the solution space.&lt;/p&gt;

&lt;p&gt;Theoretically, if we undo the steps taken from an initial state of a linked list in reverse order (undoing steps ABC by taking C'B'A') then we can get back the initial state of the linked list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dancing Links for Exact Cover
&lt;/h2&gt;

&lt;p&gt;Dancing Links takes the Exact Cover matrix and puts it into a toroidal doubly-linked list. The links kind of represent the constraints of the problem, i.e. the row, column and grid constraints for Sudoku. Toroidal basically means that the linked lists are circularly connected (i.e. bottom with top and right with left).&lt;/p&gt;

&lt;p&gt;For every column, there is a special &lt;code&gt;ColumnNode&lt;/code&gt;, which contains that column's Unique &lt;code&gt;Name&lt;/code&gt; and the column's &lt;code&gt;size&lt;/code&gt;, the number of nodes in the column.&lt;/p&gt;

&lt;p&gt;Every &lt;code&gt;1&lt;/code&gt; in the Exact Cover matrix (actually represent as a set of rows), is a &lt;code&gt;Node&lt;/code&gt;. Each &lt;code&gt;Node&lt;/code&gt; points to another object up, down, left and right. The first and last &lt;code&gt;Nodes&lt;/code&gt; for each column to its corresponding &lt;code&gt;ColumnNode&lt;/code&gt;. A special &lt;code&gt;ColumnNode h&lt;/code&gt; points to the first &lt;code&gt;ColumnNode&lt;/code&gt; on the left as a starting point for the algorithm.&lt;/p&gt;

&lt;p&gt;So Knuth's &lt;code&gt;figure 3&lt;/code&gt; would become:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6jccxe82expohyoonli0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6jccxe82expohyoonli0.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Algorithm
&lt;/h2&gt;

&lt;p&gt;Given the &lt;code&gt;ColumnNode h&lt;/code&gt;, the searching algorithm is then simplified to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getRight&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// made a round trip from h back to h&lt;/span&gt;
    &lt;span class="n"&gt;printSolution&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ColumnNode&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chooseNextColumn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;cover&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getDown&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;rowNode&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;rowNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rowNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getDown&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// row and rowNode are different&lt;/span&gt;

        &lt;span class="n"&gt;solutions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rowNode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="n"&gt;rightNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getRight&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;otherNode&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;rightNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rightNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getRight&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// otherNode ??&lt;/span&gt;
            &lt;span class="n"&gt;cover&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rightNode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;Search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;solutions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rowNode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;column&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rowNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getColumn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// column gets updated&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="n"&gt;leftNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rowNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLeft&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;leftNode&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;leftNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;leftNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLeft&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
            &lt;span class="n"&gt;uncover&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;leftNode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;uncover&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Cover
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;cover(ColumnNode c)&lt;/code&gt; function is the crux of the algorithm. It removes a column from the&lt;br&gt;
matrix as well as remove all rows in the column from other columns they are in. The code becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dataNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getColumn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getRight&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;setLeft&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLeft&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLeft&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;setRight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getRight&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getDown&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getDown&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="n"&gt;rightNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getRight&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;rightNode&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;rightNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rightNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getRight&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;rightNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getUp&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;setDown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rightNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getDown&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="n"&gt;rightNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getDown&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;setUp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rightNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getUp&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that we first remove the column from the other columns. Then we go down a column and remove the row by traversing the row to the right. Let's look at some illustrations. Here is the matrix before &lt;code&gt;Column A&lt;/code&gt; is covered. All the links in bold are the links that are going to be affected by the cover function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2vwufco8ojx9fa8nu7ni.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2vwufco8ojx9fa8nu7ni.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now here is the matrix after &lt;code&gt;Column A&lt;/code&gt; has been covered. Notice how Column A and rows 2 and 4 are now independently&lt;br&gt;
linked outside of the matrix. In effect, they have been removed. Also note that each &lt;code&gt;node&lt;/code&gt; that has&lt;br&gt;
been removed from the matrix still points to an element inside the matrix. This allows us to easily&lt;br&gt;
backtrack.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh7v480widzazyjumyu00.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh7v480widzazyjumyu00.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Uncover
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;uncover(ColumnNode c)&lt;/code&gt; function is the answer to easy backtracking. Taking advantage of the fact that every &lt;code&gt;node&lt;/code&gt; that has been removed retains information about its neighbors, we can easily put the &lt;code&gt;node&lt;/code&gt; back into the matrix using the reverse operation of &lt;code&gt;cover(ColumnNode c)&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dataNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getColumn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// starting from the bottom row and moving up&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getUp&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getUp&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// starting from the rightmost column within a row&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="n"&gt;leftNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getleft&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;leftNode&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;leftNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;leftNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getRight&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;leftNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getUp&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;setDown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;leftNode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;leftNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getDown&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;setUp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;leftNode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getRight&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;setLeft&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLeft&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;setRight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that the traversal through the column and row are opposite to that of &lt;code&gt;cover(ColumnNode c)&lt;/code&gt;. We first put the rows back by traveling up the column and to the left of the row. Then we put the column back. In effect, we undo the operation of &lt;code&gt;cover(ColumnNode c)&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Miscellaneous Functions
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;getConstraintWithLeastOptions()&lt;/code&gt; advances the column pointer right or chooses the column with the least number of nodes. Choosing the column with the least number of nodes decreases the branching of the algorithm. It can be ignored if this isn't needed. &lt;/p&gt;

&lt;p&gt;As described in Knuth's paper, there are two methods to choose the next column in the search method.  The first simply chooses the node to the right of &lt;code&gt;ColumnNode h&lt;/code&gt;. The second minimizes the branching  of the algorithm by looking for the column with the least number of nodes in the column. The second method  is much faster for solving 16x16 Sudoku puzzles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding a Solution
&lt;/h2&gt;

&lt;p&gt;A solution is found when all the columns have been removed from the matrix. This means that very row that we have added to the answer has one node in every column. All constraints have been satisfied by the set of rows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Modeling Sudoku as an Exact Cover Problem
&lt;/h2&gt;

&lt;p&gt;Sudoku is a puzzle on a 9x9 grid with 3x3 regions, with the rule that the digits 1-9 must be placed in each cell such that every row, column, and region contains only one instance of the digit.&lt;/p&gt;

&lt;p&gt;To create the sparse matrix of Sudoku needed to convert the problem into an Exact Cover Problem, we need to recognize what the rows and columns represent.&lt;/p&gt;

&lt;p&gt;The columns represent the constraints of the puzzle. In Sudoku, we have four:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A position constraint: Only 1 number can occupy a cell&lt;/li&gt;
&lt;li&gt;A row constraint: Only 1 instance of a number can be in the row&lt;/li&gt;
&lt;li&gt;A column constraint: Only 1 instance of a number can be in a column&lt;/li&gt;
&lt;li&gt;A region constraint: Only 1 instance of a number can be in a region&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each number comes with its own set of constraints. Therefore there are &lt;code&gt;SIZE^2 * 4&lt;/code&gt; columns., where &lt;code&gt;SIZE&lt;/code&gt; is the number of candidates/rows/cols there are in the Sudoku Puzzle. In a 4x4, this would be 64 columns. In a 9x9, this would be 324 columns.&lt;/p&gt;

&lt;p&gt;Given initial positions in the matrix, those rows will be included in the answer and &lt;code&gt;covered()&lt;/code&gt;. Then the Search algorithm will produce the solutions to the puzzle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;There are unique ways to code the solution for the &lt;cite&gt;&lt;a href="https://leetcode.com/problems/sudoku-solver" rel="noopener noreferrer"&gt;problem&lt;/a&gt;&lt;/cite&gt; using the pseudo-code in the &lt;cite&gt;&lt;a href="https://www.ocf.berkeley.edu/~jchu/publicportal/sudoku/sudoku.paper.html" rel="noopener noreferrer"&gt;paper&lt;/a&gt;&lt;/cite&gt;. The best learning outcome will be to try it out yourself.&lt;/p&gt;

&lt;p&gt;For reference, here is an OOP style implementation in C++: &lt;cite&gt;&lt;a href="https://github.com/prantoran/cp/blob/master/LeetCode/sudoku-solver.cpp" rel="noopener noreferrer"&gt;github.com/prantoran/.../sudoku-solver.cpp&lt;/a&gt;&lt;/cite&gt;.&lt;/p&gt;

&lt;p&gt;Here are some observations and tricks I learned during the process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep data models as separate classes and keep methods small.&lt;/li&gt;
&lt;li&gt;Take small steps and debug. Ensure that all previous steps are bug free before trying out next steps. For example, I checked whether the constraint columns are generated properly by assigning names and printing them out.&lt;/li&gt;
&lt;li&gt;The branching from a state affect runtime. At every step of &lt;code&gt;search()&lt;/code&gt;, I picked the constraint column with the smallest number of options.&lt;/li&gt;
&lt;li&gt;Reduce possible rows by eliminating options that are impossible by checking the existing digits in the rows, columns and grids.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Good luck and have fun!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
