# Enigmatic Code

Programming Enigma Puzzles

## Enigma 859: Oh lucky day!

From New Scientist #2014, 27th January 1996 [link]

I have a lucky number. When the numbers of a date add up to the square of my lucky number I call that a “lucky day”. (For example, if my lucky number were 11 then 24/3/94 would be a lucky day since 24 + 3 + 94 = 121). I especially like the lucky days which fall on Sundays.

I once noted the occurrences of my lucky days as they happened over a period of three consecutive calendar years. I had one day each month. Furthermore, there were more lucky Sundays in the first year than in the second, and more lucky Sundays in the second than the third.

What was the date of the first lucky day in that three-year period?

[enigma859]

### One response to “Enigma 859: Oh lucky day!”

1. Jim Randell 20 June 2022 at 2:46 pm

This Python program runs in 81ms. (Internal run time is 17.9ms).

Run: [ @replit ]

```from datetime import (date, timedelta)
from collections import defaultdict
from enigma import (
Record, irange, is_square, tuples, seq_all_same, intersect, printf
)

# record lucky number data for year <y>
def year(y):
# record by lucky number ...
m = defaultdict(lambda:  * 12)  # number of lucky days each month
s = defaultdict(int)  # number of lucky Sundays
f = dict()  # first lucky day
d = date(y, 1, 1)
i = timedelta(days=1)
while d.year == y:
n = d.day + d.month + (d.year % 100)
k = is_square(n)
if k:
m[k][d.month - 1] += 1
if d.isoweekday() == 7:
s[k] += 1
if k not in f: f[k] = d
d += i
# find lucky numbers with exactly 1 lucky day each month
(rs, rf) = (dict(), dict())
for (k, vs) in m.items():
if seq_all_same(vs, value=1):
rs[k] = s[k]
rf[k] = f[k]
return Record(year=y, sun=rs, first=rf)

# consider 3 consecutive years (a, b, c) working backwards from 1995
for (c, b, a) in tuples(map(year, irange(1995, 1900, step=-1)), 3):
# consider common lucky numbers
for k in intersect([x.sun.keys() for x in (a, b, c)]):
# check for increasing lucky Sundays
if a.sun[k] > b.sun[k] > c.sun[k]:
first = a.first[k]
printf("lucky = {k}; years = {a.year} {b.year} {c.year}; first = {first}")
```

Solution: The first lucky day was 16th January 1983.

The lucky number is 10, so we are looking for dates that sum to 100.

In 1983, 1984, 1985 we have:

16 + 01 + 83 = 100 (Sunday)
15 + 02 + 83 = 100
14 + 03 + 83 = 100
13 + 04 + 83 = 100
12 + 05 + 83 = 100
11 + 06 + 83 = 100
10 + 07 + 83 = 100 (Sunday)
09 + 08 + 83 = 100
08 + 09 + 83 = 100
07 + 10 + 83 = 100
06 + 11 + 83 = 100 (Sunday)
05 + 12 + 83 = 100

15 + 01 + 84 = 100 (Sunday)
14 + 02 + 84 = 100
13 + 03 + 84 = 100
12 + 04 + 84 = 100
11 + 05 + 84 = 100
10 + 06 + 84 = 100 (Sunday)
09 + 07 + 84 = 100
08 + 08 + 84 = 100
07 + 09 + 84 = 100
06 + 10 + 84 = 100
05 + 11 + 84 = 100
04 + 12 + 84 = 100

14 + 01 + 85 = 100
13 + 02 + 85 = 100
12 + 03 + 85 = 100
11 + 04 + 85 = 100
10 + 05 + 85 = 100
09 + 06 + 85 = 100 (Sunday)
08 + 07 + 85 = 100
07 + 08 + 85 = 100
06 + 09 + 85 = 100
05 + 10 + 85 = 100
04 + 11 + 85 = 100
03 + 12 + 85 = 100

Further back in time we can find more solutions (some with different lucky numbers):

lucky number = 10; years = 1875 1876 1877; first = 1875-01-24
lucky number = 7; years = 1827 1828 1829; first = 1827-01-21
lucky number = 11; years = 1795 1796 1797; first = 1795-01-25
lucky number = 9; years = 1759 1760 1761; first = 1759-01-21

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