Welcome Guest!
 VB.NET Helper
 Previous Message All Messages Next Message 
VB .NET Helper Newsletter  Rod Stephens
 Nov 18, 2011 13:59 PST 

Happy Thanksgiving to those in the US.

Microsoft has me listed as a featured MVP blogger at
http://msdn.microsoft.com/en-us/dd361754. Hardly an exclusive honor but
still kind of cool.

This newsletter just includes a puzzle that you may find interesting.
See how many triangles you can find "manually" and then write a program
to see if you found them all.
Beginning Database Design Solutions

    A good database design doesn't guarantee success, but a bad one
guarantees failure.
WPF Programmer's Reference

    Go beyond what you thought possible in user interface development
Visual Basic 24-Hour Trainer

    Unique book-and-DVD package for novice Visual Basic programmers
Have a great week and thanks for subscribing!


Twitter feeds:

    VB.NET Contents:
1. New HowTo: Puzzle: find the equilateral triangles in Visual Basic
1. New HowTo: Puzzle: find the equilateral triangles in Visual Basic

(Picture at http://www.vb-helper.com/howto_net_triangle_puzzle.png.)

This is a puzzle that was used recently on National Public Radio (NPR).
How many equilateral triangles can you make with corners on the points
drawn by the program? For this blog, the puzzle has two parts. First see
if you can solve the puzzle "manually." Then write a program that solves
the puzzle.

The code available for download with this post draws the points and will
draw the solution after you fill in the appropriate code. You only need
to fill in a small piece of code that initializes the solution, or
better yet discovers the solution for you.

The rest of this post shows how parts of the program that I've written
for you work. The following code executes when the form loads. (This is
where you need to add your code.)

' The points.
Private Points() As PointF

' The solutions.
Private Solutions As List(Of Integer())

' The solution we should display.
Private CurrentSolution As Integer = 100

' Define the points and solutions.
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
    DoubleBuffered = True

    ' Define the points.
    Dim dy As Single = CSng(ClientSize.Height / 4)
    Dim dx As Single = CSng(dy / Math.Sqrt(3))
    Dim top_x As Single = CSng(ClientSize.Width / 2)
    Dim top_y As Single = -dy / 2
    Points = New PointF() _
    { _
        New PointF(top_x - dx, top_y + dy), _
        New PointF(top_x + dx, top_y + dy), _
        New PointF(top_x - 2 * dx, top_y + 2 * dy), _
        New PointF(top_x - 0 * dx, top_y + 2 * dy), _
        New PointF(top_x + 2 * dx, top_y + 2 * dy), _
        New PointF(top_x - 3 * dx, top_y + 3 * dy), _
        New PointF(top_x - 1 * dx, top_y + 3 * dy), _
        New PointF(top_x + 1 * dx, top_y + 3 * dy), _
        New PointF(top_x + 3 * dx, top_y + 3 * dy), _
        New PointF(top_x - 2 * dx, top_y + 4 * dy), _
        New PointF(top_x - 0 * dx, top_y + 4 * dy), _
        New PointF(top_x + 2 * dx, top_y + 4 * dy) _

    ' Define the solutions.
    Solutions = New List(Of Integer())()

    ' Insert your code here...
End Sub

This code creates the Points array that defines the points. The points
are numbered from top to bottom and left to right so the points in the
first row have indices 0 and 1, the points in the second row have
indices 2, 3, and 4, and so forth.

This code also creates an empty Solutions list. Your code should add
arrays of three integers to the list to indicate the indices of points
that make up the triangles. For example, the following statement adds a
triangle to the list that uses points 0, 2, and 3.

Solutions.Add(new int() { 0, 2, 3 })

The program uses the following Paint event handler to draw the points
and the solution triangle indicated by the CurrentSolution variable.

' Draw the circles and any triangles currently defined.
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As
System.Windows.Forms.PaintEventArgs) Handles Me.Paint
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias

    ' Draw the points.
    Const radius As Single = 5
    For Each pt As PointF In Points
        e.Graphics.FillEllipse(Brushes.Blue, _
            pt.X - radius, pt.Y - radius, _
            2 * radius, 2 * radius)
    Next pt

    ' Draw the current solution.
    If (CurrentSolution < 0) Then
        ' Draw all solutions.
        For i As Integer = 0 To Solutions.Count - 1
            DrawSolution(e.Graphics, i)
        Next i
        ' Draw the current solution.
        DrawSolution(e.Graphics, CurrentSolution)
    End If
End Sub

This code loops through the points and draws them. Then if
CurrentSolution is less than 0, the program loops through all of the
solutions and calls DrawSolution for each. If CurrentSolution is not
less than 0, the program calls DrawSolution to draw just that solution.

The following code shows how the DrawSolution method draws a particular

' Draw a solution.
Private Sub DrawSolution(ByVal gr As Graphics, ByVal solution_num As
    If (solution_num >= Solutions.Count) Then Return

    ' Make a list of the points in this solution.
    Dim pts As New List(Of PointF)()
    For Each i As Integer In Solutions(solution_num)
    Next i
    gr.DrawPolygon(Pens.Red, pts.ToArray())
End Sub

If the solution number passed to the method is not a valid solution
index, the method returns without doing anything.

If the solution number is valid, the code creates a List of PointF. It
loops through the indices stored in the indicated solution and adds
their points to the list. It then calls the Graphics object's
DrawPolygon method to draw the points. DrawPolygon works with arrays not
lists so the code calls the list's ToArray method to convert it into an

The rest of the program's code is reasonably straightforward.

' Start showing solutions.
Private Sub btnShowSolutions_Click(ByVal sender As System.Object, ByVal
e As System.EventArgs) Handles btnShowSolutions.Click
    ' Disable the button.
    btnShowSolutions.Enabled = False

    ' Start at the first solution.
    CurrentSolution = 0

    ' Start the timer.
    tmrChangeSolution.Enabled = True

    ' Redraw.
End Sub

' Show the next solution.
Private Sub tmrChangeSolution_Tick(ByVal sender As System.Object, ByVal
e As System.EventArgs) Handles tmrChangeSolution.Tick
    ' Increment CurrentSolution. If the result is greater than the
    ' last solution's index, disable the timer.
    CurrentSolution += 1
    tmrChangeSolution.Enabled = (CurrentSolution < Solutions.Count)

    ' If we're done drawing, enable the button.
    btnShowSolutions.Enabled = (Not tmrChangeSolution.Enabled)

    ' Redraw.
End Sub

' Show all of the solutions.
Private Sub btnShowAllSolutions_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles btnShowAllSolutions.Click
    CurrentSolution = -1
    tmrChangeSolution.Enabled = False
    btnShowSolutions.Enabled = True
End Sub

When you click the Show Solutions button, the program disables that
button so you can't press it again. It then sets CurrentSolution = 0 to
display the first solution, enables the tmrChangeSolution Timer, and
refreshes the form to redraw. The Paint event handler draws the selected
solution (number 0). If there are no solutions, then the DrawSolution
method draws nothing because the index 0 is not a valid index in the
Solutions list.

When the timer ticks, the program increments CurrentSolution. It sets
the Timer's Enabled property to true if the new value is still a valid
solution index so the Timer runs until the last solution has been
displayed. If the timer is no longer enabled, the code re-enables the
Show Solutions button. The Tick event handler finishes by refreshing the
form to redraw it.

Finally if when you click the Show All button, the program sets
CurrentSolution to -1 and refreshes to redraw the solution. If you look
back at the Paint event handler, you'll see that it calls DrawSolution
for every solution if CurrentSolution < 0.

Download the example program and try to solve the puzzle. You can
explicitly enter code to create solutions that you figured out yourself,
or you can write code to find all of the solutions. Here's a small hint:
There are more solutions than you will probably think of at first.

If you find a solution, zip up your project and email it to me at
RodSte-@vb-helper.com. I'll post my solutions (manually solved and
automatically solved) and any others that I receive on Monday and
Tuesday, November 28 and 29, 2011.

Twitter feeds:

Post questions at:
 Previous Message All Messages Next Message 
  Check It Out!

  Topica Channels
 Best of Topica
 Art & Design
 Books, Movies & TV
 Food & Drink
 Health & Fitness
 News & Information
 Personal Finance
 Personal Technology
 Small Business
 Travel & Leisure
 Women & Family

  Start Your Own List!
Email lists are great for debating issues or publishing your views.
Start a List Today!

© 2001 Topica Inc. TFMB
Concerned about privacy? Topica is TrustE certified.
See our Privacy Policy.