# Enigmatic Code

Programming Enigma Puzzles

From New Scientist #2261, 21st October 2000 [link]

Take a large sheet of paper and a black pen and draw a rectangle ABCD with AB = 10 metres and BC = 2 metres. Now draw lines to divide your rectangle into small squares, each of side 1 centimetre. Place your diagram so that A is due north of D and B is east of A. In each small square draw the diagonal that goes from northwest to southeast. Let P and Q be the mid-points of AD and BC, respectively. Then there is a black line PQ; remove it and replace it by a red line.

Amber is a small ant who can walk along the black lines in your diagram. North of PQ she covers a centimetre in 1 minute, but south of PQ she can cover a centimetre in 30 seconds. She is to walk from C to A and she chooses the quickest route.

1. How long does Amber take on her journey? Give the time, to the nearest second, in hours, minutes and seconds.

Ben is another ant who walks along the black lines. North of PQ he goes at the same speed as Amber, but not south of PQ. The fastest time for Ben to get from C to A is 24 hours.

2. South of PQ, how long does Ben take to cover a centimetre? Give the time, to the nearest second, in minutes and seconds.

[enigma1105]

### 2 responses to “Enigma 1105: Road ants”

1. Jim Randell 24 July 2017 at 8:26 am

This Python program uses the find_value() routine from the enigma.py to find a numerical answer to the second part of the puzzle. It runs in 196ms.

```from enigma import sqrt, irange, Accumulator, find_value, sprintf, printf

# distance along a diagonal
r2 = sqrt(2)

# distance in a 100 by x rectangle
def dist(x):
return (x * r2 + 100 - x) if x < 100 else (100 * r2 + x - 100)

# min journey time (in s)
def min_time(tN, tS):
# find the minimal time
r = Accumulator(fn=min)
# choose a point along PQ
for x in irange(0, 1000):
# distance below the line (in cm)
S = dist(1000 - x)
# distance above the line (in cm)
N = dist(x)
# calculate time taken (in seconds)
t = tS * S + tN * N
r.accumulate(t)
# return the minimum value
return r.value

# convert seconds to hours, minutes, seconds
def hms(t):
s = t % 60
(h, m) = divmod(int(t) // 60, 60)
x = sprintf("{s:.0f}s")
if m: x = sprintf("{m}m {x}")
if h: x = sprintf("{h}h {x}")
return x

# A takes 60s to go 1cm above the line and 30s below the line
A = min_time(60, 30)
printf("A: min time = {t}", t=hms(A))

# B takes 60s to go 1cm above the line, and the min journey time is 24h
day = 24 * 60 * 60
B = find_value((lambda t: min_time(60, t)), day, 0, day)
printf("B: tS = {t}", t=hms(B.v))
```

Solution: 1. Amber’s journey takes 10h 12m 8s; 2. Ben takes 3m 59s to cover 1cm in the Southern part of the grid. (Times to the nearest second).

Here are minimal duration paths for Amber and Ben:

Amber covers (100√2) cm in the Northern section [3], and ((100√2) + 800) cm in the Southern section [2] + [1], giving an overall time of (24000 + 9000√2) seconds.

Ben covers (900 + 100√2) cm in the Northern section [3] + [2], and 100 cm in the Southern section [1], for an overall time of 86400 s, giving a time t to cover 1cm in the Southern section of:

54000 + 6000√2 + 100t = 86400
t = 324 – 60√2

2. Hugh Casement 25 July 2017 at 4:16 pm

I think I’m right in saying that there are only these two basic patterns of quickest route (with their rotations by 180°, depending as the ant is faster in the northern or southern band).
Type A flips to type B when the ratio of the two speeds exceeds 1 + √2.

Of course where a band contains both horizontal and diagonal segments (red for Amber, blue for Ben), there are numerous possible zigzag routes with the two directions alternating. But the overall distances covered in each direction remain the same.