fun is_older (date1 : int*int*int, date2 : int*int*int)= let fun toNumber (date : int*int*int) = (#1 date)*10000 + (#2 date)*100 + (#3 date) in if (toNumber(date1) < toNumber(date2)) then true else false end fun number_in_month (datelist : (int*int*int) list, month : int) = let fun isMonth (date : int*int*int) = if ((#2 date) = month) then 1 else 0 in if null datelist then 0 else isMonth(hd(datelist)) + number_in_month(tl datelist, month) end fun number_in_months (datelist : (int*int*int) list, months : int list) = let fun isMonths (date : int*int*int, months : int list) = let fun isMonth (date : int*int*int, month : int) = if ((#2 date) = month) then 1 else 0 in if null months then 0 else isMonth(date, hd(months)) + isMonths(date, tl months) end in if null datelist then 0 else isMonths(hd(datelist), months) + number_in_months(tl datelist, months) end fun dates_in_month (datelist : (int*int*int) list, month : int) = let fun isDateInMonth (date : int*int*int) = if ((#2 date) = month) then [date] else [] in if null datelist then [] else isDateInMonth(hd(datelist)) @ dates_in_month(tl datelist, month) end fun dates_in_months (datelist : (int*int*int) list, months : int list) = let fun isDatesInMonths (date : int*int*int, months : int list) = let fun isDateInMonth (date : int*int*int, month : int) = if ((#2 date) = month) then [date] else [] in if null months then [] else isDateInMonth(date, hd(months)) @ isDatesInMonths(date, tl months) end in if null datelist then [] else isDatesInMonths(hd(datelist), months) @ dates_in_months(tl datelist, months) end fun get_nth (stringlist : string list, n : int) = if (n = 1) then hd(stringlist) else get_nth(tl stringlist, n - 1); fun date_to_string (date : int*int*int) = let val MonthList = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; in get_nth(MonthList, #2 date) ^ " " ^ Int.toString(#3 date) ^ ", " ^ Int.toString(#1 date) end fun number_before_reaching_sum (sum : int, datalist : int list) = if (sum <= hd (datalist)) then 0 else 1 + number_before_reaching_sum (sum - hd (datalist), tl datalist); fun what_month (day : int) = let val daysInMonthList = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] in number_before_reaching_sum (day, daysInMonthList) + 1 end fun month_range (day1 : int, day2 : int) = if (day1 > day2) then [] else [what_month(day1)] @ month_range(day1 + 1, day2); fun oldest (datelist : (int*int*int) list) = if null datelist then NONE else let fun oldest_nonempty (xs : (int*int*int) list ) = if null (tl xs) then hd xs else let val tl_ans = oldest_nonempty(tl xs) in if is_older(hd xs, tl_ans) then hd xs else tl_ans end in SOME(oldest_nonempty datelist) end fun unique (months : int list) = let fun loop (result : int list, months : int list) = if null months then result else let fun contains (result : int list, month : int) = if null result then false else if (hd result = month) then true else contains(tl result, month) in if (contains (result,(hd months))) then loop(result, tl months) else loop((hd months) :: result, tl months) end in loop([], months) end fun number_in_months_challenge (datelist : (int*int*int) list, months : int list) = number_in_months (datelist, unique(months)) fun dates_in_months_challenge (datelist : (int*int*int) list, months : int list) = dates_in_months (datelist, unique(months))
Test Code:
val is_older_Test = is_older((1997, 1, 11), (1997, 2, 1)); val number_in_month_test = number_in_month([(1997, 5, 11), (1999, 6, 11), (1991, 5, 21), (1992, 7, 11), (1993, 5, 11), (1991, 11, 11), (1997, 1, 1), (1992, 5, 13), (1998, 9, 30)], 5); val number_in_months_test = number_in_months([(1997, 5, 11), (1999, 6, 11), (1991, 5, 21), (1992, 7, 11), (1993, 5, 11), (1991, 11, 11), (1997, 1, 1), (1992, 5, 13), (1998, 9, 30)], [5, 6]); val dates_in_month_test = dates_in_month([(1997, 5, 11), (1999, 6, 11), (1991, 5, 21), (1992, 7, 11), (1993, 5, 11), (1991, 11, 11), (1997, 1, 1), (1992, 5, 13), (1998, 9, 30)], 5); val dates_in_months_test = dates_in_months([(1997, 5, 11), (1999, 6, 11), (1991, 5, 21), (1992, 7, 11), (1993, 5, 11), (1991, 11, 11), (1997, 1, 1), (1992, 5, 13), (1998, 9, 30)], [5, 6]); val get_nth_test = get_nth(["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] , 4); val date_to_string_test = date_to_string((2013, 1, 20)); val number_before_reaching_sum_test = number_before_reaching_sum (100, [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]); val what_month_test = what_month(32); val month_range_test = month_range(28, 33); val oldest_test = oldest([(1997, 5, 11), (1999, 6, 11), (1991, 5, 21), (1992, 7, 11), (1993, 5, 11), (1991, 11, 11), (1997, 1, 1), (1992, 5, 13), (1998, 9, 30)]); val oldest_test1 = oldest []; val number_before_reaching_sum_test = number_before_reaching_sum (1, [2]); val number_before_reaching_sum_test = number_before_reaching_sum (5, [3,1,2]); val number_before_reaching_sum_test = number_before_reaching_sum (5, [3,2,2]); val number_before_reaching_sum_test = number_before_reaching_sum (4, [1,4,1,1]); val number_before_reaching_sum_test = number_before_reaching_sum (6, [4,1,1,1]); val number_before_reaching_sum_test = number_before_reaching_sum (10, [1,2,3,4,5]);