Enigmatic Code

Programming Enigma Puzzles

Enigma 1583: Have a good day

From New Scientist #2748, 20th February 2010 [link]

Some years ago I bought a car which had a digital display on its dashboard. The 10 digits displayed showed the date and time, such as

17:05:86 15:32

A “good day” was a day during which the 10 digits displayed were all different. In particular, I recall two good days, more than four months apart. The day mid-way between the two was not a good day, but in each month between those two good days there was at least one good day.

What were the dates (day and month) of those two particular good days?

[enigma1583]

Advertisements

One response to “Enigma 1583: Have a good day

  1. jimrandell 31 January 2012 at 3:55 pm

    The following Python program runs in 77ms.

    from itertools import permutations
    from collections import defaultdict
    import datetime
    
    # consider: DD:MM:YY hh:mm
    #
    # D1 in {0, 1, 2, 3}
    # M1 in {0, 1}
    # h1 in {0, 1, 2}
    # m1 in {0, 1, 2, 3, 4, 5}
    
    good = defaultdict(list)
    for M1 in (0, 1):
      for h1 in (0, 1, 2):
        if h1 == M1: continue
        for D1 in (0, 1, 2, 3):
          if D1 in (M1, h1): continue
          for m1 in (0, 1, 2, 3, 4, 5):
            if m1 in (M1, h1, D1): continue
    
            # and the rest
            for (D2, M2, Y1, Y2, h2, m2) in permutations(set(range(10)).difference((M1, h1, D1, m1))):
              DD = D1 * 10 + D2
              if DD > 31: continue
              MM = M1 * 10 + M2
              if MM > 12: continue
              hh = h1 * 10 + h2
              if hh > 23: continue
              YY = Y1 * 10 + Y2
              mm = m1 * 10 + m2
    
              good["{YY:02d}{MM:02d}{DD:02d}".format(YY=YY, MM=MM, DD=DD)].append("{hh:02d}{mm:02d}".format(hh=hh, mm=mm))
    
    
    # day to month number
    def month(d):
      return 12 * int(d[0:2]) + int(d[2:4])
    
    # day to day number
    def day(d):
      (yy, mm, dd) = map(int, (d[0:2], d[2:4], d[4:6]))
      return datetime.date(1900+yy, mm, dd).toordinal()
    
    
    # list of good days
    days = sorted(good.keys())
    
    # consider possible start days
    for i in range(len(days)):
      d1 = days[i]
      # month number
      m1 = month(d1)
      # months following this one with good days
      months = set((m1,))
      # consider the subsequent days
      for j in range(i+1, len(days)):
        d2 = days[j]
        m2 = month(d2)
        # skip days in the same month as m1
        if m2 == m1: continue
        # this month has a good day
        months.add(m2)
        # are the months contiguous?
        if m2 - 1 not in months: break
        # are we less than 4 months from the start date
        if m2 - m1 < 4 or (m2 - m1 == 4 and not(int(d1[4:6]) < int(d2[4:6]))): continue
    
        # compute the mid date (using Python datetimes)
        (m, r) = divmod(day(d1) + day(d2), 2)
        if r > 0: continue
        mid = datetime.date.fromordinal(m).strftime("%y%m%d")
        if mid in good: continue
    
        print(d1, d2, mid)
    

    Solution: The two good days are 24th March and 26th July.

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 )

Google+ photo

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

Connecting to %s

%d bloggers like this: