<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Janne Mattila's blog : Application Development</title><link>http://blogs.msdn.com/jannemattila/archive/tags/Application+Development/default.aspx</link><description>Tags: Application Development</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Maximize the use of CPU with parallel extensions (+ some WPF stuff)</title><link>http://blogs.msdn.com/jannemattila/archive/2008/08/26/maximize-the-use-of-cpu-with-parallel-extensions-some-wpf-stuff.aspx</link><pubDate>Tue, 26 Aug 2008 22:03:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8898129</guid><dc:creator>jannemattila</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/jannemattila/comments/8898129.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jannemattila/commentrss.aspx?PostID=8898129</wfw:commentRss><description>&lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Since this is my &lt;u&gt;40th post to this blog&lt;/u&gt; I decided to go back to square one… or &lt;a href="http://blogs.msdn.com/jannemattila/archive/2007/01/07/solving-small-puzzles-with-just-a-few-lines-of-code.aspx" target="_blank"&gt;post one&lt;/a&gt; actually &lt;strong&gt;:-)&lt;/strong&gt; I’m going to create Windows Presentation Foundation (WPF) application that solves the &lt;a href="http://en.wikipedia.org/wiki/Knight%27s_tour" target="_blank"&gt;Knight’s Tour&lt;/a&gt; puzzle. I actually didn’t know about this puzzle before I bought book called &lt;a href="http://www.wrox.com/WileyCDA/WroxTitle/Puzzles-for-Programmers-and-Pros.productCd-0470121688.html" target="_blank"&gt;Puzzles for Programmers and Pros&lt;/a&gt;. That book had interesting puzzle that lead in to this post. So here we go!&lt;/p&gt;  &lt;p&gt;I said that I’m going to create WPF application for my UI. You might ask why not the “good old” Windows Forms application...? Well for these simple reasons:    &lt;br /&gt;    &lt;br /&gt;&lt;strong&gt;1.&lt;/strong&gt;&amp;#160; I don’t like to write code to &lt;em&gt;OnPaint&lt;/em&gt; / &lt;em&gt;MainForm_Paint&lt;/em&gt; methods.     &lt;br /&gt;&lt;strong&gt;2. &lt;/strong&gt;I wanted to define my user interface and then just say in code “hey knight go there” and it should just draw the UI with the knight in the correct position. But the defined UI must be also scalable.     &lt;br /&gt;&lt;strong&gt;3. &lt;/strong&gt;WPF doesn’t have same barriers than Windows Forms does =&amp;gt; It’s the face of future applications!     &lt;br /&gt;    &lt;br /&gt;I don’t probably have to explain my reason #1 for you if you have experienced the same that I have :-) You’ll end up writing the UI code a lot and that’s not what you’re trying to do. You’re trying to solve puzzle and you are suddenly focusing for the UI code. That’s wrong approach. Therefore reason #2 goes hand-in-hand with #1. &lt;/p&gt;  &lt;p&gt;So let’s look the the UI of the running application:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/jannemattila/WindowsLiveWriter/KnightsTourparallelism_CDDE/WPF%20UI_2.png"&gt;&lt;img title="WPF UI" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="306" alt="WPF UI" src="http://blogs.msdn.com/blogfiles/jannemattila/WindowsLiveWriter/KnightsTourparallelism_CDDE/WPF%20UI_thumb.png" width="306" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;It’s the view of the classic chess board and I decided to take shortcut when creating the knight. I decided to use gray circle instead (or ellipse actually) &lt;strong&gt;:-)&lt;/strong&gt; And for the layout management I just took the easy approach by using &lt;em&gt;Grid&lt;/em&gt; and defining &lt;em&gt;Columns&lt;/em&gt; and &lt;em&gt;Rows&lt;/em&gt;. Here is the XAML for the UI:&lt;/p&gt;  &lt;table cellspacing="10"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" align="right"&gt;         &lt;pre&gt;&lt;font color="gray"&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37&lt;/font&gt;&lt;/pre&gt;
      &lt;/td&gt;

      &lt;td valign="top"&gt;
        &lt;pre&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a31515"&gt;Window&lt;/font&gt;&lt;font color="#ff0000"&gt; x&lt;/font&gt;&lt;font color="#0000ff"&gt;:&lt;/font&gt;&lt;font color="#ff0000"&gt;Class&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;Window1&amp;quot;
&lt;/font&gt;  &lt;font color="#ff0000"&gt; xmlns&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;
&lt;/font&gt;  &lt;font color="#ff0000"&gt; xmlns&lt;/font&gt;&lt;font color="#0000ff"&gt;:&lt;/font&gt;&lt;font color="#ff0000"&gt;x&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;
&lt;/font&gt;  &lt;font color="#ff0000"&gt; Title&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;Knight's Tour&amp;quot;&lt;/font&gt;&lt;font color="#ff0000"&gt; MinHeight&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;100&amp;quot;&lt;/font&gt;&lt;font color="#ff0000"&gt; MinWidth&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;100&amp;quot;&lt;/font&gt; 
    &lt;font color="#ff0000"&gt; Width&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;300&amp;quot;&lt;/font&gt;&lt;font color="#ff0000"&gt; Height&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;300&amp;quot;&lt;/font&gt;&lt;font color="#ff0000"&gt; Loaded&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;Window_Loaded&amp;quot;&amp;gt;
&lt;/font&gt;&lt;font color="#a31515"&gt;  &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a31515"&gt;Grid&lt;/font&gt;&lt;font color="#ff0000"&gt; x&lt;/font&gt;&lt;font color="#0000ff"&gt;:&lt;/font&gt;&lt;font color="#ff0000"&gt;Name&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;Board&amp;quot;&amp;gt;
&lt;/font&gt;&lt;font color="#a31515"&gt;    
    &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a31515"&gt;Grid.ColumnDefinitions&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;
&lt;/font&gt;&lt;font color="#a31515"&gt;      &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a31515"&gt;ColumnDefinition&lt;/font&gt;&lt;font color="#0000ff"&gt; /&amp;gt;
&lt;/font&gt;&lt;font color="#a31515"&gt;      &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a31515"&gt;ColumnDefinition&lt;/font&gt;&lt;font color="#0000ff"&gt; /&amp;gt;
&lt;/font&gt;&lt;font color="#a31515"&gt;      &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a31515"&gt;ColumnDefinition&lt;/font&gt;&lt;font color="#0000ff"&gt; /&amp;gt;
&lt;/font&gt;&lt;font color="#a31515"&gt;      &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a31515"&gt;ColumnDefinition&lt;/font&gt;&lt;font color="#0000ff"&gt; /&amp;gt;
&lt;/font&gt;&lt;font color="#a31515"&gt;      &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a31515"&gt;ColumnDefinition&lt;/font&gt;&lt;font color="#0000ff"&gt; /&amp;gt;
&lt;/font&gt;&lt;font color="#a31515"&gt;      &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a31515"&gt;ColumnDefinition&lt;/font&gt;&lt;font color="#0000ff"&gt; /&amp;gt;
&lt;/font&gt;&lt;font color="#a31515"&gt;      &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a31515"&gt;ColumnDefinition&lt;/font&gt;&lt;font color="#0000ff"&gt; /&amp;gt;
&lt;/font&gt;&lt;font color="#a31515"&gt;      &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a31515"&gt;ColumnDefinition&lt;/font&gt;&lt;font color="#0000ff"&gt; /&amp;gt;
&lt;/font&gt;&lt;font color="#a31515"&gt;    &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#a31515"&gt;Grid.ColumnDefinitions&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;
&lt;/font&gt;&lt;font color="#a31515"&gt;    &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a31515"&gt;Grid.RowDefinitions&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;
&lt;/font&gt;&lt;font color="#a31515"&gt;      &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a31515"&gt;RowDefinition&lt;/font&gt;&lt;font color="#0000ff"&gt; /&amp;gt;
&lt;/font&gt;&lt;font color="#a31515"&gt;      &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a31515"&gt;RowDefinition&lt;/font&gt;&lt;font color="#0000ff"&gt; /&amp;gt;
&lt;/font&gt;&lt;font color="#a31515"&gt;      &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a31515"&gt;RowDefinition&lt;/font&gt;&lt;font color="#0000ff"&gt; /&amp;gt;
&lt;/font&gt;&lt;font color="#a31515"&gt;      &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a31515"&gt;RowDefinition&lt;/font&gt;&lt;font color="#0000ff"&gt; /&amp;gt;
&lt;/font&gt;&lt;font color="#a31515"&gt;      &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a31515"&gt;RowDefinition&lt;/font&gt;&lt;font color="#0000ff"&gt; /&amp;gt;
&lt;/font&gt;&lt;font color="#a31515"&gt;      &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a31515"&gt;RowDefinition&lt;/font&gt;&lt;font color="#0000ff"&gt; /&amp;gt;
&lt;/font&gt;&lt;font color="#a31515"&gt;      &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a31515"&gt;RowDefinition&lt;/font&gt;&lt;font color="#0000ff"&gt; /&amp;gt;
&lt;/font&gt;&lt;font color="#a31515"&gt;      &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a31515"&gt;RowDefinition&lt;/font&gt;&lt;font color="#0000ff"&gt; /&amp;gt;
&lt;/font&gt;&lt;font color="#a31515"&gt;    &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#a31515"&gt;Grid.RowDefinitions&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;

&lt;/font&gt;&lt;font color="#a31515"&gt;    &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a31515"&gt;Ellipse&lt;/font&gt;&lt;font color="#ff0000"&gt; x&lt;/font&gt;&lt;font color="#0000ff"&gt;:&lt;/font&gt;&lt;font color="#ff0000"&gt;Name&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;Knight&amp;quot;&lt;/font&gt;&lt;font color="#ff0000"&gt; Fill&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;Gray&amp;quot;&lt;/font&gt;&lt;font color="#ff0000"&gt; Panel.ZIndex&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;1&amp;quot;
&lt;/font&gt;        &lt;font color="#ff0000"&gt; Grid.Column&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;{&lt;/font&gt;&lt;font color="#a31515"&gt;Binding&lt;/font&gt;&lt;font color="#ff0000"&gt; Path&lt;/font&gt;&lt;font color="#0000ff"&gt;=KnightX}&amp;quot;&lt;/font&gt; 
        &lt;font color="#ff0000"&gt; Grid.Row&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;{&lt;/font&gt;&lt;font color="#a31515"&gt;Binding&lt;/font&gt;&lt;font color="#ff0000"&gt; Path&lt;/font&gt;&lt;font color="#0000ff"&gt;=KnightY}&amp;quot; /&amp;gt;
&lt;/font&gt;&lt;font color="#a31515"&gt;    
    &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a31515"&gt;Rectangle&lt;/font&gt;&lt;font color="#ff0000"&gt; x&lt;/font&gt;&lt;font color="#0000ff"&gt;:&lt;/font&gt;&lt;font color="#ff0000"&gt;Name&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;A8&amp;quot;&lt;/font&gt;&lt;font color="#ff0000"&gt; Fill&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;White&amp;quot; /&amp;gt;
&lt;/font&gt;&lt;font color="#a31515"&gt;    &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a31515"&gt;Rectangle&lt;/font&gt;&lt;font color="#ff0000"&gt; x&lt;/font&gt;&lt;font color="#0000ff"&gt;:&lt;/font&gt;&lt;font color="#ff0000"&gt;Name&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;B8&amp;quot;&lt;/font&gt;&lt;font color="#ff0000"&gt; Grid.Column&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;1&amp;quot; /&amp;gt;
&lt;/font&gt;&lt;font color="#a31515"&gt;    &lt;/font&gt;&lt;font color="#008000"&gt;&amp;lt;!-- Etc... --&amp;gt;
&lt;/font&gt;&lt;font color="#a31515"&gt;  &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#a31515"&gt;Grid&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;
&amp;lt;/&lt;/font&gt;&lt;font color="#a31515"&gt;Window&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/pre&gt;
      &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;You probably noticed the interesting part of the XAML... and that’s the lines 30 and 31 where &lt;em&gt;Binding &lt;/em&gt;is defined. It means that these values coming from the public properties of the &lt;em&gt;DataContext&lt;/em&gt;. So let’s look at the code behind that XAML and let’s discuss the binding little bit more: 

  &lt;table cellspacing="10"&gt;&lt;tbody&gt;
      &lt;tr&gt;
        &lt;td valign="top" align="right"&gt;
          &lt;pre&gt;&lt;font color="gray"&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48&lt;/font&gt;&lt;/pre&gt;
        &lt;/td&gt;

        &lt;td valign="top"&gt;
          &lt;pre&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt; System;
&lt;font color="#0000ff"&gt;using&lt;/font&gt; System.ComponentModel;
&lt;font color="#0000ff"&gt;using&lt;/font&gt; System.Diagnostics;
&lt;font color="#0000ff"&gt;using&lt;/font&gt; System.Windows;
&lt;font color="#0000ff"&gt;using&lt;/font&gt; System.Windows.Media;
&lt;font color="#0000ff"&gt;using&lt;/font&gt; System.Windows.Shapes;

&lt;font color="#0000ff"&gt;public&lt;/font&gt; &lt;font color="#0000ff"&gt;partial&lt;/font&gt; &lt;font color="#0000ff"&gt;class&lt;/font&gt; &lt;font color="#2b91af"&gt;Window1&lt;/font&gt; : &lt;font color="#2b91af"&gt;Window&lt;/font&gt;, &lt;font color="#2b91af"&gt;INotifyPropertyChanged
&lt;/font&gt;{
  &lt;font color="#0000ff"&gt;private&lt;/font&gt; &lt;font color="#0000ff"&gt;int&lt;/font&gt; knightX = 0;
  &lt;font color="#0000ff"&gt;public&lt;/font&gt; &lt;font color="#0000ff"&gt;int&lt;/font&gt; KnightX
  {
    &lt;font color="#0000ff"&gt;get&lt;/font&gt; { &lt;font color="#0000ff"&gt;return&lt;/font&gt; knightX; }
    &lt;font color="#0000ff"&gt;set
&lt;/font&gt;    {
      knightX = &lt;font color="#0000ff"&gt;value&lt;/font&gt;;
      NotifyPropertyChanged(&lt;font color="#a31515"&gt;&amp;quot;KnightX&amp;quot;&lt;/font&gt;);
    }
  }

  &lt;font color="#0000ff"&gt;private&lt;/font&gt; &lt;font color="#0000ff"&gt;int&lt;/font&gt; knightY = 0;
  &lt;font color="#0000ff"&gt;public&lt;/font&gt; &lt;font color="#0000ff"&gt;int&lt;/font&gt; KnightY
  {
    &lt;font color="#0000ff"&gt;get&lt;/font&gt; { &lt;font color="#0000ff"&gt;return&lt;/font&gt; knightY; }
    &lt;font color="#0000ff"&gt;set
&lt;/font&gt;    {
      knightY = &lt;font color="#0000ff"&gt;value&lt;/font&gt;;
      NotifyPropertyChanged(&lt;font color="#a31515"&gt;&amp;quot;KnightY&amp;quot;&lt;/font&gt;);
    }
  }

  &lt;font color="#0000ff"&gt;private&lt;/font&gt; &lt;font color="#0000ff"&gt;void&lt;/font&gt; Window_Loaded(&lt;font color="#0000ff"&gt;object&lt;/font&gt; sender, &lt;font color="#2b91af"&gt;RoutedEventArgs&lt;/font&gt; e)
  {
    Knight.DataContext = &lt;font color="#0000ff"&gt;this&lt;/font&gt;;
    &lt;font color="#008000"&gt;// Now moving the Knight is easy!
&lt;/font&gt;    KnightX = 3;
    KnightY = 3;
  }

  &lt;font color="#0000ff"&gt;public&lt;/font&gt; &lt;font color="#0000ff"&gt;event&lt;/font&gt; &lt;font color="#2b91af"&gt;PropertyChangedEventHandler&lt;/font&gt; PropertyChanged;
  &lt;font color="#0000ff"&gt;private&lt;/font&gt; &lt;font color="#0000ff"&gt;void&lt;/font&gt; NotifyPropertyChanged(&lt;font color="#2b91af"&gt;String&lt;/font&gt; info)
  {
    &lt;font color="#0000ff"&gt;if&lt;/font&gt; (PropertyChanged != &lt;font color="#0000ff"&gt;null&lt;/font&gt;)
    {
      PropertyChanged(&lt;font color="#0000ff"&gt;this&lt;/font&gt;, &lt;font color="#0000ff"&gt;new&lt;/font&gt; &lt;font color="#2b91af"&gt;PropertyChangedEventArgs&lt;/font&gt;(info));
    }
  }
  &lt;font color="#008000"&gt;//...&lt;/font&gt;&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;&lt;/table&gt;
You might already noticed that my window also implements &lt;em&gt;INotyfyPropertyChanged&lt;/em&gt; interface. And my two properties actually call &lt;em&gt;NotifyPropertyChanged&lt;/em&gt; method when they are changed. So what’s this all about? Well if you don’t do this your values will be updated for the first time and after that they don’t actually get “bubbled” up to the ellipse anymore... unless you implement the notify mechanisms yourself. This is quite important and you should probably read more information about it on MSDN. &lt;/p&gt;

&lt;p&gt;For the actual solving part I just used classic “old recursion” to solve the puzzle. And this is the part where we finally are going to the &lt;em&gt;title&lt;/em&gt; of my post... &lt;/p&gt;

&lt;p&gt;Classic one worker thread approach gives “fairly easy to implement but sub-optimal” solution. And you might ask why? And to answer this question I’m going so show you picture of task manager: 
  &lt;br /&gt;&lt;a href="http://blogs.msdn.com/blogfiles/jannemattila/WindowsLiveWriter/KnightsTourparallelism_CDDE/CPU1_2.png"&gt;&lt;img title="CPU1" height="116" alt="CPU1" src="http://blogs.msdn.com/blogfiles/jannemattila/WindowsLiveWriter/KnightsTourparallelism_CDDE/CPU1_thumb.png" width="654" border="0" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;This picture was taken when my solver was running in “full speed ahead” –mode. And guess what... &lt;u&gt;I’m not impressed&lt;/u&gt;! I’m actually just using single CPU (see the third box where green line has reached the roof)!!! So my worker thread approach is far from optimal resource usage.&lt;/p&gt;

&lt;p&gt;Okay... What can I do then? I could do multiple threads and handle them manually but that’s again writing a lot of code that doesn’t have anything to do with the actual solving!? So if I would chosen Windows Forms + manual handling of multiple threads I would have a lot of code and just small fraction of that would actually do work that I was originally planning to do. &lt;/p&gt;

&lt;p&gt;This is where &lt;a href="http://blogs.msdn.com/pfxteam/" target="_blank"&gt;&lt;em&gt;Parallel Extensions&lt;/em&gt;&lt;/a&gt;&lt;em&gt; &lt;/em&gt;(&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=348F73FD-593D-4B3C-B055-694C50D2B0F3&amp;amp;displaylang=en" target="_blank"&gt;download&lt;/a&gt;)&lt;em&gt; &lt;/em&gt;comes into the game! It’s additional library (&lt;em&gt;System.Threading.dll&lt;/em&gt;) sitting on top of .NET Framework 3.5 and it’s currently in CTP phase. But I still highly recommend you to check it out if you want easily get more horse power to your algorithms. &lt;/p&gt;

&lt;p&gt;I analyzed my code and noticed part where I could do things differently: 
  &lt;table cellspacing="10"&gt;&lt;tbody&gt;
      &lt;tr&gt;
        &lt;td valign="top" align="right"&gt;
          &lt;pre&gt;&lt;font color="gray"&gt;1
2
3
4
5
6
7
8
9
10
11
&lt;/font&gt;&lt;/pre&gt;
        &lt;/td&gt;

        &lt;td valign="top"&gt;
          &lt;pre&gt;&lt;font color="#008000"&gt;// My code was this:
&lt;/font&gt;&lt;font color="#0000ff"&gt;foreach&lt;/font&gt; (&lt;font color="#0000ff"&gt;int&lt;/font&gt; location &lt;font color="#0000ff"&gt;in&lt;/font&gt; startLocations)
{
  &lt;font color="#008000"&gt;// Calculations here!
&lt;/font&gt;}

&lt;font color="#008000"&gt;// And I changed it to this:
&lt;/font&gt;&lt;font color="#2b91af"&gt;Parallel&lt;/font&gt;.ForEach&amp;lt;&lt;font color="#0000ff"&gt;int&lt;/font&gt;&amp;gt;(startLocations, (location) =&amp;gt;
{
  &lt;font color="#008000"&gt;// Calculations here!
&lt;/font&gt;});&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;&lt;/table&gt;

  &lt;br /&gt;So I changed code in line 2 to be the code at line 8. What was the result at the task manager then: 

  &lt;br /&gt;&lt;a href="http://blogs.msdn.com/blogfiles/jannemattila/WindowsLiveWriter/KnightsTourparallelism_CDDE/CPU2_2.png"&gt;&lt;img title="CPU2" height="111" alt="CPU2" src="http://blogs.msdn.com/blogfiles/jannemattila/WindowsLiveWriter/KnightsTourparallelism_CDDE/CPU2_thumb.png" width="650" border="0" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Well I believe that I managed to get better use of the available horse power &lt;strong&gt;:-)&lt;/strong&gt; It shows of course in the results: 

  &lt;br /&gt;“foreach”: ~50 solved solutions in ~5 minutes 

  &lt;br /&gt;”Parallel.ForEach”: ~450 solved solutions in &amp;lt; 5 minutes&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;To summarize... &lt;/strong&gt;&lt;u&gt;I just changed 1 line of code and I was able to get unbelievable results from it!&lt;/u&gt; So if you’re doing something similar then I recommend checking out the parallel extensions first before doing “own custom solution” for that. &lt;/p&gt;

&lt;p&gt;I originally thought that I would go little bit deeper into the details of my solver but this post ended up too long even without it so maybe I’ll pass this time... But I’ll include &lt;a href="http://blogs.msdn.com/jannemattila/attachment/8898129.ashx" target="_blank"&gt;video clip&lt;/a&gt; that shows the UI of the application when it’s solving.

  &lt;br /&gt;

  &lt;br /&gt;Anyways... Happy hacking! 

  &lt;br /&gt;

  &lt;br /&gt;J&lt;/p&gt;

&lt;p&gt;P.S. I’m also interested in F# and I’m probably going to do something fun with that too.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8898129" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/jannemattila/attachment/8898129.ashx" length="18623" type="video/x-ms-wmv" /><category domain="http://blogs.msdn.com/jannemattila/archive/tags/.NET+General/default.aspx">.NET General</category><category domain="http://blogs.msdn.com/jannemattila/archive/tags/Application+Development/default.aspx">Application Development</category><category domain="http://blogs.msdn.com/jannemattila/archive/tags/tips+and+tricks/default.aspx">tips and tricks</category><category domain="http://blogs.msdn.com/jannemattila/archive/tags/Programming/default.aspx">Programming</category></item><item><title>CRM 4.0 (or SharePoint or custom application) and DebugView</title><link>http://blogs.msdn.com/jannemattila/archive/2008/05/07/crm-4-0-or-sharepoint-or-custom-application-and-debugview.aspx</link><pubDate>Wed, 07 May 2008 10:04:03 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8465208</guid><dc:creator>jannemattila</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/jannemattila/comments/8465208.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jannemattila/commentrss.aspx?PostID=8465208</wfw:commentRss><description>&lt;p&gt;Every now and then I’m find myself trying to solve same issues over and over again :-) That’s why I found myself (again) using &lt;em&gt;DebugView&lt;/em&gt; as my debugging assistant at remote box. If you don’t know what &lt;em&gt;DebugView&lt;/em&gt; is then you should definitely try it out. I’m going to give you few ideas how you could use it at your applications. You can download the &lt;em&gt;DebugView&lt;/em&gt; from &lt;a title="DebugView download" href="http://technet.microsoft.com/en-us/sysinternals/bb896647.aspx" target="_blank"&gt;Technet&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Why do I use &lt;em&gt;DebugView&lt;/em&gt;? Well I want to get debug messages from running system BUT... I don’t want to write to EventLog or to File since it’s totally unnecessary to write all the messages all the time. I just want messages when I’m ready to observe the system. And DebugView is handy tool for that. Here is list of steps how I normally implement that kind of approach:&lt;br&gt;1) Create log class that implements logging/tracing/debugging (this is pretty much just wrapper to few simple method calls) (I recommend making this as singleton)&lt;br&gt;2) Use you log class in your application/solution&lt;br&gt;3) Use &lt;em&gt;DebugView &lt;/em&gt;to follow the trace messages written by your log class&lt;/p&gt; &lt;p&gt;In 1) I mention that I recommend using singleton approach at the log class. This is important especially at the CRM 4.0 where you need to add default trace listener so that you’ll get the trace messages. Here is the code example for that:&lt;/p&gt; &lt;p&gt; &lt;table cellspacing="10"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td valign="top" align="right"&gt;&lt;pre&gt;&lt;font color="gray"&gt;1
2
3&lt;/font&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td valign="top"&gt;&lt;pre&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt; System.Diagnostics;
&lt;font color="#008000"&gt;// ...
&lt;/font&gt;&lt;font color="#2b91af"&gt;Trace&lt;/font&gt;.Listeners.Add(&lt;font color="#0000ff"&gt;new&lt;/font&gt; &lt;font color="#2b91af"&gt;DefaultTraceListener&lt;/font&gt;());&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;
&lt;p&gt;After you have added the default listener you can just use this oneliner:&lt;/p&gt;
&lt;p&gt;
&lt;table cellspacing="10"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td valign="top" align="right"&gt;&lt;pre&gt;&lt;font color="gray"&gt;1&lt;/font&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td valign="top"&gt;&lt;pre&gt;&lt;font color="#2b91af"&gt;Trace&lt;/font&gt;.WriteLine(&lt;font color="#a31515"&gt;"My Trace: "&lt;/font&gt; + message);&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;
&lt;p&gt;Now your trace can be seen at the &lt;em&gt;DebugView&lt;/em&gt;:&lt;br&gt;&lt;img border="0" alt="DebugView" src="http://blogs.msdn.com/blogfiles/jannemattila/WindowsLiveWriter/CRM4.0andDebugView_60C3/DebugView_c8bc2cb2-c36a-463a-9b14-168b4e41f642.png" width="470" height="243"&gt;&lt;br&gt;(here is CRM 4.0 where I have menu item that points to custom ASPX page and I’m using “My Trace” to see what’s happening in there)&lt;/p&gt;
&lt;p&gt;&lt;em&gt;DebugView&lt;/em&gt; has many built-in functionalities like “Save As” etc. that can help you on your debug/trace efforts. So I recommend that you learn to play around with it.&lt;/p&gt;
&lt;p&gt;I also had the magic word “SharePoint” in my title. That is for the simple reason that this same story applies to SharePoint too. And don’t forget... Since &lt;em&gt;System.Diagnostics.Trace&lt;/em&gt; is implemented at the .NET Framework this story also applies to all other applications which are built on top of that.&lt;/p&gt;
&lt;p&gt;You might also want to read my previous post about tracing: &lt;a title="CRM 4.0, SharePoint and ASP.NET Trace" href="http://blogs.msdn.com/jannemattila/archive/2008/02/23/crm-4-0-sharepoint-and-asp-net-trace.aspx" target="_blank"&gt;CRM 4.0, SharePoint and ASP.NET Trace&lt;/a&gt;.&lt;br&gt;&lt;br&gt;Anyways... Happy hacking!&lt;br&gt;&lt;br&gt;J&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8465208" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jannemattila/archive/tags/Application+Development/default.aspx">Application Development</category><category domain="http://blogs.msdn.com/jannemattila/archive/tags/Microsoft+Office+SharePoint+Server+2007/default.aspx">Microsoft Office SharePoint Server 2007</category><category domain="http://blogs.msdn.com/jannemattila/archive/tags/tips+and+tricks/default.aspx">tips and tricks</category><category domain="http://blogs.msdn.com/jannemattila/archive/tags/Programming/default.aspx">Programming</category><category domain="http://blogs.msdn.com/jannemattila/archive/tags/Microsoft+CRM/default.aspx">Microsoft CRM</category></item><item><title>How to install Windows SharePoint Services 3.0 Tools to XP or Vista</title><link>http://blogs.msdn.com/jannemattila/archive/2007/08/16/how-to-install-windows-sharepoint-services-3-0-tools-to-xp-or-vista.aspx</link><pubDate>Thu, 16 Aug 2007 06:42:24 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4409644</guid><dc:creator>jannemattila</dc:creator><slash:comments>84</slash:comments><comments>http://blogs.msdn.com/jannemattila/comments/4409644.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jannemattila/commentrss.aspx?PostID=4409644</wfw:commentRss><description>&lt;p&gt;I got email from Philip Edney with a hint that how you can install &lt;em&gt;&lt;a title="VSeWSS download" href="http://www.microsoft.com/downloads/details.aspx?familyid=19f21e5e-b715-4f0c-b959-8c6dcbdc1057&amp;amp;displaylang=en" target="_blank"&gt;Windows SharePoint Services 3.0 Tools: Visual Studio 2005 Extensions (VSeWSS)&lt;/a&gt;&amp;nbsp; &lt;/em&gt;for none-Windows 2003 server OS. Of course since that's &lt;strong&gt;not supported &lt;/strong&gt;you'll have to do small registry hack (but that's what developers do&amp;nbsp;:-):&lt;/p&gt; &lt;p&gt;[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\12.0] &lt;br&gt;"Sharepoint"="Installed"  &lt;p&gt;I just tested it with Windows Vista and it works! Before the hack it gives me "&lt;em&gt;This product can be installed if Windows SharePoint Services 3.0 has been installed first.&lt;/em&gt;" and after the hack it went fine. I think there're a lot of people who would like to&amp;nbsp;try/use this&amp;nbsp;option even if they fall for unsupported mode.  &lt;p&gt;But thanks to Phil to let me know about that possibility! &lt;strong&gt;Update:&lt;/strong&gt; Phil mentioned that he actually got the information from Raju Sakthivel so the credits chain just goes on and on :-)&lt;br&gt;&lt;br&gt;Anyways... Happy hacking!&lt;br&gt;&lt;br&gt;J&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4409644" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jannemattila/archive/tags/Application+Development/default.aspx">Application Development</category><category domain="http://blogs.msdn.com/jannemattila/archive/tags/Microsoft+Office+SharePoint+Server+2007/default.aspx">Microsoft Office SharePoint Server 2007</category><category domain="http://blogs.msdn.com/jannemattila/archive/tags/tips+and+tricks/default.aspx">tips and tricks</category></item><item><title>Solving small puzzles (with just a few lines of code)</title><link>http://blogs.msdn.com/jannemattila/archive/2007/01/07/solving-small-puzzles-with-just-a-few-lines-of-code.aspx</link><pubDate>Sun, 07 Jan 2007 15:42:34 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1428489</guid><dc:creator>jannemattila</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/jannemattila/comments/1428489.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jannemattila/commentrss.aspx?PostID=1428489</wfw:commentRss><description>&lt;p&gt;For my first blog post I decided to choose subject that is just really me: Solving small puzzles. It's one of my weird hobbies that requires a bit of understanding of the puzzle and of course some programming skills. I have used this same idea that I'm going to present here to many puzzles.&lt;/p&gt; &lt;h3&gt;Background of the puzzle: Survo&lt;/h3&gt; &lt;p&gt;Survo puzzle&amp;nbsp;is invention of Seppo Mustonen. He invented Survo puzzles in 2006, so it's quite new. Idea of Survo puzzle is similar to Sudoku. You need to add numbers to the puzzle so that row and column sums are same as given values. Biggest difference to Sudoku is the number of solutions. In Survo puzzle there will be only one possible solution. Puzzles are created so that solution is unique. As opposite to the Sudoku that might not be the case. Also numbers that are used to solve the case isn't limited to 1 to 9. Board size isn't fixed to some predefined size like in Sudoku and it's typically something like 3x3, 4x3 10x2 or 6x6. All this will make sense when we look at the example. More background can be find from &lt;a title="Survo puzzles" href="http://www.survo.fi/puzzles/index.html" target="_blank"&gt;Survo puzzle homepages&lt;/a&gt;&amp;nbsp;or from &lt;a title="Survo puzzles paper" href="http://www.survo.fi/papers/puzzles.pdf" target="_blank"&gt;paper&lt;/a&gt; written by Seppo Mustonen. It also worth mentioning that they give&amp;nbsp;degree of the difficulty for the puzzle. Really easy puzzles are something&amp;nbsp;around 1 to 10&amp;nbsp;and the most challenging Survo puzzle is 17000 (which is also known as the beast).&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Important note: &lt;/strong&gt;All Survo puzzles used in this page are taken from the &lt;a title="Survo puzzles" href="http://www.survo.fi/puzzles/index.html" target="_blank"&gt;Survo puzzle homepages&lt;/a&gt;&amp;nbsp;or from published places such as &lt;a title="Helsingin yliopiston tiedelehti" href="http://www.helsinki.fi/yliopistolehti/2006/13/survotehtava.htm" target="_blank"&gt;Helsingin yliopiston tiedelehti (=Science magazine of Helsinki University)&lt;/a&gt;.&lt;/p&gt; &lt;h3&gt;First example of Survo puzzle&lt;/h3&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/jannemattila/WindowsLiveWriter/Solvingsmallpuzzleswithjustafewlinesofco_131E6/SurvoEasy310.jpg" target="_new" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; margin: 0px 5px 5px 0px; border-right-width: 0px" height="196" src="http://blogs.msdn.com/blogfiles/jannemattila/WindowsLiveWriter/Solvingsmallpuzzleswithjustafewlinesofco_131E6/SurvoEasy3_thumb8.jpg" width="291" align="left" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Here is our first Survo puzzle (already inside my application :). For now let's concentrate only to the grid where is many empty slots and few given numbers. We can see that this puzzle is 4x3 and puzzle has 3 extra numbers given already. Idea is to fill those white slots with numbers 1 to 12 (which comes from 4x3). And numbers 3, 6 and 8 are already given to the grid. So there is still available 1, 2, 4, 5, 7, 9, 10, 11 and 12 (=9 numbers). Those numbers should be put to white slots so that each row and column sum matches the values given in the gray slots. Ex. On column 1 you could put 10-8-9 (8 was already given) which satisfies the rule 27. But in order to those be good selections you need to still be able to satisfy the row restrictions too: 30, 18 and 30. &lt;/p&gt; &lt;p&gt;Normally people use paper and pen to solve these kind of problems, but I don't like that :) I prefer creating program that does the dirty work for me. And this kind of problems are typically solved with &lt;a href="http://en.wikipedia.org/wiki/Brute-force_search"&gt;Brute force&lt;/a&gt;&amp;nbsp;/ &lt;a href="http://en.wikipedia.org/wiki/Game_theory"&gt;Game theory&lt;/a&gt;&amp;nbsp;or whatever you want to&amp;nbsp;call it. The idea is anyway to go through every possible configuration at the board, but use some kind of knowledge of the game to rule out bad configurations or selections away. And why do we want to do that? Well just because it would take a lot of time to go through all the possible combinations. In this example case it would be something like &lt;em&gt;9! = 362880&lt;/em&gt; combinations. Since our example puzzle is really simple (degree of difficulty isn't know for this example) we don't need to create super &lt;a href="http://en.wikipedia.org/wiki/Algorithm"&gt;Algorithm&lt;/a&gt;&amp;nbsp;to solve that. But when board size grows and is something like 5x5 it's totally a different case: &lt;em&gt;25! = 1.55 * 10^25&lt;/em&gt;. That kind of puzzle takes a long time to solve if you go through every possible combination without any optimizations that would rule out unfit solutions. Next I'm going to tell you how I started solving this problem.&lt;/p&gt; &lt;h3&gt;Creating the Survo Puzzle Solver&lt;/h3&gt; &lt;p&gt;I started working on my Survo Puzzle Solver with Visual Studio 2005 and C#. As you can see from the UI of the application -&amp;gt;&amp;nbsp;I'm not UI Designer :) I just created minimal set of buttons and grid that displays the current situation on the board. Then I created first version of my &lt;a href="http://en.wikipedia.org/wiki/Algorithm"&gt;Algorithm&lt;/a&gt;. Here it is in &lt;a href="http://en.wikipedia.org/wiki/Pseudocode"&gt;Pseudocode&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;&amp;lt;solver_code1&amp;gt;&lt;br&gt;&lt;code&gt;&amp;nbsp;1: Bool Solve&lt;br&gt;&amp;nbsp;2: {&lt;br&gt;&amp;nbsp;3: &amp;nbsp; If ( board is full)&lt;br&gt;&amp;nbsp;4: &amp;nbsp; {&lt;br&gt;&amp;nbsp;5: &amp;nbsp;&amp;nbsp;&amp;nbsp; // Evaluate returns true if solution is found&lt;br&gt;&amp;nbsp;6: &amp;nbsp;&amp;nbsp;&amp;nbsp; // or false if solution isn't correct one.&lt;br&gt;&amp;nbsp;7: &amp;nbsp;&amp;nbsp;&amp;nbsp; return Evaluate();&lt;br&gt;&amp;nbsp;8: &amp;nbsp; }&lt;br&gt;&amp;nbsp;9: &amp;nbsp; Foreach(location in board)&lt;br&gt;10: &amp;nbsp; {&lt;br&gt;11: &amp;nbsp;&amp;nbsp;&amp;nbsp; If (location is free)&lt;br&gt;12: &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;13: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Foreach(choice from available choices)&lt;br&gt;14: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;15: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; addChoiceToBoard(choice);&lt;br&gt;16: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If (Solve())&lt;br&gt;17: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;18: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // We have solution for this puzzle!&lt;br&gt;19: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;20: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; removeChoiceFromBoard(choice);&lt;br&gt;21: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;22: &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;23: &amp;nbsp; }&lt;br&gt;24: }&lt;br&gt;&lt;/code&gt;&amp;lt;/solver_code1&amp;gt;&lt;/p&gt; &lt;p&gt;So you can easily see that our code&amp;nbsp;uses &lt;a href="http://en.wikipedia.org/wiki/Recursion"&gt;Recursion&lt;/a&gt;. It means that it calls itself (line 16). S&lt;em&gt;olver code 1&amp;nbsp;&lt;/em&gt; inserts available numbers to the board slots that are free and when it notices that board is full (line 3) it validates the solutions (line 7). If &lt;em&gt;Evaluate&lt;/em&gt; method returns true our solution has been found:&lt;br&gt;&lt;a href="http://blogs.msdn.com/blogfiles/jannemattila/WindowsLiveWriter/Solvingsmallpuzzleswithjustafewlinesofco_131E6/SurvoEasy14.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="196" src="http://blogs.msdn.com/blogfiles/jannemattila/WindowsLiveWriter/Solvingsmallpuzzleswithjustafewlinesofco_131E6/SurvoEasy1_thumb2.jpg" width="291" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This &lt;em&gt;solver code 1&lt;/em&gt; clearly solves the problem... right? It does, but not completely. This approach has a lot to improve. I call this &lt;em&gt;phase 1: Code the functionality without any optimization&lt;/em&gt;. We have now solution that works, but it's simply isn't usable for a bit harder puzzles. It just takes too long time to get the solution. So now it's time to analyze our solution little bit and try to optimize it to be more robust. If you run that kind of code you would see that it would fill entire board and then validate the correctness of the solution (see&amp;nbsp;image below which is taken during the solving process):&lt;a href="http://blogs.msdn.com/blogfiles/jannemattila/WindowsLiveWriter/Solvingsmallpuzzleswithjustafewlinesofco_131E6/SurvoEasy43.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; margin: 5px 5px 5px 0px; border-right-width: 0px" height="193" src="http://blogs.msdn.com/blogfiles/jannemattila/WindowsLiveWriter/Solvingsmallpuzzleswithjustafewlinesofco_131E6/SurvoEasy4_thumb1.jpg" width="286" align="left" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;And you can see right away that it isn't correct because the first row doesn't pass the check: 1 + 6 + 2 + 4 = 30. If that part doesn't match then why have we continued with search under it? It's even more noticeable from treelike presentation (click images to see them original size)(Note: Now you know that I can't even draw&amp;nbsp;:). &lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/jannemattila/WindowsLiveWriter/Solvingsmallpuzzleswithjustafewlinesofco_131E6/tree7.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="79" src="http://blogs.msdn.com/blogfiles/jannemattila/WindowsLiveWriter/Solvingsmallpuzzleswithjustafewlinesofco_131E6/tree_thumb5.jpg" width="240" border="0"&gt;&lt;/a&gt;&lt;br&gt;&lt;em&gt;Full tree search &lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/jannemattila/WindowsLiveWriter/Solvingsmallpuzzleswithjustafewlinesofco_131E6/tree_marked5.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="78" src="http://blogs.msdn.com/blogfiles/jannemattila/WindowsLiveWriter/Solvingsmallpuzzleswithjustafewlinesofco_131E6/tree_marked_thumb3.jpg" width="240" border="0"&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;br&gt;&lt;em&gt;Optimized search tree&lt;/em&gt;&lt;/p&gt; &lt;p&gt;In the first tree every single node of the tree needs to be tested before we know the answer. &lt;em&gt;Optimized search tree&lt;/em&gt; shows black nodes that indicates that this subtree can be ignored entirely. So red nodes are the ones that won't even be tested and we still know that the solution can be found from the rest of the nodes! So from this we can go to our next phase. Let's call it &lt;em&gt;phase 2: Simple optimization&lt;/em&gt;. &lt;/p&gt; &lt;p&gt;We don't need to modify our code much in order to make simple optimization. Let's add check each time when the row is filled. This one is pretty simple to implement and improves performance quite a lot:&lt;/p&gt; &lt;p&gt;&amp;lt;solver_code2&amp;gt;&lt;br&gt;&lt;code&gt;&amp;nbsp;1: Bool Solve&lt;br&gt;&amp;nbsp;2: {&lt;br&gt;&amp;nbsp;3: &amp;nbsp; If ( board is full)&lt;br&gt;&amp;nbsp;4: &amp;nbsp; {&lt;br&gt;&amp;nbsp;5: &amp;nbsp;&amp;nbsp;&amp;nbsp; // Evaluate returns true if solution is found&lt;br&gt;&amp;nbsp;6: &amp;nbsp;&amp;nbsp;&amp;nbsp; // or false if solution isn't correct one.&lt;br&gt;&amp;nbsp;7: &amp;nbsp;&amp;nbsp;&amp;nbsp; return Evaluate();&lt;br&gt;&amp;nbsp;8: &amp;nbsp; }&lt;br&gt;&amp;nbsp;9: &amp;nbsp; Foreach(location in board)&lt;br&gt;10: &amp;nbsp; {&lt;br&gt;11: &amp;nbsp;&amp;nbsp;&amp;nbsp; If (location is free)&lt;br&gt;12: &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;13: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Foreach(choice from available choices)&lt;br&gt;14: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;15: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; addChoiceToBoard(choice);&lt;br&gt;16:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If (location is end of the row AND&lt;br&gt;&lt;/code&gt;&lt;code&gt;17:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EvaluateRow())&lt;br&gt;18:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;/code&gt;&lt;code&gt;&lt;br&gt;19: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If (Solve())&lt;br&gt;20: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;21: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // We have solution for this puzzle!&lt;br&gt;22: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;23:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;24: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; removeChoiceFromBoard(choice);&lt;br&gt;25: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;26: &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;27: &amp;nbsp; }&lt;br&gt;28: }&lt;br&gt;&lt;/code&gt;&amp;lt;/solver_code2&amp;gt;&lt;/p&gt; &lt;p&gt;So before we go to deeper recursion, we'll check the conditions for it (lines 16 and 17). If &lt;em&gt;EvaluateRow&lt;/em&gt; method returns true then current row is correctly filled. This improved performance but we haven't reached our goal yet. Since that optimization was easy to make we can take bit harder step next. Let's call it &lt;em&gt;phase 3: return of the optimization!&lt;/em&gt; Idea is to check the conditions every time we insert item to the board:&lt;/p&gt; &lt;p&gt;&amp;lt;solver_code3&amp;gt;&lt;br&gt;&lt;code&gt;&amp;nbsp;1: Bool Solve&lt;br&gt;&amp;nbsp;2: {&lt;br&gt;&amp;nbsp;3: &amp;nbsp; If ( board is full)&lt;br&gt;&amp;nbsp;4: &amp;nbsp; {&lt;br&gt;&amp;nbsp;5: &amp;nbsp;&amp;nbsp;&amp;nbsp; // Solution is found!&lt;br&gt;&amp;nbsp;6: &amp;nbsp;&amp;nbsp;&amp;nbsp; return true;&lt;br&gt;&amp;nbsp;7: &amp;nbsp; }&lt;br&gt;&amp;nbsp;8: &amp;nbsp; Foreach(location in board)&lt;br&gt;&amp;nbsp;9: &amp;nbsp; {&lt;br&gt;10: &amp;nbsp;&amp;nbsp;&amp;nbsp; If (location is free)&lt;br&gt;11: &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;12: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Foreach(choice from available choices)&lt;br&gt;13: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;14: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; addChoiceToBoard(choice);&lt;br&gt;15:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If (Evaluate&lt;/code&gt;&lt;code&gt;())&lt;br&gt;16:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;/code&gt;&lt;code&gt;&lt;br&gt;17: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If (Solve())&lt;br&gt;18: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;19: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // We have solution for this puzzle!&lt;br&gt;20: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;21:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;22: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; removeChoiceFromBoard(choice);&lt;br&gt;23: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;24: &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;25: &amp;nbsp; }&lt;br&gt;26: }&lt;br&gt;&lt;/code&gt;&amp;lt;/solver_code3&amp;gt;&lt;/p&gt; &lt;p&gt;Now &lt;em&gt;Evaluate&lt;/em&gt; method checks that does the current board configuration satisfy the conditions set. So this kind of example could happen: We have row limit set to 20 and there is 12 + 1+ 3 already put in place in that row (=17). We know that there is still one place to fill and we know what numbers we have left. So if the smallest available number would be 5, then we couldn't satisfy the conditions since 12 + 1 + 3 + 5 isn't 20. So we can take back and ignore that subtree too. It optimizes the search a lot. With that &lt;a href="http://en.wikipedia.org/wiki/Algorithm"&gt;Algorithm&lt;/a&gt; we can go solve puzzle of the degree of difficulty 8700 in two seconds! &lt;br&gt;&lt;a href="http://blogs.msdn.com/blogfiles/jannemattila/WindowsLiveWriter/Solvingsmallpuzzleswithjustafewlinesofco_131E6/SurvoHard13.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="254" src="http://blogs.msdn.com/blogfiles/jannemattila/WindowsLiveWriter/Solvingsmallpuzzleswithjustafewlinesofco_131E6/SurvoHard1_thumb1.jpg" width="300" border="0"&gt;&lt;/a&gt; &lt;a href="http://blogs.msdn.com/blogfiles/jannemattila/WindowsLiveWriter/Solvingsmallpuzzleswithjustafewlinesofco_131E6/SurvoHard33.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="239" src="http://blogs.msdn.com/blogfiles/jannemattila/WindowsLiveWriter/Solvingsmallpuzzleswithjustafewlinesofco_131E6/SurvoHard3_thumb1.jpg" width="291" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Of course we need to&amp;nbsp;go&amp;nbsp;through the full&amp;nbsp;search of the tree so that we can verify the uniqueness of the solution.&amp;nbsp;But that's easy to implement. Just don't stop even if solution is found (line 6 on &lt;em&gt;Solver code 3&lt;/em&gt;). Just modify&amp;nbsp;it to store the solution somewhere (text file perhaps) and continue the search.&lt;/p&gt; &lt;h3&gt;Why would I like to do this?&amp;nbsp;Isn't this kind of solving a bit stupid?&lt;/h3&gt; &lt;p&gt;Well yes and no :) Yes in sense, that you could have much more fun solving these by paper and pen. I'm not saying that you can't do that anymore. No in sense that you can use this kind of codebase to test your optimization skills. And Visual Studio is great tool in that! You can run performance/profiling tests and then see where the application spends most of&amp;nbsp;it's time. This is actually really good exercise. You should try it! &lt;/p&gt; &lt;p&gt;Another good thing is that this &lt;a href="http://en.wikipedia.org/wiki/Algorithm"&gt;Algorithm&lt;/a&gt; is pretty useful in even more challenging games like chess, tic-tac-toe, checkers, 4 in a row, etc. Creating the base for the solver is easy... extending it with&amp;nbsp;really good &lt;em&gt;Evaluate&lt;/em&gt; method is hard. For example in chess you need to take so many variable into count that it makes my head spin. But if you learn from easier games like this you could easily develop such skills. It's always nice to play games that have cool &lt;a href="http://en.wikipedia.org/wiki/Artificial_intelligence"&gt;Artificial intelligence&lt;/a&gt;. &lt;br&gt;&lt;br&gt;Wow.. I thought that I start with small first post, but it somehow ended like this. Maybe next time I'll write something shorter.&lt;/p&gt; &lt;p&gt;Anyways... happy hacking!&lt;br&gt;&lt;br&gt;J&lt;br&gt;&lt;br&gt;&lt;strong&gt;Updated: &lt;/strong&gt;I finally had time to test my solver on the "beast" (degree of difficulty 17000 =&amp;gt; most difficult ever published Survo puzzle). &lt;br&gt;&lt;a href="http://blogs.msdn.com/blogfiles/jannemattila/WindowsLiveWriter/Solvingsmallpuzzleswithjustafewlinesofco_131E6/SurvoBeast13.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; margin: 5px 0px; border-right-width: 0px" height="260" src="http://blogs.msdn.com/blogfiles/jannemattila/WindowsLiveWriter/Solvingsmallpuzzleswithjustafewlinesofco_131E6/SurvoBeast1_thumb1.jpg" width="287" border="0"&gt;&lt;/a&gt;&lt;br&gt;And it even suprised me when it managed to solve it in almost 10 seconds! It also verified uniqueness of the solution in 20 seconds. I'll post the solution into here, but don't peek if you do want to solve it by yourself :) &lt;br&gt;&lt;a href="http://blogs.msdn.com/blogfiles/jannemattila/WindowsLiveWriter/Solvingsmallpuzzleswithjustafewlinesofco_131E6/SurvoBeast26.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; margin: 5px 0px 0px; border-right-width: 0px" height="63" src="http://blogs.msdn.com/blogfiles/jannemattila/WindowsLiveWriter/Solvingsmallpuzzleswithjustafewlinesofco_131E6/SurvoBeast2_thumb4.jpg" width="70" border="0"&gt;&lt;/a&gt;&amp;nbsp;&lt;br&gt;&lt;strong&gt;Updated(2):&lt;/strong&gt; I almost forgot... &lt;a title="Blog of Jezz Santos" href="http://blogs.msdn.com/jezzsa/" target="_blank"&gt;Jezz Santos&lt;/a&gt; found this really nice Sudoku article that you should&amp;nbsp;definitely checkout:&amp;nbsp;&lt;a title="Microsoft Sudoku: Optimizing UMPC Applications for Touch and Ink" href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dntablet/html/tbconSudokuSampleFinal.asp" target="_blank"&gt;Microsoft Sudoku: Optimizing UMPC Applications for Touch and Ink&lt;/a&gt;&amp;nbsp;on MSDN by &lt;a title="Blog of Stephen Toub" href="http://blogs.msdn.com/toub" target="_blank"&gt;Stephen Toub&lt;/a&gt;.&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1428489" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jannemattila/archive/tags/Application+Development/default.aspx">Application Development</category><category domain="http://blogs.msdn.com/jannemattila/archive/tags/tips+and+tricks/default.aspx">tips and tricks</category><category domain="http://blogs.msdn.com/jannemattila/archive/tags/Programming/default.aspx">Programming</category></item></channel></rss>