64 lines
2.2 KiB
Text
64 lines
2.2 KiB
Text
Rebol [
|
|
title: "Rosetta code: Five weekends"
|
|
file: %Five_weekends.r3
|
|
url: https://rosettacode.org/wiki/Five_weekends
|
|
]
|
|
|
|
five-weekends: function/with [
|
|
"Show all months that have five full weekends."
|
|
start [integer!] "Start year"
|
|
end [integer!] "End year"
|
|
][
|
|
boring-years: total-fw-months: awesome-years: 0
|
|
for year start end 1 [
|
|
fw-months: clear []
|
|
;; A month has five weekends when its first day is a Saturday (weekday 7)
|
|
foreach month long-months [
|
|
if 1 = get-day year month 1 6 [
|
|
++ total-fw-months
|
|
append fw-months month-names/:month
|
|
]
|
|
]
|
|
prin ajoin [as-yellow year ": "]
|
|
print switch count: length? fw-months [
|
|
0 [
|
|
++ boring-years
|
|
as-red "Boring year!"
|
|
]
|
|
1 [
|
|
ajoin ["1 month: " fw-months]
|
|
]
|
|
2 [
|
|
++ awesome-years
|
|
ajoin [as-green count " months: " ajoin/with fw-months ", "]
|
|
]
|
|
]
|
|
]
|
|
print-horizontal-line
|
|
print ["Total five-weekend months: " total-fw-months]
|
|
print ["Total years with no five-weekend months: " boring-years ]
|
|
print ["Total years with 2+ five-weekend months: " awesome-years]
|
|
][
|
|
;; Return the day-of-month for the Nth weekday in a given month,
|
|
;; or NONE if that occurrence falls outside the month.
|
|
get-day: function [
|
|
year [integer!]
|
|
month [integer!]
|
|
week [integer!]
|
|
weekday [integer!]
|
|
][
|
|
date: to-date reduce [1 month year] ; first-of-month
|
|
;; Rebol weekday is Mon=1 .. Sun=7; shift to Sun=1 .. Sat=7
|
|
weekday-1st: (date/weekday + 1) % 7
|
|
;; Days from the 1st to the target weekday in the requested week
|
|
offset: (week - 1) * 7 + (weekday - weekday-1st)
|
|
target-date: date + offset
|
|
;; Return the day number only if it still falls within the same month or none
|
|
if target-date/month = month [target-date/day]
|
|
]
|
|
month-names: system/locale/months
|
|
;; Months with 31 days are the only ones that can hold five full weekends
|
|
long-months: [1 3 5 7 8 10 12]
|
|
]
|
|
|
|
five-weekends 1900 2100
|