https://www.coursera.org/learn/programming-languages/home

B站搬运：

https://www.bilibili.com/video/BV1dL411j7L7

代码

(* problem 1 *)
fun is_older(date1: int*int*int, date2: int*int*int) =
if (#1 date1) < (#1 date2)
then true
else
if (#1 date1) = (#1 date2)
then
if (#2 date1) < (#2 date2)
then true
else
if (#2 date1) = (#2 date2)
then
if (#3 date1) < (#3 date2)
then true
else false
else false
else false

(* problem 2 *)
fun number_in_month(dates: (int*int*int) list, month: int) =
if null dates
then 0
else
let val month1 = (#2 (hd dates))
val cnt = number_in_month((tl dates), month)
in
if month1 = month
then 1 + cnt
else cnt
end

(* problem 3 *)
fun number_in_months(dates: (int*int*int) list, months: int list) =
if null months
then 0
else
if null dates
then 0
else number_in_month(dates, (hd months)) + number_in_months(dates, (tl months))

(* problem 4 *)
fun dates_in_month(dates: (int*int*int) list, month: int) =
if null dates
then []
else
let val month1 = (#2 (hd dates))
val result = dates_in_month((tl dates), month)
in
if month1 = month
then (hd dates)::result
else result
end

(* problem 5 *)
fun dates_in_months(dates: (int*int*int) list, months: int list) =
if null months
then []
else
if null dates
then []
else dates_in_month(dates, (hd months))@dates_in_months(dates, (tl months))

(* problem 6 *)
fun get_nth(strings: string list, n: int) =
if null strings
then ""
else
if n = 1
then (hd strings)
else get_nth((tl strings), n - 1)

(* problem 7 *)
fun date_to_string(date: int*int*int) =
let
val str_months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
val year = #1 date
val month = #2 date
val day = #3 date
in
get_nth(str_months, month) ^ " " ^ Int.toString(day) ^ ", " ^ Int.toString(year)
end

(* problem 8 *)
fun number_before_reaching_sum(sum: int, arr: int list) =
let
(* partial_sum < sum, partial_sum + (hd partial_arr) >= sum *)
fun helper(partial_sum: int, partial_arr: int list, n: int) =
if partial_sum >= sum
then 0
else
if null partial_arr
then 0
else
let
val partial_sum1 = partial_sum + (hd partial_arr)
in
if partial_sum1 >= sum
then n
else
helper(partial_sum1, (tl partial_arr), n + 1)
end
in
if (hd arr) >= sum
then 0
else helper(0, arr, 0)
end

(* problem 9 *)
fun what_month(day) =
let
val months = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
in
number_before_reaching_sum(day, months) + 1
end

(* problem 10 *)
fun month_range(day1: int, day2: int) =
if day1 > day2
then []
else
what_month(day1)::month_range(day1 + 1, day2)

(* problem 11 *)
fun oldest(dates: (int*int*int) list) =
let
fun helper(date: (int*int*int), remain_dates: (int*int*int) list) =
if null remain_dates
then date
else
let
val date1 = (hd remain_dates)
in
if is_older(date, date1)
then helper(date, (tl remain_dates))
else helper(date1, (tl remain_dates))
end
in
if null dates
then NONE
else SOME (helper((hd dates), (tl dates)))
end

(* problem 12 *)
fun remove_dup_month(months: int list) =
if null months
then []
else
let
fun contain(n: int, arr: int list) =
if null arr
then false
else
if n = (hd arr)
then true
else contain(n, (tl arr))
fun helper(month: int, cur_month: int list) =
if month > 12
then []
else
let
val res = helper(month + 1, cur_month)
in
if contain(month, cur_month)
then month::res
else res
end
in
helper(1, months)
end

fun number_in_months_challenge(dates: (int*int*int) list, months: int list) =
let
val months_no_dup = remove_dup_month(months)
in
number_in_months(dates, months_no_dup)
end

(* problem 13 *)
fun dates_in_months_challenge(dates: (int*int*int) list, months: int list) =
let
val months_no_dup = remove_dup_month(months)
in
dates_in_months(dates, months_no_dup)
end

fun reasonable_date(date: int*int*int) =
let
fun is_leap(year: int) =
if (year mod 400) = 0
then true
else
if ((year mod 100) <> 0) andalso ((year mod 4) = 0)
then true
else false
fun get_month_day(months: int list, n: int) =
if null months
then 0
else
if n = 1
then (hd months)
else get_month_day((tl months), n - 1)
fun helper(date: int*int*int) =
let
val year = #1 date
val month = #2 date
val day = #3 date
val months = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
in
if year = 0
then
false
else
if (month < 1) orelse (month > 12)
then false
else
if month = 2
then
if is_leap(year)
then
if day <= (get_month_day(months, month) + 1)
then true
else false
else
if day <= get_month_day(months, month)
then true
else false
else
if (day <= get_month_day(months, month))
then true
else false
end
in
helper(date)
end

测试

(* Homework1 Simple Test *)
(* These are basic test cases. Passing these tests does not guarantee that your code will pass the actual homework grader *)
(* To run the test, add a new line to the top of this file: use "homeworkname.sml"; *)
(* All the tests should evaluate to true. For example, the REPL should say: val test1 = true : bool *)
use "hw1.sml";

val test1_1 = is_older ((1,2,3),(2,3,4)) = true
val test1_2 = is_older ((1,2,3),(1,3,4)) = true
val test1_3 = is_older ((3,2,3),(2,3,4)) = false
val test1_4 = is_older ((1,2,3),(1,3,4)) = true
val test1_5 = is_older ((1,2,3),(1,2,4)) = true
val test1_6 = is_older ((1,2,5),(1,2,4)) = false
val test1_7 = is_older ((1,2,5),(1,2,5)) = false

val test2_1 = number_in_month ([(2012,2,28),(2013,12,1)],2) = 1
val test2_2 = number_in_month ([],2) = 0
val test2_3 = number_in_month ([(2012,2,28),(2013,12,1)],3) = 0

val test3_1 = number_in_months ([(2012,2,28),(2013,12,1),(2011,3,31),(2011,4,28)],[2,3,4]) = 3
val test3_2 = number_in_months ([(2012,2,28),(2013,12,1),(2011,3,31),(2011,4,28)],[]) = 0
val test3_3 = number_in_months ([],[2,3,4]) = 0

val test4_1 = dates_in_month ([(2012,2,28),(2013,12,1)],2) = [(2012,2,28)]
val test4_2 = dates_in_month ([(2012,2,28),(2013,12,1)],3) = []
val test4_3 = dates_in_month ([],3) = []

val test5_1 = dates_in_months ([(2012,2,28),(2013,12,1),(2011,3,31),(2011,4,28)],[2,3,4]) = [(2012,2,28),(2011,3,31),(2011,4,28)]
val test5_2 = dates_in_months ([(2012,2,28),(2013,12,1),(2011,3,31),(2011,4,28)],[]) = []
val test5_3 = dates_in_months ([],[2,3,4]) = []

val test6_1 = get_nth (["hi", "there", "how", "are", "you"], 2) = "there"
val test6_2 = get_nth ([], 2) = ""
val test6_3 = get_nth (["hi", "there", "how", "are", "you"], 100) = ""

val test7_1 = date_to_string (2013, 6, 1) = "June 1, 2013"
val test7_2 = date_to_string (2021, 12, 31) = "December 31, 2021"

val test8_1 = number_before_reaching_sum (10, [1,2,3,4,5]) = 3
val test8_2 = number_before_reaching_sum (10, [11,2,3,4,5]) = 0

val test9_1 = what_month 31 = 1
val test9_2 = what_month 59 = 2
val test9_3 = what_month 90 = 3
val test9_4 = what_month 120 = 4
val test9_5 = what_month 151 = 5
val test9_6 = what_month 181 = 6
val test9_7 = what_month 212 = 7
val test9_8 = what_month 243 = 8
val test9_9 = what_month 273 = 9
val test9_10 = what_month 304 = 10
val test9_11 = what_month 334 = 11
val test9_12 = what_month 365 = 12
val test9_13 = what_month 70 = 3

val test10_1 = month_range (31, 34) = [1,2,2,2]
val test10_2 = month_range (35, 34) = []

val test11 = oldest([(2012,2,28),(2011,3,31),(2011,4,28)]) = SOME (2011,3,31)

val test12_1 = number_in_months_challenge ([(2012,2,28),(2013,12,1),(2011,3,31),(2011,4,28)],[2,3,4]) = 3
val test12_2 = number_in_months_challenge ([(2012,2,28),(2013,12,1),(2011,3,31),(2011,4,28)],[]) = 0
val test12_3 = number_in_months_challenge ([],[2,3,4]) = 0
val test12_4 = number_in_months_challenge ([(2012,2,28),(2013,12,1),(2011,3,31),(2011,4,28)],[2,2,2,3,3,4]) = 3
val test12_5 = number_in_months_challenge ([(2012,2,28),(2013,12,1),(2011,3,31),(2011,4,28)],[]) = 0
val test12_6 = number_in_months_challenge ([],[2,3,3,4]) = 0
val test12_7 = dates_in_months_challenge ([(2012,2,28),(2013,12,1),(2011,3,31),(2011,4,28)],[2,3,4]) = [(2012,2,28),(2011,3,31),(2011,4,28)]
val test12_8 = dates_in_months_challenge ([(2012,2,28),(2013,12,1),(2011,3,31),(2011,4,28)],[]) = []
val test12_9 = dates_in_months_challenge ([],[2,3,4]) = []
val test12_10 = dates_in_months_challenge ([(2012,2,28),(2013,12,1),(2011,3,31),(2011,4,28)],[2,3,3,2,4]) = [(2012,2,28),(2011,3,31),(2011,4,28)]
val test12_11 = dates_in_months_challenge ([(2012,2,28),(2013,12,1),(2011,3,31),(2011,4,28)],[]) = []
val test12_12 = dates_in_months_challenge ([],[4,2,3,4,4]) = []
val test12_13 = remove_dup_month ([2,2,2,3,3,4]) = [2,3,4]

val test13_1 = reasonable_date (1900,2,29) = false
val test13_2 = reasonable_date (1904,2,29) = true
val test13_3 = reasonable_date (1904,0,29) = false
val test13_4 = reasonable_date (2021,13,29) = false
val test13_5 = reasonable_date (2021,12,31) = true
val test13_6 = reasonable_date (0,2,3) = false