Solutions to Project Euler 19: How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)?

Project Euler 19: Counting Sundays

Peter Prevos

Peter Prevos |

579 words | 3 minutes

Share this content

Project Euler 19 is so trivial it is almost not worth writing an article about. One exciting aspect of this problem is the naming of weekdays and deciding which day the week starts. This issue is more complicated than it sounds because data science is, in essence, not about data but about people.

Project Euler 19 Definition

You are given the following information, but you may prefer to do some research for yourself.

  • 1 January 1900 was a Monday.
  • Thirty days has September, April, June and November.
  • All the rest have thirty-one,
  • Saving February alone, Which has twenty-eight, rain or shine. And on leap years, twenty-nine.
  • A leap year occurs on any year evenly divisible by 4, but not on a century unless it is divisible by 400.

How many Sundays fell on the first of the month during the twentieth century (1 January 1901 to 31 December 2000)?

Proposed Solution

The problem can be quickly solved with R base code and a tiny bit faster when using the lubridate package.

  ## Project Euler 19: Counting Sundays

  ## Base-R
  dates <- seq.Date(as.Date("1901-01-01"), as.Date("2000-12-31"), "days")
  days <- rep(1:7, length.out = length(dates))
  answer <- sum(days[substr(dates, 9, 10) == "01"] == 1)
  print(answer)

  ## Using Lubridate
  library(lubridate)
  dates <- seq.Date(as.Date("1901-01-01"), as.Date("2000-12-31"), "months")
  answer <- sum(wday(dates) == 1)
  print(answer)

To draw out this post a little bit further, I wrote some code to solve the problem without using any of the calendar functions in R.

  ## Calculate from scratch
  week.day <- 0
  answer <- 0
  for (y in 1901:2000) {
      for (m in 1:12) {
          max.day <- 31
          if (m %in% c(4, 6, 9, 11))
              max.day <- 30
          # Leap years
          if (m == 2) {
              if (y %% 4 == 0 & y %% 100 != 0 | y %% 400 == 0) 
                  max.day <- 29
              else 
                  max.day <- 28
          }
          for (d in 1:max.day) {
              week.day <- week.day + 1
              if (week.day == 8) week.day <- 1
              if (week.day == 1 & d == 1)
              answer <- answer + 1
          }
      }
  }
  print(answer)

Which day does the week start?

The only aspect remotely interesting about this problem is the conversion from weekdays to numbers. In R, Monday is considered day one, which makes sense in the Christian context of Western culture. Saturday and Sunday are the weekends, the two last days of the week so they are day 6 and 7. According to international standard ISO 8601, Monday is the first day of the week. Although this is the international standard, several countries, including the United States and Canada, consider Sunday to be the first day of the week.

The international standard is biased towards Christianity. The Christian or Western world marks Sunday as their day of rest and worship. Muslims refer to Friday as their day of rest and prayer. The Jewish calendar counts Saturday—the Sabbath—as the day of rest and worship. This idea is also shared by Seventh-Day Adventists.

This Euler problem shows that data science is not only about data: it is always how people interpret the world.

First day of the week around the world.
First day of the week around the world.
  ## First day of the week
  library(tidyverse)
  firstday <- read_csv("data/first_day.csv")

  map_data(map = "world") %>%
    full_join(firstday) %>%
    ggplot(aes(long, lat, group = group, fill = firstday)) +
    geom_polygon() +
    theme_void() +
    coord_fixed() +
    labs(title = "First day of the week")

  ggsave("images/problem-019.png", width = 6, height = 4)
Where do the Days of the Week Get Their Names?

Share this content

You might also enjoy reading these articles

Project Euler 35: Circular Primes below One Million

Project Euler 144: Laser Beams and Elliptical Billiards

Project Euler 33: Digit Cancelling Fractions