<?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[ puzzles - 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[ puzzles - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Tue, 28 Jul 2026 20:13:18 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/puzzles/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Solve Einstein's Five House Riddle ]]>
                </title>
                <description>
                    <![CDATA[ I recently learned about a logic puzzle online that apparently only 2% of people can solve. There are a few different incarnations of it – some have slightly different wording, different names, or change the items in the riddle slightly. But they are... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/einsteins-riddle/</link>
                <guid isPermaLink="false">66bc55ced94fa6cb67b8451b</guid>
                
                    <category>
                        <![CDATA[ logic ]]>
                    </category>
                
                    <category>
                        <![CDATA[ puzzles ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kealan Parr ]]>
                </dc:creator>
                <pubDate>Wed, 08 Sep 2021 15:36:22 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/09/Capture.JPG" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>I recently learned about a logic puzzle online that apparently only 2% of people can solve.</p>
<p>There are a few different incarnations of it – some have slightly different wording, different names, or change the items in the riddle slightly. But they are all the exact same core problem.</p>
<p>The riddle itself is used as a benchmark in the evaluation of <a target="_blank" href="https://en.wikipedia.org/wiki/Constraint_satisfaction_problem">constraint satisfaction problems</a> for computer algorithms.</p>
<h2 id="heading-what-is-the-einstein-riddle">What is the Einstein Riddle?</h2>
<p>Even the origin of it the riddle is a little unclear. It's famously known as the <strong>Einstein Riddle</strong> because it was supposedly created by Einstein as a young man for fun. Others say it was used by Einstein to only select the smartest PhD students he would supervise. </p>
<p>But there are some claims online that it actually was invented by the author of <em>Alice's Adventures in Wonderland</em>, <a target="_blank" href="https://en.wikipedia.org/wiki/Lewis_Carroll">Lewis Carrol</a>.</p>
<p>It's highly unlikely that it was written by Einstein, but that doesn't really matter. What's important is that, with a basic understanding of truth tables (and a bit of patience), you can solve it, too.</p>
<h2 id="heading-how-to-solve-einsteins-riddle">How to Solve Einstein's Riddle</h2>
<p>I'm now going to give you a list of clues, and then you will need to answer a question at the end of the clues.</p>
<p>Just to be absolutely clear, all the clues are enough for you to solve it. You don't need any extra hints, and there aren't any assumptions I expect you to know.</p>
<blockquote>
<p>There are 5 houses painted five different colors.<br>In each house lives a person with a different nationality.<br>These five owners drink a certain type of beverage, smoke a certain brand of cigar, and keep a certain pet.<br>No owners have the same pet, smoke the same brand of cigar, or drink the same beverage.</p>
</blockquote>
<ul>
<li>The Brit lives in the red house</li>
<li>The Swede keeps dogs as pets</li>
<li>The Dane drinks tea</li>
<li>The green house is on the left of the white house</li>
<li>The person who smokes Pall Malls rears birds</li>
<li>The owner of the yellow house smokes Dunhill</li>
<li>The green house’s owner drinks coffee</li>
<li>The man living in the center house drinks milk</li>
<li>The Norwegian lives in the first (leftmost) house</li>
<li>The man who smokes Blends lives next to the one who keeps cats</li>
<li>The man who keeps horses lives next to the man who smokes Dunhill</li>
<li>The owner who smokes BlueMaster drinks beer</li>
<li>The German smokes Princes</li>
<li>The Norwegian lives next to the blue house</li>
<li>The man who smokes Blends has a neighbor who drinks water</li>
</ul>
<p>Now to solve, <strong>tell me who owns the fish</strong>?</p>
<p>I solved it, but it did take me a couple attempts and a bit of scribbling on paper.</p>
<h2 id="heading-how-i-approached-the-problem">How I Approached the Problem</h2>
<p>To solve the problem, the first thing I did was to try and group together the clues. There are two references to the green house in the clues, so I tried to "solve" and consider those two clues together when I was able to.  </p>
<p>I then also filled out the center house's beverage as one clue immediately tells you, and I was also able to immediately fill out the leftmost house's nationality.</p>
<p>I essentially drew a really basic grid and eliminated and filled in possibilities based initially just on the clues. Then as I filled in more, I was able to fill in more details on other houses.  </p>
<p>I don't want to keep going with the hints if you want to solve this for yourself, but that's a starting point.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/09/image-29.png" alt="Image" width="600" height="400" loading="lazy">
<em>A screenshot of part of a 5x5 table with every different possibility of Nationality, Color, Beverage, Pet and Smoking Cigar that can be removed on click.</em></p>
<p>To try and make it easier for anyone who wants to solve it or check their answer, I have made a basic site you can find here: <a target="_blank" href="http://einsteins-riddle.com/">http://einsteins-riddle.com/</a> – the screenshot from above is a part of the grid on the site.</p>
<p>On that site, you'll find a table with all the options laid out as clickable buttons. The grid is initially filled out with all the possibilities, and as you learn more you can remove possibilities until eventually there is only one option left. </p>
<p>At the bottom is a "Check Answer" button that will evaluate what you have left on your grid.</p>
<p>Try and solve it and see how you get on! If you prefer to do it via paper please do so.</p>
<p>I wish you luck 😊</p>
<p>If it stumps you, and you want to know how to solve it, you can find the solution <a target="_blank" href="https://udel.edu/~os/riddle-solution.html">here</a>.</p>
<h2 id="heading-why-are-truth-tables-helpful">Why are Truth Tables Helpful?</h2>
<p>I enjoy trying to work through these truth table problems, as it helps improve my clarity of thought. </p>
<p>Sometimes when I'm coding and need to carefully consider some complex Boolean states in my code (not <strong>this</strong>, and not <strong>that OR this</strong> and <strong>that</strong> (and not <strong>those</strong>)) I think that these puzzles help me reason more clearly to simplify my code.</p>
<p>They also help me technically plan out my approach to a problem, from the very beginning to the eventual solution. </p>
<p>I start from a basic set of requirements and no idea how all they fit together. But as I move along, I can go through a process of fact finding, checking edge cases, verifying/testing my logic against the requirements and finally submitting my work. All of these steps translate exactly to software development.  </p>
<p>Whenever you have a complicated set of states you are confused by, draw a basic truth table. Or however you want to represent the problem. Breaking it down into smaller and smaller problems will allow you to solve almost anything.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>I hope this has been an enjoyable brain teaser, and that you solved as much or as little as was fun for you.</p>
<p>I share my writing on <a target="_blank" href="https://twitter.com/kealanparr">Twitter</a> if you enjoyed this article and want to see more.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Solve a Sudoku Puzzle Using Azure AI ]]>
                </title>
                <description>
                    <![CDATA[ By Ankit Sharma In this article, we are going to create a sudoku solver with the help of Azure Form Recognizer, an AI-powered document extraction service.  The application will allow users to upload an image of the sudoku table. We will extract the d... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/solve-sudoku-using-azure-ai/</link>
                <guid isPermaLink="false">66d45dcf680e33282da25e41</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Azure ]]>
                    </category>
                
                    <category>
                        <![CDATA[ puzzles ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 06 Apr 2021 16:30:17 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/6065634f9618b008528ab1f6.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ankit Sharma</p>
<p>In this article, we are going to create a sudoku solver with the help of Azure Form Recognizer, an AI-powered document extraction service. </p>
<p>The application will allow users to upload an image of the sudoku table. We will extract the data from the image, and then implement the sudoku solving algorithm on it.</p>
<p>We will use .NET for the backend, Angular for the front end, and Angular material for styling the application.</p>
<p>You can see a working demo of the application below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/SudokuSolver.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<ul>
<li>Install the latest LTS version of Node.JS from <a target="_blank" href="https://nodejs.org/en/download/">https://nodejs.org/en/download/</a></li>
<li>Install the Angular CLI from <a target="_blank" href="https://cli.angular.io/">https://cli.angular.io/</a></li>
<li>An Azure subscription account. You can create a free Azure account at <a target="_blank" href="https://azure.microsoft.com/en-in/free/">https://azure.microsoft.com/en-in/free/</a></li>
<li>Install the .NET Core 5.0 SDK from <a target="_blank" href="https://dotnet.microsoft.com/download/dotnet/5.0">https://dotnet.microsoft.com/download/dotnet/5.0</a></li>
<li>Install the latest version of Visual Studio 2019 from <a target="_blank" href="https://visualstudio.microsoft.com/downloads/">https://visualstudio.microsoft.com/downloads/</a></li>
</ul>
<h2 id="heading-source-code">Source Code</h2>
<p>You can get the source code from <a target="_blank" href="https://github.com/AnkitSharma-007/Azure-AI-Sudoku-solver">GitHub</a>.</p>
<h2 id="heading-what-is-azure-form-recognizer-cognitive-service">What is Azure Form Recognizer Cognitive Service?</h2>
<p>The <a target="_blank" href="https://azure.microsoft.com/en-in/services/cognitive-services/form-recognizer/">Azure Form Recognizer</a> cognitive service allows us to build automated data processing software using machine learning technology. It lets us extract text, key/value pairs, selection marks, tables, and structure from our documents. </p>
<p>We can easily invoke the Form Recognizer models with the help of a REST API or client library SDKs.</p>
<p>The Form Recognizer cognitive service provides the following features:</p>
<ul>
<li><strong>Prebuilt models</strong>: We can use the prebuilt models to extract data from the unique document type such as invoices, receipts, IDs, and business cards.</li>
<li><strong>Custom models</strong>: we can extract text, key/value pairs, selection marks, and table data from forms using the custom models. However, we need to train the custom models using our data so that it suits our custom needs.</li>
<li><strong>Layout API</strong>: It allows us to extract text, selection marks, and table structures from the documents.</li>
</ul>
<p>In this article, we are going to use the layout API to extract content from the image of the sudoku table that the user uploads.</p>
<h2 id="heading-how-to-create-the-azure-form-recognizer-cognitive-service-resource">How to Create the Azure Form Recognizer Cognitive Service Resource</h2>
<p>Login to the Azure portal and search for the cognitive services in the search bar and click on the result. On the next screen, click on the Create button. It will open the cognitive services marketplace page. Search for the Form Recognizer in the search bar and click on the “Form Recognizer” card from the search result. </p>
<p>This will open the Form Recognizer API page. Click on the Create button to create a new Form Recognizer resource. Refer to the image shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/CreateFR.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>On the Create Form Recognizer page, fill in the details as indicated below.</p>
<ul>
<li><strong>Subscription</strong>: Select the subscription type from the dropdown.</li>
<li><strong>Resource group</strong>: Select an existing resource group or create a new one.</li>
<li><strong>Region</strong>: Choose the region which is right for you.</li>
<li><strong>Name</strong>: Give a unique name to your resource.</li>
<li><strong>Pricing tier</strong>: Select the pricing tier you want.</li>
</ul>
<p>Click on the “Review +Create” button. Refer to the image shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/ConfigureFR.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>On the next page, check the terms of use, verify the information which you have provided, and then click on the “Create” button.</p>
<p>After your resource is successfully deployed, click on the “Go to resource” button. Click on the “Keys and the endpoint” link on the menu on the left. Refer to the image shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/FRKeys.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Make a note of the endpoint and any one of the keys provided. We will be using these in the latter part of this article to invoke the Layout API of the Form recognizer service from the .NET code.</p>
<h2 id="heading-how-to-create-the-aspnet-core-application">How to Create the ASP.NET Core Application</h2>
<p>Open Visual Studio 2019 and click on “Create a new Project”. A “Create a new Project” dialog will open. Select “ASP.NET Core with Angular” and click on Next. Refer to the image shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/CreateProj.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Now you will be at the “Configure your new project” screen. Provide the name for your application as <code>ngSudokuSolver</code>, and click on Next. Refer to the image shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/CreateProj_1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>On the additional information page, select the target framework as .NET 5.0 and set the authentication type to none as shown in the image below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/CreateProj_2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This will create our project. The folder structure of the application looks like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/Sol_Exp.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The <code>ClientApp</code> folder contains the Angular code for our application. The Controllers folders will contain our API controllers. The angular components are present inside the <code>ClientApp\src\app</code> folder. </p>
<p>The default template contains few Angular components. These components will not affect our application, but for the sake of simplicity, we will delete <code>fetchdata</code> and <code>counter</code> folders from <code>ClientApp/src/app</code> folder. Also, remove the reference for these two components from the <code>app.module.ts</code> file.</p>
<h2 id="heading-how-to-install-the-required-nuget-packages">How to Install the Required NuGet Packages</h2>
<p>To install the package, navigate to Tools &gt;&gt; NuGet Package Manager &gt;&gt; Package Manager Console. It will open the Package Manager Console inside Visual Studio.</p>
<p>Run the following command to install the <a target="_blank" href="https://www.nuget.org/packages/Polly">Polly library</a>. This library allows you to express resilience and transient fault handling policies such as Retry, Circuit Breaker, Timeout, Bulkhead Isolation, and Fallback in a fluent and thread-safe manner.</p>
<p><code>Install-Package Polly -Version 7.2.1</code></p>
<p>Run the following command to install the <a target="_blank" href="https://www.nuget.org/packages/Newtonsoft.Json/">Newtonsoft.Json</a> package.</p>
<p><code>Install-Package Newtonsoft.Json -Version 13.0.1</code></p>
<h2 id="heading-how-to-create-the-retrymessage-handler">How to Create the RetryMessage Handler</h2>
<p>Right-click on the <code>ngSudokuSolver</code> project and select Add &gt;&gt; New Folder. Name the folder Models. </p>
<p>Again, right-click on the Models folder and select Add &gt;&gt; Class to add a new class file. Put the name of your class as <code>HttpRetryMessageHandler.cs</code> and click "Add". </p>
<p>Put the following code inside this class.</p>
<pre><code class="lang-C#">
<span class="hljs-keyword">using</span> Newtonsoft.Json;
<span class="hljs-keyword">using</span> Polly;
<span class="hljs-keyword">using</span> System;
<span class="hljs-keyword">using</span> System.Net.Http;
<span class="hljs-keyword">using</span> System.Threading;
<span class="hljs-keyword">using</span> System.Threading.Tasks;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">ngSudokuSolver.Models</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">HttpRetryMessageHandler</span> : <span class="hljs-title">DelegatingHandler</span>
    {
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">HttpRetryMessageHandler</span>(<span class="hljs-params">HttpClientHandler handler</span>) : <span class="hljs-title">base</span>(<span class="hljs-params">handler</span>)</span> { }

        <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">override</span> Task&lt;HttpResponseMessage&gt; <span class="hljs-title">SendAsync</span>(<span class="hljs-params">
            HttpRequestMessage request,
            CancellationToken cancellationToken</span>)</span> =&gt;
            Policy
                .Handle&lt;HttpRequestException&gt;()
                .Or&lt;TaskCanceledException&gt;()
                .OrResult&lt;HttpResponseMessage&gt;(x =&gt;
                {
                    <span class="hljs-keyword">string</span> result = x.Content.ReadAsStringAsync().GetAwaiter().GetResult();
                    <span class="hljs-keyword">dynamic</span> array = JsonConvert.DeserializeObject(result);

                    <span class="hljs-keyword">if</span> (array[<span class="hljs-string">"status"</span>] == <span class="hljs-string">"running"</span>)
                    {
                        <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
                    }
                    <span class="hljs-keyword">else</span>
                    {
                        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
                    }
                })
                .WaitAndRetryAsync(<span class="hljs-number">7</span>, retryAttempt =&gt; TimeSpan.FromSeconds(Math.Pow(<span class="hljs-number">2</span>, retryAttempt)))
                .ExecuteAsync(() =&gt; <span class="hljs-keyword">base</span>.SendAsync(request, cancellationToken));
    }
}
</code></pre>
<p>We will use the RetryMessageHandler to retry the <code>sendAsync</code> call. We will retry the HTTP call if the status of the HttpResponseMessage is “running”. </p>
<p>The maximum retry attempts is set to 7. On each retry, we will increase the duration of wait time by a power of 2. If the maximum number of retries has been exhausted and the HttpResponseMessage is not successful yet, we will return false.</p>
<h2 id="heading-how-to-add-the-formrecognizer-controller">How to Add the FormRecognizer Controller</h2>
<p>Now we will add a new controller to our application. </p>
<p>Right-click on the Controllers folder and select Add &gt;&gt; New Item. An “Add New Item” dialog box will open. </p>
<p>Select “Visual C#” from the left panel, then select “API Controller-Empty” from the templates panel and put the name as <code>FormRecognizerController.cs</code>. Click on Add. Refer to the image below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/AddController.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Put the following code inside this class.</p>
<pre><code class="lang-C#"><span class="hljs-keyword">using</span> Microsoft.AspNetCore.Mvc;
<span class="hljs-keyword">using</span> Newtonsoft.Json;
<span class="hljs-keyword">using</span> Newtonsoft.Json.Linq;
<span class="hljs-keyword">using</span> ngSudokuSolver.Models;
<span class="hljs-keyword">using</span> System;
<span class="hljs-keyword">using</span> System.Collections.Generic;
<span class="hljs-keyword">using</span> System.IO;
<span class="hljs-keyword">using</span> System.Linq;
<span class="hljs-keyword">using</span> System.Net.Http;
<span class="hljs-keyword">using</span> System.Net.Http.Headers;
<span class="hljs-keyword">using</span> System.Threading.Tasks;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">ngSudokuSolver.Controllers</span>
{
    [<span class="hljs-meta">Produces(<span class="hljs-meta-string">"application/json"</span>)</span>]
    [<span class="hljs-meta">Route(<span class="hljs-meta-string">"api/[controller]"</span>)</span>]
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">FormRecognizerController</span> : <span class="hljs-title">ControllerBase</span>
    {
        <span class="hljs-keyword">static</span> <span class="hljs-keyword">string</span> endpoint;
        <span class="hljs-keyword">static</span> <span class="hljs-keyword">string</span> apiKey;

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">FormRecognizerController</span>(<span class="hljs-params"></span>)</span>
        {
            endpoint = <span class="hljs-string">"https://sudokusolver.cognitiveservices.azure.com/"</span>;
            apiKey = <span class="hljs-string">"a9f75796b3ba49bdade48eb3b905cb0e"</span>;
        }

        [<span class="hljs-meta">HttpPost, DisableRequestSizeLimit</span>]
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;<span class="hljs-keyword">string</span>[][]&gt; Post()
        {
            <span class="hljs-keyword">try</span>
            {
                <span class="hljs-keyword">string</span>[][] sudokuArray = GetNewSudokuArray();

                <span class="hljs-keyword">if</span> (Request.Form.Files.Count &gt; <span class="hljs-number">0</span>)
                {
                    <span class="hljs-keyword">var</span> file = Request.Form.Files[Request.Form.Files.Count - <span class="hljs-number">1</span>];

                    <span class="hljs-keyword">if</span> (file.Length &gt; <span class="hljs-number">0</span>)
                    {
                        <span class="hljs-keyword">var</span> memoryStream = <span class="hljs-keyword">new</span> MemoryStream();
                        file.CopyTo(memoryStream);
                        <span class="hljs-keyword">byte</span>[] imageFileBytes = memoryStream.ToArray();
                        memoryStream.Flush();

                        <span class="hljs-keyword">string</span> SudokuLayoutJSON = <span class="hljs-keyword">await</span> GetSudokuBoardLayout(imageFileBytes);
                        <span class="hljs-keyword">if</span> (SudokuLayoutJSON.Length &gt; <span class="hljs-number">0</span>)
                        {
                            sudokuArray = GetSudokuBoardItems(SudokuLayoutJSON);
                        }
                    }
                }

                <span class="hljs-keyword">return</span> sudokuArray;
            }
            <span class="hljs-keyword">catch</span>
            {
                <span class="hljs-keyword">throw</span>;
            }
        }

        <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">async</span> Task&lt;<span class="hljs-keyword">string</span>&gt; <span class="hljs-title">GetSudokuBoardLayout</span>(<span class="hljs-params"><span class="hljs-keyword">byte</span>[] byteData</span>)</span>
        {
            HttpClient client = <span class="hljs-keyword">new</span>();
            client.DefaultRequestHeaders.Add(<span class="hljs-string">"Ocp-Apim-Subscription-Key"</span>, apiKey);
            <span class="hljs-keyword">string</span> uri = endpoint + <span class="hljs-string">"formrecognizer/v2.1-preview.3/layout/analyze"</span>;
            <span class="hljs-keyword">string</span> LayoutJSON = <span class="hljs-keyword">string</span>.Empty;

            <span class="hljs-keyword">using</span> (ByteArrayContent content = <span class="hljs-keyword">new</span>(byteData))
            {
                HttpResponseMessage response;
                content.Headers.ContentType = <span class="hljs-keyword">new</span> MediaTypeHeaderValue(<span class="hljs-string">"image/png"</span>);
                response = <span class="hljs-keyword">await</span> client.PostAsync(uri, content);

                <span class="hljs-keyword">if</span> (response.IsSuccessStatusCode)
                {
                    HttpHeaders headers = response.Headers;

                    <span class="hljs-keyword">if</span> (headers.TryGetValues(<span class="hljs-string">"Operation-Location"</span>, <span class="hljs-keyword">out</span> IEnumerable&lt;<span class="hljs-keyword">string</span>&gt; values))
                    {
                        <span class="hljs-keyword">string</span> OperationLocation = values.First();
                        LayoutJSON = <span class="hljs-keyword">await</span> GetJSON(OperationLocation);
                    }
                }
            }
            <span class="hljs-keyword">return</span> LayoutJSON;
        }

        <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">async</span> Task&lt;<span class="hljs-keyword">string</span>&gt; <span class="hljs-title">GetJSON</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> endpoint</span>)</span>
        {
            <span class="hljs-keyword">using</span> <span class="hljs-keyword">var</span> client = <span class="hljs-keyword">new</span> HttpClient(<span class="hljs-keyword">new</span> HttpRetryMessageHandler(<span class="hljs-keyword">new</span> HttpClientHandler()));
            <span class="hljs-keyword">var</span> request = <span class="hljs-keyword">new</span> HttpRequestMessage();
            request.Method = HttpMethod.Get;
            request.RequestUri = <span class="hljs-keyword">new</span> Uri(endpoint);

            client.DefaultRequestHeaders.Add(<span class="hljs-string">"Ocp-Apim-Subscription-Key"</span>, apiKey);

            <span class="hljs-keyword">var</span> response = <span class="hljs-keyword">await</span> client.SendAsync(request);
            <span class="hljs-keyword">var</span> result = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();

            <span class="hljs-keyword">return</span> result;
        }

        <span class="hljs-keyword">static</span> <span class="hljs-keyword">string</span>[][] GetSudokuBoardItems(<span class="hljs-keyword">string</span> LayoutData)
        {
            <span class="hljs-keyword">string</span>[][] sudokuArray = GetNewSudokuArray();
            <span class="hljs-keyword">dynamic</span> array = JsonConvert.DeserializeObject(LayoutData);
            <span class="hljs-keyword">int</span> countOfCells = ((JArray)array?.analyzeResult?.pageResults[<span class="hljs-number">0</span>]?.tables[<span class="hljs-number">0</span>]?.cells).Count;

            <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; countOfCells; i++)
            {
                <span class="hljs-keyword">int</span> rowIndex = array.analyzeResult.pageResults[<span class="hljs-number">0</span>].tables[<span class="hljs-number">0</span>].cells[i].rowIndex;
                <span class="hljs-keyword">int</span> columnIndex = array.analyzeResult.pageResults[<span class="hljs-number">0</span>].tables[<span class="hljs-number">0</span>].cells[i].columnIndex;

                sudokuArray[rowIndex][columnIndex] = array.analyzeResult.pageResults[<span class="hljs-number">0</span>].tables[<span class="hljs-number">0</span>].cells[i]?.text;
            }
            <span class="hljs-keyword">return</span> sudokuArray;
        }

        <span class="hljs-keyword">static</span> <span class="hljs-keyword">string</span>[][] GetNewSudokuArray()
        {
            <span class="hljs-keyword">string</span>[][] sudokuArray = <span class="hljs-keyword">new</span> <span class="hljs-keyword">string</span>[<span class="hljs-number">9</span>][];

            <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">9</span>; i++)
            {
                sudokuArray[i] = <span class="hljs-keyword">new</span> <span class="hljs-keyword">string</span>[<span class="hljs-number">9</span>];
            }

            <span class="hljs-keyword">return</span> sudokuArray;
        }
    }
}
</code></pre>
<p>In the constructor of the class, we have initialized the key and the endpoint URL for the formrecognizer API.</p>
<p>The Post method will receive the image data as a file collection in the request body and return a two-dimensional array. We will convert the image data to a byte array and invoke the <code>GetSudokuBoardLayout</code> method. If we get a successful response and the JSON result is not empty, we will invoke the <code>GetSudokuBoardItems</code> method.</p>
<p>Inside the <code>GetSudokuBoardLayout</code> method, we will instantiate a new HttpClient. We will pass the subscription key in the header of the request. </p>
<p>When we use the formrecognizer API, we will get a status code as 202. This indicates that the service has accepted the request and will start processing later. </p>
<p>The response includes an "Operation-Location" header. The "Operation-Location" field contains the URL that we should use to get the result of the formrecognizer operation. The URL mentioned in the header will expire in 48 hours.</p>
<p>For the result of the formrecognizer service to be available, it requires a certain amount of time that depends on the length of the text. </p>
<p>This is where our RetryMessageHandler will be utilized. We will fetch the URL from the header and invoke the <code>GetJSON</code> method to fetch the JSON result. </p>
<p>Inside the <code>GetJSON</code> method, we create the HttpClient and initialize it with our custom <code>HttpRetryMessageHandler</code>. This method will return the JSON response as a string.</p>
<p>The <code>GetSudokuBoardItems</code> method will accept the JSON string. It will then iterate over the tables property of the JSON string to prepare the two-dimensional <code>sudokuArray</code>.</p>
<h2 id="heading-now-lets-work-on-the-client-side-of-the-application">Now Let's Work on the Client Side of the Application</h2>
<p>The code for the client-side is available in the ClientApp folder. We will use Angular CLI to work with the client code.</p>
<blockquote>
<p>Using Angular CLI is not mandatory. I am using Angular CLI here as it is user-friendly and straightforward. If you do not want to use CLI then you can create the files for components and services manually.</p>
</blockquote>
<p>Navigate to the <code>ngSudokuSolver\ClientApp</code> folder in your machine and open a command window. We will execute all our Angular CLI commands in this window.</p>
<h2 id="heading-how-to-install-angular-material">How to Install Angular Material</h2>
<p>Run the following command to add Angular Material to the project.</p>
<p><code>ng add @angular/material</code></p>
<p>This command will install Angular Material to your project and then ask the following questions to determine which features to include:</p>
<ul>
<li>Choose a prebuilt theme name, or "custom" for a custom theme: We will select the Indigo/Pink theme.</li>
<li>Set up global Angular Material typography styles? (Y/n): Y</li>
<li>Set up browser animations for Angular Material? (Y/n): Y</li>
</ul>
<p>Refer to the image shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/ngMaterial.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-add-the-module-for-angular-material">How to Add the Module for Angular Material</h2>
<p>Run the following command to create a new module.</p>
<p><code>ng g m ng-material</code></p>
<p>Open the <code>src\app\ng-material\ng-material.module.ts</code> file and put the following code inside it.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { NgModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { CommonModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/common'</span>;
<span class="hljs-keyword">import</span> { MatButtonModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/material/button'</span>;
<span class="hljs-keyword">import</span> { MatCardModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/material/card'</span>;
<span class="hljs-keyword">import</span> { MatInputModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/material/input'</span>;
<span class="hljs-keyword">import</span> { MatToolbarModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/material/toolbar'</span>;
<span class="hljs-keyword">import</span> { MatDividerModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/material/divider'</span>;
<span class="hljs-keyword">import</span> { MatIconModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/material/icon'</span>;

<span class="hljs-keyword">const</span> materialModules = [
  MatButtonModule,
  MatCardModule,
  MatInputModule,
  MatToolbarModule,
  MatDividerModule,
  MatIconModule,
];

<span class="hljs-meta">@NgModule</span>({
  declarations: [],
  imports: [CommonModule, ...materialModules],
  <span class="hljs-built_in">exports</span>: [...materialModules],
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> NgMaterialModule {}
</code></pre>
<p>We are importing all the required modules for Angular material components that we'll use in this application. A separate module for Angular material will make the application easy to maintain.</p>
<p>Import the <code>NgMaterialModule</code> in the <code>app.module.ts</code> file as shown below:</p>
<pre><code><span class="hljs-keyword">import</span> { NgMaterialModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'./ng-material/ng-material.module'</span>;

@NgModule({
    ...
    imports: [
        ...
        NgMaterialModule,
    ],
})
</code></pre><h2 id="heading-how-to-configure-the-nav-bar-of-the-app">How to Configure the Nav-bar of the App</h2>
<p>Open <code>nav-menu.component.html</code> and put the following code inside it.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">mat-toolbar</span> <span class="hljs-attr">color</span>=<span class="hljs-string">"primary"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"mat-elevation-z2"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">mat-toolbar-row</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">mat-button</span> [<span class="hljs-attr">routerLink</span>]=<span class="hljs-string">'["/"]'</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">mat-icon</span>&gt;</span>book<span class="hljs-tag">&lt;/<span class="hljs-name">mat-icon</span>&gt;</span> Sudoku Solver
      <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">mat-toolbar-row</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">mat-toolbar</span>&gt;</span>
</code></pre>
<p>We have added the material toolbar and a button that will link to the base route of the application.</p>
<h2 id="heading-how-to-create-the-form-recognizer-service">How to Create the Form Recognizer Service</h2>
<p>We will create an Angular service that will invoke the Web API endpoints and pass the response to our component. Run the following command.</p>
<p><code>ng g s services\form-recognizer</code></p>
<p>This command will create a folder name as services and then create the following two files inside it:</p>
<ul>
<li>form-recognizer.service.ts — the service class file.</li>
<li>form-recognizer.service.spec.ts — the unit test file for service.</li>
</ul>
<p>Open the <code>form-recognizer.service.ts</code> file and put the following code inside it.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Injectable } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { HttpClient } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/common/http'</span>;

<span class="hljs-meta">@Injectable</span>({
  providedIn: <span class="hljs-string">'root'</span>,
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> FormRecognizerService {
  baseURL: <span class="hljs-built_in">string</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> http: HttpClient</span>) {
    <span class="hljs-built_in">this</span>.baseURL = <span class="hljs-string">'/api/FormRecognizer'</span>;
  }

  getSudokuTableFromImage(image: FormData) {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.http.post(<span class="hljs-built_in">this</span>.baseURL, image);
  }
}
</code></pre>
<p>We have defined a variable baseURL that will hold the endpoint URL of our API. We will initialize the baseURL in the constructor and set it to the endpoint of the <code>FormRecognizerController</code>.</p>
<p>The <code>getSudokuTableFromImage</code> method will send a Post request to the <code>FormRecognizerController</code> and supply the parameter of type FormData. It will fetch a two-dimensional array that denotes the items in the sudoku table.</p>
<h2 id="heading-how-to-update-the-home-component">How to Update the Home Component</h2>
<p>Open <code>home.component.html</code> and put the following code in it.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"display-4"</span>&gt;</span>Solve Sudoku using Azure AI<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">mat-divider</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">mat-divider</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"row mt-3"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-6"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">mat-card</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"mat-elevation-z4"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">mat-card-content</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">table</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">tr</span> *<span class="hljs-attr">ngFor</span>=<span class="hljs-string">"let row of gameBoard"</span>&gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">td</span> *<span class="hljs-attr">ngFor</span>=<span class="hljs-string">"let col of gameBoard"</span>&gt;</span>
                {{game[row][col]}}
              <span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">table</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">mat-card-content</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">mat-card-actions</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">mat-raised-button</span> <span class="hljs-attr">color</span>=<span class="hljs-string">"primary"</span> (<span class="hljs-attr">click</span>)=<span class="hljs-string">"SolveSudoku()"</span>&gt;</span> Solve Sudoku <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">mat-card-actions</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">mat-card</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-6"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"image-container"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"preview-image"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">{{imagePreview}}</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"file"</span> (<span class="hljs-attr">change</span>)=<span class="hljs-string">"uploadImage($event)"</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">hr</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">mat-raised-button</span> <span class="hljs-attr">color</span>=<span class="hljs-string">"accent"</span> (<span class="hljs-attr">click</span>)=<span class="hljs-string">"GetSudokuTable()"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">span</span> *<span class="hljs-attr">ngIf</span>=<span class="hljs-string">"loading"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"spinner-border spinner-border-sm mr-1"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>Extract Sudoku Table
      <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>We have created a 9x9 table that denotes a sudoku board. We have defined a file upload control that will allow us to upload an image. After uploading the image, the preview of the image will be displayed using an <code>&lt;img&gt;</code> element.</p>
<p>Clicking on the “Extract Sudoku Table” button will fetch the content of the sudoku from the image and partially fill the table. Clicking on “Solve Sudoku” will solve the sudoku and update the table with the result.</p>
<p>Open the <code>home.component.ts</code> file and put the following code inside it.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Component, OnDestroy, OnInit } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { Subject } <span class="hljs-keyword">from</span> <span class="hljs-string">'rxjs'</span>;
<span class="hljs-keyword">import</span> { FormRecognizerService } <span class="hljs-keyword">from</span> <span class="hljs-string">'../services/form-recognizer.service'</span>;
<span class="hljs-keyword">import</span> { takeUntil } <span class="hljs-keyword">from</span> <span class="hljs-string">'rxjs/operators'</span>;

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-home'</span>,
  templateUrl: <span class="hljs-string">'./home.component.html'</span>,
  styleUrls: [<span class="hljs-string">'./home.component.scss'</span>],
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> HomeComponent <span class="hljs-keyword">implements</span> OnDestroy {
  gameBoard = [<span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</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>];
  loading = <span class="hljs-literal">false</span>;
  imageFile;
  imagePreview;
  maxFileSize: <span class="hljs-built_in">number</span>;
  isValidFile = <span class="hljs-literal">true</span>;
  status: <span class="hljs-built_in">string</span>;
  DefaultStatus: <span class="hljs-built_in">string</span>;
  imageData = <span class="hljs-keyword">new</span> FormData();
  game = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Array</span>(<span class="hljs-number">9</span>);
  <span class="hljs-keyword">private</span> unsubscribe$ = <span class="hljs-keyword">new</span> Subject();

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> formRecognizerService: FormRecognizerService</span>) {
    <span class="hljs-built_in">this</span>.DefaultStatus = <span class="hljs-string">'Maximum size allowed for the image is 4 MB'</span>;
    <span class="hljs-built_in">this</span>.status = <span class="hljs-built_in">this</span>.DefaultStatus;
    <span class="hljs-built_in">this</span>.maxFileSize = <span class="hljs-number">4</span> * <span class="hljs-number">1024</span> * <span class="hljs-number">1024</span>; <span class="hljs-comment">// 4MB</span>

    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-built_in">this</span>.game.length; i++) {
      <span class="hljs-built_in">this</span>.game[i] = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Array</span>(<span class="hljs-number">9</span>);
    }
  }

  uploadImage(event) {
    <span class="hljs-built_in">this</span>.imageFile = event.target.files[<span class="hljs-number">0</span>];
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.imageFile.size &gt; <span class="hljs-built_in">this</span>.maxFileSize) {
      <span class="hljs-built_in">this</span>.status = <span class="hljs-string">`The file size is <span class="hljs-subst">${<span class="hljs-built_in">this</span>.imageFile.size}</span> bytes, this is more than the allowed limit of <span class="hljs-subst">${<span class="hljs-built_in">this</span>.maxFileSize}</span> bytes.`</span>;
      <span class="hljs-built_in">this</span>.isValidFile = <span class="hljs-literal">false</span>;
    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.imageFile.type.indexOf(<span class="hljs-string">'image'</span>) == <span class="hljs-number">-1</span>) {
      <span class="hljs-built_in">this</span>.status = <span class="hljs-string">'Please upload a valid image file'</span>;
      <span class="hljs-built_in">this</span>.isValidFile = <span class="hljs-literal">false</span>;
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-keyword">const</span> reader = <span class="hljs-keyword">new</span> FileReader();
      reader.readAsDataURL(event.target.files[<span class="hljs-number">0</span>]);
      reader.onload = <span class="hljs-function">() =&gt;</span> {
        <span class="hljs-built_in">this</span>.imagePreview = reader.result;
      };
      <span class="hljs-built_in">this</span>.status = <span class="hljs-built_in">this</span>.DefaultStatus;
      <span class="hljs-built_in">this</span>.isValidFile = <span class="hljs-literal">true</span>;
    }
  }

  GetSudokuTable() {
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.isValidFile) {
      <span class="hljs-built_in">this</span>.loading = <span class="hljs-literal">true</span>;
      <span class="hljs-built_in">this</span>.imageData.append(<span class="hljs-string">'imageFile'</span>, <span class="hljs-built_in">this</span>.imageFile);

      <span class="hljs-built_in">this</span>.formRecognizerService
        .getSudokuTableFromImage(<span class="hljs-built_in">this</span>.imageData)
        .pipe(takeUntil(<span class="hljs-built_in">this</span>.unsubscribe$))
        .subscribe(
          <span class="hljs-function">(<span class="hljs-params">result: <span class="hljs-built_in">any</span></span>) =&gt;</span> {
            <span class="hljs-built_in">this</span>.game = result;
            <span class="hljs-built_in">this</span>.loading = <span class="hljs-literal">false</span>;
          },
          <span class="hljs-function">() =&gt;</span> {
            <span class="hljs-built_in">console</span>.error();
            <span class="hljs-built_in">this</span>.loading = <span class="hljs-literal">false</span>;
          }
        );
    }
  }

  SolveSudoku() {
    <span class="hljs-built_in">this</span>.sudokuSolver(<span class="hljs-built_in">this</span>.game);
  }

  ngOnDestroy() {
    <span class="hljs-built_in">this</span>.unsubscribe$.next();
    <span class="hljs-built_in">this</span>.unsubscribe$.complete();
  }

  <span class="hljs-keyword">private</span> sudokuSolver(data) {
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">9</span>; i++) {
      <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> j = <span class="hljs-number">0</span>; j &lt; <span class="hljs-number">9</span>; j++) {
        <span class="hljs-keyword">if</span> (data[i][j] == <span class="hljs-string">''</span>) {
          <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> k = <span class="hljs-number">1</span>; k &lt;= <span class="hljs-number">9</span>; k++) {
            <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.isSudokuValid(data, i, j, k)) {
              data[i][j] = <span class="hljs-string">`<span class="hljs-subst">${k}</span>`</span>;
              <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.sudokuSolver(data)) {
                <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
              } <span class="hljs-keyword">else</span> {
                data[i][j] = <span class="hljs-string">''</span>;
              }
            }
          }
          <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
        }
      }
    }
    <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
  }

  <span class="hljs-keyword">private</span> isSudokuValid(board, row, col, k) {
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">9</span>; i++) {
      <span class="hljs-keyword">const</span> m = <span class="hljs-number">3</span> * <span class="hljs-built_in">Math</span>.floor(row / <span class="hljs-number">3</span>) + <span class="hljs-built_in">Math</span>.floor(i / <span class="hljs-number">3</span>);
      <span class="hljs-keyword">const</span> n = <span class="hljs-number">3</span> * <span class="hljs-built_in">Math</span>.floor(col / <span class="hljs-number">3</span>) + (i % <span class="hljs-number">3</span>);
      <span class="hljs-keyword">if</span> (board[row][i] == k || board[i][col] == k || board[m][n] == k) {
        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
      }
    }
    <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
  }
}
</code></pre>
<p>We will inject the formRecognizerService in the constructor of the <code>HomeComponent</code> and set a message and the value for the max image size allowed inside the constructor. We will also initialize the two-dimensional array to hold the value of the sudoku.</p>
<p>The <code>uploadImage</code> method will be invoked upon uploading an image. We will check if the uploaded file is a valid image and is within the allowed size limit. We will process the image data using a FileReader object. The readAsDataURL method will read the contents of the uploaded file. </p>
<p>When the read operation completes successfully, the reader.onload event will be triggered. The value of imagePreview will be set to the result returned by the fileReader object, which is of type ArrayBuffer.</p>
<p>Inside the <code>GetSudokuTable</code> method, we will append the image file to a variable for type FormData. We will invoke the <code>getSudokuTableFromImage</code> of the service and bind the result to the game array.</p>
<p>The <code>sudokuSolver</code> method will accept the Sudoku board as a parameter. We will then solve the sudoku board with the help of the backtracking algorithm.</p>
<h2 id="heading-execution-demo">Execution Demo</h2>
<p>Press F5 to launch the application. Upload the image of a sudoku table. Click on the “Extract Sudoku Table” button. It will extract the content from the image and populate the table on the left side. Refer to the image shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/ExecDemo1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Click on the “Solve Sudoku” button. You can see the final result of the sudoku on the UI. Refer to the image shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/ExecDemo2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-summary"><strong>Summary</strong></h2>
<p>We have created a sudoku solver application using Angular and Azure form recognizer service. The application can extract the data from the image of a sudoku board uploaded by the user. We then implement backtracking to solve the sudoku. We have used Angular material for styling the app.</p>
<p>Get the Source code from <a target="_blank" href="https://github.com/AnkitSharma-007/Azure-AI-Sudoku-solver">GitHub</a> and play around to get a better understanding.</p>
<h2 id="heading-see-also">See Also</h2>
<ul>
<li><a target="_blank" href="https://ankitsharmablogs.com/optical-character-reader-using-angular-and-azure-computer-vision/">Optical Character Reader Using Angular And Azure Computer Vision</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/multi-language-translator-using-blazor-and-azure-cognitive-services/">Multi-Language Translator Using Blazor And Azure Cognitive Services</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/facebook-authentication-and-authorization-in-server-side-blazor-app/">Facebook Authentication And Authorization In Server-Side Blazor App</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/continuous-deployment-for-angular-app-using-heroku-and-github/">Continuous Deployment For Angular App Using Heroku And GitHub</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/going-serverless-with-blazor/">Going Serverless With Blazor</a></li>
</ul>
<p>If you like the article, please share it with your friends. You can also connect with me on <a target="_blank" href="https://twitter.com/ankitsharma_007">Twitter</a> and <a target="_blank" href="https://www.linkedin.com/in/ankitsharma-007/">LinkedIn</a>.</p>
<p>Originally published at <a target="_blank" href="https://ankitsharmablogs.com/">https://ankitsharmablogs.com/</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Common Logic Puzzles – The Knights and Knaves, Monty Hall, and Dining Philosophers Problems Explained ]]>
                </title>
                <description>
                    <![CDATA[ While not strictly related to programming, logic puzzles are a good warm up to your next coding session. You may encounter a logic puzzle in your next technical interview as a way to judge your problem solving skills, so it's worth being prepared. In... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/common-logic-puzzles-the-knights-and-knaves-monty-hall-and-dining-philosophers-problems-explained/</link>
                <guid isPermaLink="false">66c347a04f1fc448a3678fd0</guid>
                
                    <category>
                        <![CDATA[ logic ]]>
                    </category>
                
                    <category>
                        <![CDATA[ puzzles ]]>
                    </category>
                
                    <category>
                        <![CDATA[ toothbrush ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Sat, 01 Feb 2020 00:00:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9d11740569d1a4ca35b6.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>While not strictly related to programming, logic puzzles are a good warm up to your next coding session. You may encounter a logic puzzle in your next technical interview as a way to judge your problem solving skills, so it's worth being prepared.</p>
<p>In this article, we've collected a few famous logic puzzles and their solutions. Can you solve them without peeking at the answer?</p>
<h2 id="heading-knights-and-knaves">Knights and Knaves</h2>
<p>For this logic puzzle, imagine there are two types of people, knights and knaves. Knights only tell the truth, while Knaves only tell lies.</p>
<p>There are many variations of this puzzle, but most involve asking a question to figure out who is the knight and who is the knave.</p>
<h3 id="heading-red-and-blue">Red and Blue</h3>
<p>There are two people standing in front of you, Red and Blue. Blue says, "We are both knaves." Who is really the knight and who is the knave?</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/photo-1556549957-f41c6fcc4210-4.jpeg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><strong>Solution</strong><br>It's impossible for Blue to be the knight. If Blue was a knight, the statement, "We are both knaves," would actually be a lie. Therefore, Blue is a knave as his statement is a lie, and Red must be a knight.</p>
<h3 id="heading-two-paths">Two Paths</h3>
<p>You arrive at a fork in the road and need to choose the correct path that leads to your destination. There are two people standing at the fork, and you know that one must be a knight and the other must be a knave. </p>
<p>What single question could you ask to one of the people to determine the correct path, A or B?</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/photo-1519401706-5cf17f6e70de.jpeg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><strong>Solution</strong><br>The question you can ask either person is, "What path would the other person tell me is the correct one?" The answer will always be the wrong path to take, and you can safely take the other path.  </p>
<p>Imagine the correct path is A.   </p>
<p>If you ask directly, "Which is the correct path?" the knave will say B is correct while the knight will say A.  </p>
<p>However, when asked which path the <em>other</em> person would say is correct, the knave will lie and say that the knight would tell you path B is correct. Meanwhile, the knight will tell the truth about the knave's answer, and say that the knave will tell you that path B is the correct one.  </p>
<p>In both cases  you know that then answer, path B, is actually a lie, so you should take the other path.</p>
<h2 id="heading-the-monty-hall-problem">The Monty Hall Problem</h2>
<p>The Monty Hall Problem is a riddle on probability named after the host of the 70’s game show it’s based on, <em>Let’s Make a Deal</em>. This particular problem is a <a target="_blank" href="https://en.wikipedia.org/wiki/Paradox">veridical paradox</a>, which means that there is a solution that seems counter-intuitive, yet proven to be true.</p>
<p>Imagine you are on a game show and there are 3 doors, each with a different prize behind them. Behind one of the three doors is a car. Behind the other two doors there are goats. </p>
<p>You must choose one of the 3 doors to select as your prize. </p>
<p>Say you decide to open Door 1. The host, who knows where the car is, opens a different door, Door 2, which reveals a goat. He then asks if you would like to open Door 3 instead.</p>
<p>Should you choose Door 3 over your original choice? Does it even matter?</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/zachary-anderson-ceYJ1HKt9Rk-unsplash.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><strong>Solution</strong><br>It turns out that your choice really does matter, and it is actually to your benefit to choose Door 3 instead of Door 1. Here's why.</p>
<p>When you chose Door 1 from the 3 closed doors, you had a 1 out of 3 chance that you picked the right one. Both Door 2 and Door 3 also have a 1 out of the 3 chance of having a car behind it. </p>
<p>Another way to think about it is that Doors 2 and 3 have a 2 out of 3 chance of having a car behind it <em>combined</em>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/8EsVvZk-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>But when the host opens Door 2 and reveals the goat, you suddenly have more information about the problem.</p>
<p>Remember that Doors 2 and 3 have a combined probability hiding the car 2/3rds of the time. When Door 2 was opened you know that there was no car behind it.</p>
<p>But this reveal does not change the combined probability of the two doors. That’s the key takeaway here!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/V2JzAka-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Since you know that Door 2 has a 0/3 chance of hiding the car, you can now say that there's a 2/3 chance that the car is behind Door 3. Door 1 remains unchanged – there's only a 1/3 the car is behind it.</p>
<p>So if you decide to switch, you go from roughly a 33.33% chance to a 66.67% chance of finding the car. In other words, you are doubling your chances of success by opening Door 3 instead!</p>
<p>Yes, it is possible that Door 1 was hiding all along and host tricked you. That doesn’t matter. You are gambling by taking the deal, but you’re gambling smart. You should make the best decision with the information you’re given and let the dice roll. </p>
<p>In the long run, you'd perform better by switching than a contestant who decides to go with their first choice. Though it's not immediately obvious, the host is actually doing you a favor by offering you a better deal.</p>
<h2 id="heading-the-dining-philosophers-problem"><strong>The Dining Philosophers Problem</strong></h2>
<p>The dining philosophers problem is a classic example in computer science to illustrate issues with synchronization. It was originally created by Edsger Dijkstra in 1965, who presented it to his students as a handful of computers competing for access to shared tape drives.</p>
<p>Imagine five silent philosophers sitting around a table, each with a bowl of spaghetti. There are forks on the table between each pair of adjacent philosophers.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/at_the_table.png" alt="Image" width="600" height="400" loading="lazy">
<em>Image courtesy of <a target="_blank" href="http://adit.io/posts/2013-05-11-The-Dining-Philosophers-Problem-With-Ron-Swanson.html">adit.io</a>.</em></p>
<p>Each philosopher can only do one thing at a time: think and eat. However, a philosopher can only eat spaghetti when they have both the left and right forks. A fork can only be held by one philosopher at a time.</p>
<p>After a philosopher finishes eating, they need to put down both the left and right forks so they're available to the others. A philosopher can take a fork as soon as it's available, but can only start eating once they have both forks.</p>
<p>The philosophers are famous for their appetites – they can all eat endlessly and never get full. On top of that, the bowls of spaghetti magically replenish no matter how much is eaten.</p>
<p>The problem is, how can can you ensure that no philosopher will starve, and that they can continue eating and thinking forever?</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/mae-mu-Pvclb-iHHYY-unsplash.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-synchronization-and-deadlock">Synchronization and Deadlock</h3>
<p>In simple terms, the dining philosophers problem is an illustration of how synchronized access to a shared resource can result in creation of a deadlock situation.</p>
<p><strong>Synchronization</strong> is used to control concurrent access to a shared resource. This is necessary in any situation where multiple independent actors may be competing for the use of one resource like the forks. Since there is only one resource available, we use synchronization to prevent confusion and chaos.</p>
<p>A <strong>Deadlock</strong> is a system state where no progress is possible. This situation can occur when synchronization is enforced, and many processes end up waiting for a shared resource which is being held by some other process. Like with the philosophers who are either stuck eating or thinking, the processes just keep waiting and execute no further.</p>
<h3 id="heading-solutions">Solutions</h3>
<p>At first glance it appears like it would not be possible for a deadlock where all philosophers are stuck either eating or thinking. For example, pattern for each philosopher to follow might be:</p>
<blockquote>
<p>1: think until the left fork is available; when it is, pick it up;  </p>
<p>2: think until the right fork is available; when it is, pick it up;  </p>
<p>3: when both forks are held, eat for a fixed amount of time;  </p>
<p>4: then, put the right fork down;  </p>
<p>5: then, put the left fork down;  </p>
<p>6: repeat from the beginning.  </p>
<p>Source: <a target="_blank" href="https://en.wikipedia.org/wiki/Dining_philosophers_problem">Wikipedia</a></p>
</blockquote>
<p>There are many solutions possible to prevent deadlock. If we look closely, one problem in the algorithm above is that all philosophers have equal chance (have the same priority) of acquiring one fork. This prevents anyone from acquiring two forks and the whole system grinds to a halt.</p>
<p>Here are some possible solutions:</p>
<ol>
<li><strong>Priority</strong>: Some philosophers are assigned higher priority, so that the chance of acquiring both forks is increased.</li>
<li><strong>Preemption</strong> (Politeness): Philosophers relinquish the acquired fork without eating, in case the other fork is not available.</li>
<li><strong>Arbitration</strong>: A mediator allocates forks ensuring that two forks are given to one person, instead of one to many.</li>
</ol>
<p>Now that you know how to solve these logic puzzles, treat yourself to an endless bowl of spaghetti. You earned it.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
