Calculate the Most Frequent Weekdays in Go


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")
  })
})