Rebol3 Code Examplex
Five weekends
Count months that contain five weekends.
Rebol [
title: "Rosetta code: Five weekends"
file: %Five_weekends.r3
url: https://rosettacode.org/wiki/Five_weekends
note: "Based on Hinjo's Red version"
]
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