The challenge

What is your favourite day of the week? Check if it’s the most frequent day of the week in the year.

You are given a year as integer (e. g. 2001). You should return the most frequent day(s) of the week in that year. The result has to be a list of days sorted by the order of days in week (e. g. ['Monday', 'Tuesday']['Saturday', 'Sunday']['Monday', 'Sunday']). Week starts with Monday.

Input: Year as an int.

Output: The list of most frequent days sorted by the order of days in week (from Monday to Sunday).

Preconditions:

  • Week starts on Monday.
  • Year is between 1583 and 4000.
  • Calendar is Gregorian.

Example:

MostFrequentDays(2427) == []string{"Friday"}
MostFrequentDays(2185) == []string{"Saturday"}
MostFrequentDays(2860) == []string{"Thursday", "Friday"}

The solution in Golang

Option 1:

package mostfrequentdays
import (
  "time"
)
func MostFrequentDays(year int) []string {
  beg := time.Date(year, time.January, 1, 0, 0, 0, 0, time.UTC).Weekday()
  end := time.Date(year, time.December, 31, 0, 0, 0, 0, time.UTC).Weekday()
  if beg == end {
    return []string{beg.String()}
  }
  if beg == time.Sunday {
    beg, end = end, beg
  }
  return []string{beg.String(), end.String()}
} 

Option 2:

package mostfrequentdays
import "time"
func MostFrequentDays(year int) (result []string) {
  jan_1 := time.Date(year, time.January, 1, 0, 0, 0, 0, time.UTC)
  result = append(result, jan_1.Weekday().String())  
  if year % 4 == 0 {
    jan_2 := jan_1.Add(24*time.Hour)
    if result[0] == "Sunday" {
      result = append([]string{jan_2.Weekday().String()}, result...)
    } else {
      result = append(result, jan_2.Weekday().String())
    }
  }  
  return result
}

Option 3:

package mostfrequentdays
import ("time";"sort")
func MostFrequentDays(year int) (r []string) {
  first := time.Date(year, 1, 1, 0, 0, 0, 0, time.UTC)
  last := time.Date(year, 12, 1, 0, 0, 0, 0, time.UTC).AddDate(0, 1, -1)
  for {
    r = append(r, first.Weekday().String())
    if first.Weekday() == last.Weekday() { break }
    first = first.Add(24 * time.Hour)
  }
  m := map[string]int{"Monday": 1, "Tuesday": 2, "Wednesday": 3, "Thursday": 4, "Friday": 5, "Saturday": 6, "Sunday": 7}
  sort.Slice(r, func(i, j int) bool { return m[r[i]] < m[r[j]] })
  return
}

Test cases to validate our solution

package mostfrequentdays_test
import (
  . "github.com/onsi/ginkgo"
  . "github.com/onsi/gomega"
)
func test(input int, expected ...string) {
  Expect(MostFrequentDays(input)).To(Equal(expected))
}
var _ = Describe("Sample Tests", func() {
  It("Sample Tests", func() {
    test(2427, "Friday")
    test(2185, "Saturday")
    test(1167, "Sunday")
    test(1770, "Monday")
    test(1785, "Saturday")
    test(1984, "Monday", "Sunday")
    test(3076, "Saturday", "Sunday")
  })
})