The Math Forum

Search All of the Math Forum:

Views expressed in these public forums are not endorsed by NCTM or The Math Forum.

Math Forum » Discussions » sci.math.* » sci.math

Notice: We are no longer accepting new posts, but the forums will continue to be readable.

Topic: Continous path on square grid
Replies: 15   Last Post: Feb 6, 2013 7:04 PM

Advanced Search

Back to Topic List Back to Topic List Jump to Tree View Jump to Tree View   Messages: [ Previous | Next ]
The Last Danish Pastry

Posts: 740
Registered: 12/13/04
Re: Continous path on square grid
Posted: Feb 6, 2013 12:12 PM
  Click to see the message monospaced in plain text Plain Text   Click to reply to this topic Reply

On Feb 6, 11:36 am, Frederick Williams <>

> That's neat.  What algorithm did you use to find the paths?  The answer
> may be long and complicated, and if so I'll not press you for it; but if
> it's short and simple I wouldn't mind knowing.

Thanks. As to the algorithm...

The algorithm effectively has two parameters:

n = the number of spots along the side of the square. In our case 5.
m = the maximum number of moves to make. In our case 8.

By the way, when looking for P(5,8) the program never found a solution
in less than 8 moves.

The program deals with points and lines.

Each point is defined by a triple of integers: (x,y,z).

# An object of this class represents the point (x/z, y/z).
# z must not be negative.
# If any of x, y, z are non-zero then gcd(x, y, z) must be 1.
# If z = 0 the point is at infinity.
# The point (0, 0, 0) lies on every line.

Each line is defined by a triple of integers: [a,b,c].

# An object of this class represents the line a*x + b*y + c = 0.
# c must not be negative.
# If any of a, b, c are non-zero then gcd(a, b, c) must be 1.
# If a = 0 and b = 0 then c must be 0 or 1.
# The line [0, 0, 1] is the line at infinity.
# Every point at infinity lies on this line.
# No finite point lies on this line.
# The line [0, 0, 0] passes through every point.

The point (x,y,z) lies on the line [a,b,c] iff a*x + b*y + c*z = 0.

With these definitions the code for computing the intersection of two
lines or the join of two points is identical:

public static Point Intersection(Line l1, Line l2)
int x = l1.b*l2.c - l2.b*l1.c;
int y = l2.a*l1.c - l1.a*l2.c;
int z = l1.a*l2.b - l2.a*l1.b;

if (z < 0 || (z == 0 && x < 0) || (z == 0 && x == 0 && y < 0))
x = -x;
y = -y;
z = -z;
int gcd = U.gcd(U.gcd(Math.Abs(x), Math.Abs(y)), z);

return gcd == 0? new Point(): new Point(x/gcd, y/gcd, z/gcd);
} // Intersection

public static Line Join(Point p1, Point p2)
int a = p1.y*p2.z - p2.y*p1.z;
int b = p2.x*p1.z - p1.x*p2.z;
int c = p1.x*p2.y - p2.x*p1.y;

if (c < 0 || (c == 0 && a < 0) || (c == 0 && a == 0 && b < 0))
a = -a;
b = -b;
c = -c;
int gcd = U.gcd(U.gcd(Math.Abs(a), Math.Abs(b)), c);

return gcd == 0? new Line(): new Line(a/gcd, b/gcd, c/gcd);
} // Join

So, our entire universe of points and lines is defined in terms of
integers. And all questions about points and lines can be answered by
comparing integers.

The program uses a traditional backtracking approach, but before the
search starts the program computes a number of data structures.

A) The program computes all the lines defined by the 25 spots. There
are 140 such lines.

B) The program computes all the (finite) intersections of those 140
lines. There are 3,861 such points (including the 25 spots).

C) For each of the 3,861 points the program computes a list of the
lines through that point.

D) For each of the 140 lines the program computes a list of the points
on that line. The program sorts each such list into sequential order
along the line. [Essentially, sorting the points by their x/z value
(or by y/z if the line is parallel to the y-axis) although no
divisions are required in the comparison process.]

E) Using the structures that are now available, for each of the 3,861
points the program now computes a list of allowable moves from that
point. An allowable move being along a line through the point and
including at least TWO spots [not counting the starting point, if it
happens to be a spot, but counting the finishing point, if it happens
to be a spot]. The data stored for the move is a reference to the
finishing point and a list of the spots crossed.

F) The program finally finds, for each of the 3,861 points, the 7
points which are the rotations and reflections of that point. This
helps in discarding duplicate solutions during the search.

G) The program now does the usual depth-first search of the tree of
possible moves, being careful to avoid moves which include an already-
traversed spot.

The program never considers a move which crosses fewer than two spots.
Whilst a line segment which includes NO spots is, perhaps, unlikely, a
segment which crosses just one spot is entirely possible and the
program may certainly have missed some solutions because of this.
Originally I did include such one-spot moves but the program ran very
slowly, so I changed it. Currently the program takes about 17 minutes
to find the 118 5x5 solutions. [I have just noticed an error in the
program which probably causes it to miss certain solutions. I will
look into this.]

I have tried the 6x6 puzzle but the program has never found a single
solution. However, looking at the 5x5 solutions it is clear that some
of them,
for example, could easily be extended to a P(6,10).

I hope this gives you some feeling for how the search algorithm works.

Clive Tooth

Point your RSS reader here for a feed of the latest messages in this topic.

[Privacy Policy] [Terms of Use]

© The Math Forum at NCTM 1994-2018. All Rights Reserved.