Countdown: Problem #4

A few years ago I stumbled upon a web site which presents various problems that you are supposed to solve using Ruby. So I wondered how easy would it be to create a solution for one of the problems (the hard one) using VB.NET

The problem’s description is as follows:

You’ll be provided (in the $input variable) with ‘source’ numbers and ‘target’ numbers. What you’ll have to do is arrange the source numbers into a mathematical expression that equals the target number.

The input is provided as single string, like this:

TARGET:104;SOURCE:100,3,4,7,1,2;

According to the description of the problem, you are supposed to combine the SOURCE numbers using the four basic arithmetic operations (addition, subtraction, multiplication and division) until you find a combination that produces the desired result, the TARGET.

So a possible solution would be:
100+(3-(4-(7*1)+2)) == 104

And that’s the output that is expected from the program.

Once I had the basic the code implemented I started enhancing it with several features that were not required but that made the program quite nice, and entertaining:

  • Ability to search for all possible solutions (not just one).
  • Option to display the progress, that is, all the combinations that the program is trying.

Here’s a link to the project source code:
Countdown (1212 downloads )

CountdownUI

CountdownUI

A couple of months ago I decided to create a WinForms version of the program. It worked well, but since I didn’t implement any multi-threading, the UI would become unresponsive while the program was running — quite useless, and implementing multi-threading, callbacks and all the stuff that is required to free up the UI thread from other processes in the program was out of the question. It wasn’t worth it.

But, this past Sunday I found about a new language enhancement that Microsoft is preparing for both C# and VB.NET that will simplify the process of implementing asynchronous calls.
Fortunately, we don’t have to wait for this enhancement to be officially rolled out as Microsoft is providing it as a CTP.
It can be downloaded from Microsoft’s MSDN web site at the following link: Visual Studio Async CTP
Make sure you check out the PDC2010 video also available on the web site.

So, by simply changing some of the method calls to async calls, the program runs at full speed without hardly affecting the UI thread. Awesome!

How easy it is to make those code changes you ask?
Consider this synchronous version of this method:

Private Sub FindSolutions()
    Dim params As String = ""
    If chkFindAll.Checked Then params += " /all"
    If chkShowProgress.Checked Then params += " /sp"

    SetUIState(False)
    Dim args = String.Format("TARGET:{0};SOURCES:{1} {2}", txtTarget.Text, txtSources.Text, params.Trim()).Split(" "c)
    Run()
    SetUIState(True)
End Sub

Now, here’s how the async version looks like:

Private Async Sub FindSolutionsAsync()
    Dim params As String = ""
    If chkFindAll.Checked Then params += " /all"
    If chkShowProgress.Checked Then params += " /sp"
    Dim args = String.Format("TARGET:{0};SOURCES:{1} {2}", txtTarget.Text, txtSources.Text, params.Trim()).Split(" "c)

    SetUIState(False)
    cts = New CancellationTokenSource()
    Await sf.RunAsync(args, cts.Token)
    cts.Dispose()
    SetUIState(True)
End Sub

It couldn’t be easier.
Basically, all you need to do is sign the method with the Async modifier and then determine which portion of the code you want to await. What happens is that when the awaited code is called the execution is immediately returned to the calling process and the code that appears after the awaited code will be executed, through a callback, when the awaited code finishes.
The beauty of this is that the rewiring of the code is performed under the hood by the compiler!
A lot more information is available on the Async CTP web site.

Oh, and here’s a link to the UI version of the Countdown program (including source code):
CountdownGUI (1114 downloads )