Welcome Guest!
 VB Helper
 Previous Message All Messages Next Message 
VB 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
http://www.vb-helper.com/db_design.htm

    A good database design doesn't guarantee success, but a bad one
guarantees failure.
-----
WPF Programmer's Reference
http://www.vb-helper.com/wpf_prog_ref.htm

    Go beyond what you thought possible in user interface development
-----
Visual Basic 24-Hour Trainer
http://www.vb-helper.com/24hourvb.htm

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

Rod
RodSte-@vb-helper.com

Twitter feeds:
    VBHelper
    CSharpHelper
==========
==========

    VB6 Contents:
1. New HowTo: Puzzle: find the equilateral triangles in Visual Basic 6

    VB.NET Contents:
2. New HowTo: Puzzle: find the equilateral triangles in Visual Basic
.NET
==========
++++++++++
       <VB6>
++++++++++
==========
1. New HowTo: Puzzle: find the equilateral triangles in Visual Basic 6
http://www.vb-helper.com/howto_triangle_puzzle.html
http://www.vb-helper.com/HowTo/howto_triangle_puzzle.zip

(Picture at http://www.vb-helper.com/howto_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 Xs As Collection
Private Ys As Collection

' The solutions.
Private Solutions As Collection

' The solution we should display.
Private CurrentSolution As Integer

' Define the points and solutions.
Private Sub Form_Load()
Dim dy As Single
Dim dx As Single
Dim top_x As Single
Dim top_y As Single

    ScaleMode = vbPixels

    ' Define the points.
    dy = CSng(ScaleHeight / 4)
    dx = CSng(dy / Sqr(3))
    top_x = CSng(ScaleWidth / 2)
    top_y = -dy / 2
    Set Xs = New Collection
    Set Ys = New Collection
    Xs.Add (top_x - dx): Ys.Add (top_y + dy)
    Xs.Add (top_x + dx): Ys.Add (top_y + dy)
    Xs.Add (top_x - 2 * dx): Ys.Add (top_y + 2 * dy)
    Xs.Add (top_x - 0 * dx): Ys.Add (top_y + 2 * dy)
    Xs.Add (top_x + 2 * dx): Ys.Add (top_y + 2 * dy)
    Xs.Add (top_x - 3 * dx): Ys.Add (top_y + 3 * dy)
    Xs.Add (top_x - 1 * dx): Ys.Add (top_y + 3 * dy)
    Xs.Add (top_x + 1 * dx): Ys.Add (top_y + 3 * dy)
    Xs.Add (top_x + 3 * dx): Ys.Add (top_y + 3 * dy)
    Xs.Add (top_x - 2 * dx): Ys.Add (top_y + 4 * dy)
    Xs.Add (top_x - 0 * dx): Ys.Add (top_y + 4 * dy)
    Xs.Add (top_x + 2 * dx): Ys.Add (top_y + 4 * dy)

    ' Define the solutions.
    Set Solutions = New Collection

    ' Insert your code here...
    AddSolution 1, 3, 4
    
    ' Start displaying no solution.
    CurrentSolution = Solutions.Count + 1
End Sub

This code creates the Xs and Ys collections that hold the coordinates of
the points and defines the points. The points are numbered from top to
bottom and left to right so the points in the first row have indices 1
and 2, the points in the second row have indices 3, 4, and 5, and so
forth.

This code also creates the Solutions collection. Your code should add
collections holding three integers each to the Solutions collection to
indicate the indices of points that make up the triangles. To make this
easier, the program includes the following AddSolution subroutine that
adds a triangle to thue solution. The Form_Load event handler calls
AddSolution once to show how to create a triangle that uses the points
numbered 1, 3, and 4.

' Add a new solution.
Private Sub AddSolution(ParamArray indices() As Variant)
Dim new_solution As Collection
Dim i As Integer

    ' Create the new solution collection.
    Set new_solution = New Collection
    For i = LBound(indices) To UBound(indices)
        new_solution.Add indices(i)
    Next i
    
    ' Add the new solution to the solutions list.
    Solutions.Add new_solution
End Sub

The AddSolution subroutine creates a new collection to hold the new
solution. It loops through the parameters passed to the routine adding
them to the new collection. It then adds that collection to the
Solutions collection.

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 Form_Paint()
Const radius As Single = 5

Dim i As Integer

    ' Draw the points.
    Me.FillStyle = vbFSSolid
    Me.FillColor = vbBlue
    For i = 1 To Xs.Count
        Me.Circle (Xs(i), Ys(i)), radius, vbBlue
    Next i

    ' Draw the current solution.
    If (CurrentSolution < 1) Then
        ' Draw all solutions.
        For i = 1 To Solutions.Count
            DrawSolution i
        Next i
    Else
        ' Draw the current solution.
        DrawSolution CurrentSolution
    End If
End Sub

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

The following code shows how the DrawSolution method draws a particular
solution.

' Draw a solution.
Private Sub DrawSolution(ByVal solution_num As Integer)
Dim solution As Collection
Dim i As Integer

    If (solution_num > Solutions.Count) Then Exit Sub

    ' Draw this solution.
    Set solution = Solutions(solution_num)
    
    ' Start at the last point.
    Me.CurrentX = Xs(solution(solution.Count))
    Me.CurrentY = Ys(solution(solution.Count))
    
    ' Connect to the other points.
    For i = 1 To solution.Count
        Me.Line -(Xs(solution(i)), Ys(solution(i))), vbRed
    Next i
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 sets the form's CurrentX and
CurrentY properties to the lastg point in the current solution. It then
loops through the points in the solution drawing a line connecting them
to the previous point.

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

' Start showing solutions.
Private Sub cmdShowSolutions_Click()
    ' Disable the button.
    cmdShowSolutions.Enabled = False

    ' Start at the first solution.
    CurrentSolution = 1

    ' Start the timer.
    tmrChangeSolution.Enabled = True

    ' Redraw.
    Refresh
End Sub

' Show the next solution.
Private Sub tmrChangeSolution_Timer()
    ' Increment CurrentSolution. If the result is greater than the
    ' last solution's index, disable the timer.
    CurrentSolution = CurrentSolution + 1
    tmrChangeSolution.Enabled = (CurrentSolution <= Solutions.Count)

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

    ' Redraw.
    Refresh
End Sub

' Show all of the solutions.
Private Sub cmdShowAllSolutions_Click()
    CurrentSolution = 0
    tmrChangeSolution.Enabled = False
    cmdShowSolutions.Enabled = True
    Refresh
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 = 1 to
display the first solution, enables the tmrChangeSolution Timer, and
refreshes the form to redraw. The Paint event handler draws the selected
solution (number 1). If there are no solutions, then the DrawSolution
method draws nothing because the index 1 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 0 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 < 1.

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.
==========
++++++++++
      <VB.NET>
++++++++++
==========
2. New HowTo: Puzzle: find the equilateral triangles in Visual Basic
.NET
http://www.vb-helper.com/howto_net_triangle_puzzle.html
http://www.vb-helper.com/HowTo/howto_net_triangle_puzzle.zip

(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
    Else
        ' 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
solution.

' Draw a solution.
Private Sub DrawSolution(ByVal gr As Graphics, ByVal solution_num As
Integer)
    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)
        pts.Add(Points(i))
    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
array.

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.
    Refresh()
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.
    Refresh()
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
    Refresh()
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.
==========
Archives:
    http://www.topica.com/lists/VBHelper
    http://www.topica.com/lists/VB6Helper
    http://www.topica.com/lists/VBNetHelper

Twitter feeds:
    VBHelper
    CSharpHelper

Post questions at:
    http://www.topica.com/lists/VBHelperQA
	
 Previous Message All Messages Next Message 
  Check It Out!

  Topica Channels
 Best of Topica
 Art & Design
 Books, Movies & TV
 Developers
 Food & Drink
 Health & Fitness
 Internet
 Music
 News & Information
 Personal Finance
 Personal Technology
 Small Business
 Software
 Sports
 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.