# Enigmatic Code

Programming Enigma Puzzles

## Enigma 1540: On the run

From New Scientist #2703, 11th April 2009 [link]

On three days in each calendar week (Sunday to Saturday) I go for a run, but I never run on two consecutive days.

In the last 12 years there was

(a) a year when I went for two more runs in February than in March,
(b) a year when I went for four more runs in March than in February.

Which years were those?

[enigma1540]

### One response to “Enigma 1540: On the run”

1. Jim Randell 16 April 2012 at 8:33 pm

The following Python program runs in 100ms.

```from itertools import combinations
from datetime import date, timedelta
from enigma import irange, printf

# weeks that are internal to the month always have 3 runs in them
# and the runs can be Mon, Wed, Fri, so not interfere with adjacent weeks

# generate runs such that there are three a week and no two are consecutive
runs = []
for r in combinations(irange(0, 6), 3):
r = sorted(r)
if r[2] - r[1] == 1 or r[1] - r[0] == 1: continue
runs.append(r)

# s = start date
# feb = accumulated runs in Feb
# mar = accumulated runs in Mar
# sat = does the previous week end with a run on a Saturday?
def solve(s, feb, mar, sat):
# are we done?
if s.month == 4:
if feb == mar + 2:
printf("[a] year={s.year} feb={feb} mar={mar}")
return True
elif mar == feb + 4:
printf("[b] year={s.year} feb={feb} mar={mar}")
return True
return False
# what's the date at the end of this week?
e = s + timedelta(days=6)
if s.month == e.month:
# internal week, so add three runs to the current month
if s.month == 2:
feb += 3
else:
mar += 3
return solve(s + timedelta(days=7), feb, mar, False)

# try one of the possible patterns of runs
for p in runs:
# can't run on a Sunday if we ran on a Saturday in the previous week
if sat and p[0] == 0: continue
(f, m) = (0, 0)
for i in p:
d = (s + timedelta(days=i)).month
if d == 2:
f += 1
elif d == 3:
m += 1
if solve(s + timedelta(days=7), feb + f, mar + m, p[2] == 6): return True

for year in irange(1997, 2009):
# find the first Sunday on or before 1st February
d = date(year, 2, 1)
s = d - timedelta(days=d.isoweekday() % 7)
solve(s, 0, 0, False)
```

Solution: (a) 2000, (b) 2005.

This site uses Akismet to reduce spam. Learn how your comment data is processed.