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: [0] * 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

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

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

%d bloggers like this: