-- TEST ----------------------------------------------------------------------- on run fiveWeekends(1900, 2100) end run -- FIVE WEEKENDS -------------------------------------------------------------- -- fiveWeekends :: Int -> Int -> Record on fiveWeekends(fromYear, toYear) set lstYears to enumFromTo(fromYear, toYear) -- yearMonthString :: (Int, Int) -> String script yearMonthString on |λ|(lstYearMonth) ((item 1 of lstYearMonth) as string) & " " & ¬ item (item 2 of lstYearMonth) of ¬ {"January", "", "March", "", "May", "", ¬ "July", "August", "", "October", "", "December"} end |λ| end script -- addLongMonthsOfYear :: [(Int, Int)] -> [(Int, Int)] script addLongMonthsOfYear on |λ|(lstYearMonth, intYear) -- yearMonth :: Int -> (Int, Int) script yearMonth on |λ|(intMonth) {intYear, intMonth} end |λ| end script lstYearMonth & ¬ map(yearMonth, my longMonthsStartingFriday(intYear)) end |λ| end script -- leanYear :: Int -> Bool script leanYear on |λ|(intYear) 0 = length of longMonthsStartingFriday(intYear) end |λ| end script set lstFullMonths to map(yearMonthString, ¬ foldl(addLongMonthsOfYear, {}, lstYears)) set lstLeanYears to filter(leanYear, lstYears) {{|number|:length of lstFullMonths}, ¬ {firstFive:(items 1 thru 5 of lstFullMonths)}, ¬ {lastFive:(items -5 thru -1 of lstFullMonths)}, ¬ {leanYearCount:length of lstLeanYears}, ¬ {leanYears:lstLeanYears}} end fiveWeekends -- longMonthsStartingFriday :: Int -> [Int] on longMonthsStartingFriday(intYear) -- startIsFriday :: Int -> Bool script startIsFriday on |λ|(iMonth) weekday of calendarDate(intYear, iMonth, 1) is Friday end |λ| end script filter(startIsFriday, [1, 3, 5, 7, 8, 10, 12]) end longMonthsStartingFriday -- calendarDate :: Int -> Int -> Int -> Date on calendarDate(intYear, intMonth, intDay) tell (current date) set {its year, its month, its day, its time} to ¬ {intYear, intMonth, intDay, 0} return it end tell end calendarDate -- GENERIC FUNCTIONS ---------------------------------------------------------- -- enumFromTo :: Enum a => a -> a -> [a] on enumFromTo(m, n) set {intM, intN} to {fromEnum(m), fromEnum(n)} if intM > intN then set d to -1 else set d to 1 end if set lst to {} if class of m is text then repeat with i from intM to intN by d set end of lst to chr(i) end repeat else repeat with i from intM to intN by d set end of lst to i end repeat end if return lst end enumFromTo -- fromEnum :: Enum a => a -> Int on fromEnum(x) set c to class of x if c is boolean then if x then 1 else 0 end if else if c is text then if x ≠ "" then id of x else missing value end if else x as integer end if end fromEnum -- filter :: (a -> Bool) -> [a] -> [a] on filter(f, xs) tell mReturn(f) set lst to {} set lng to length of xs repeat with i from 1 to lng set v to item i of xs if |λ|(v, i, xs) then set end of lst to v end repeat return lst end tell end filter -- foldl :: (a -> b -> a) -> a -> [b] -> a on foldl(f, startValue, xs) tell mReturn(f) set v to startValue set lng to length of xs repeat with i from 1 to lng set v to |λ|(v, item i of xs, i, xs) end repeat return v end tell end foldl -- map :: (a -> b) -> [a] -> [b] on map(f, xs) tell mReturn(f) set lng to length of xs set lst to {} repeat with i from 1 to lng set end of lst to |λ|(item i of xs, i, xs) end repeat return lst end tell end map -- Lift 2nd class handler function into 1st class script wrapper -- mReturn :: Handler -> Script on mReturn(f) if class of f is script then f else script property |λ| : f end script end if end mReturn