Skip to content
Vamshi Jandhyala

Books · The Riddler

Chapter 25

When Will The Arithmetic Anarchists Attack?

The year is 2000, and an arithmetical anarchist group has an idea. For the next 100 years, it will vandalise a famous landmark whenever the year (in two-digit form, for example this year is “18”) is the product of the month and date, that is, month ×\times date == year, in MM/DD/YY format. A few questions about the lawless ensuing century: How many attacks happen between the start of 2001 and the end of 2099? Which year sees the most vandalism, and how many years see none? What is the longest gap between attacks?

The Riddler, FiveThirtyEight(original post)

Solution

An attack on date m/d/yym/d/yy happens exactly when md=yym \cdot d = yy with the month mm in 1121\ldots 12 and the day dd a real date of that month. So the number of attacks in year yyyy is the number of ways to write yyyy as mdm \cdot d with m12m \le 12 and dd no larger than the length of month mm. This is a divisor count, capped by the calendar.

Adding these over yy=199yy = 1\ldots 99 gives 212\boxed{212} attacks across the century. The busiest year is 2024\boxed{2024}: the number 2424 factors as 1241\cdot24, 2122\cdot12, 383\cdot8, 464\cdot6, 646\cdot4, 838\cdot3 and 12212\cdot2, all with valid days, for 77 attacks. At the other extreme, 20\boxed{20} years see no attack at all: every prime above 1212 (such as 37,41,4337,41,43) and a handful of others (like 58=22958 = 2\cdot29, whose only small factor needs a nonexistent day) cannot be written as a small month times a real day. The longest drought runs from the single attack of 2057 (March 19, since 57=31957 = 3\cdot19) to the first of 2060 (March 20, since 60=32060 = 3\cdot20), a gap of 1097\boxed{1097} days, just over three years.

The computation

Sweep every date of the century: for each year, month and valid day (leap years included), record an attack when month times day equals the two-digit year, then read off the totals, the busiest and quietest years, and the largest gap between consecutive attack dates.

from datetime import date
length = {1:31,2:28,3:31,4:30,5:31,6:30,7:31,8:31,9:30,10:31,11:30,12:31}
attacks = {}; dates = []
for yy in range(1, 100):
    n = 0
    for m in range(1, 13):
        days = length[m] + (1 if yy % 4 == 0 and m == 2 else 0)
        for d in range(1, days + 1):
            if m * d == yy:
                n += 1; dates.append(date(2000 + yy, m, d))
    attacks[yy] = n
dates.sort()
gap = max((dates[i+1] - dates[i]).days for i in range(len(dates) - 1))
print(sum(attacks.values()),                      # 212 total
      max(attacks, key=attacks.get),              # 24  busiest year
      sum(v == 0 for v in attacks.values()),      # 20  empty years
      gap)                                         # 1097 longest gap