-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhw1.sml
More file actions
154 lines (145 loc) · 3.8 KB
/
hw1.sml
File metadata and controls
154 lines (145 loc) · 3.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
(*1*)
fun is_older(date_1 : int * int * int, date_2 : int * int * int) =
if (#1 date_1)<(#1 date_2)
then true
else if (#1 date_1)=(#1 date_2) andalso (#2 date_1)<(#2 date_2)
then true
else if (#1 date_1)=(#1 date_2) andalso (#2 date_1)=(#2 date_2) andalso (#3 date_1)<(#3 date_2)
then true
else false
(*2*)
fun number_in_month(dates:(int * int * int) list,month:int) =
if null dates
then 0
else if #2 (hd dates) <> month
then number_in_month(tl dates,month)
else number_in_month(tl dates,month) + 1
(*3*)
fun number_in_months(dates:(int * int * int) list , months:int list) =
if null months
then 0
else number_in_month(dates,hd months) + number_in_months(dates,tl months)
(*4*)
fun dates_in_month(dates:(int * int * int) list,month:int) =
if null dates
then []
else if #2 (hd dates) <> month
then dates_in_month(tl dates,month)
else hd dates::dates_in_month(tl dates,month)
(*5*)
fun dates_in_months(dates:(int * int * int) list,months:int list) =
if null months
then []
else dates_in_month(dates,hd months) @ dates_in_months(dates,tl months)
(*6*)
fun get_nth(s:string list, n:int) =
if n = 1
then hd s
else get_nth(tl s,n-1)
(*7*)
fun date_to_string(date:int * int * int) =
let
val months = ["January","February","March","April","May","June","July","August","September","October","November","December"]
in
get_nth(months,#2 date) ^" "^ Int.toString(#3 date) ^", "^Int.toString(#1 date)
end
(*8*)
fun number_before_reaching_sum(sum:int,nx:int list) =
if sum > 0 andalso sum - hd nx <= 0
then 0
else number_before_reaching_sum(sum - hd nx,tl nx) + 1
(*9*)
fun what_month(day:int) =
let
val months = [31,28,31,30,31,30,31,31,30,31,30,31]
in
number_before_reaching_sum(day,months) + 1
end
(*10*)
fun month_range(day1:int,day2:int) =
let
val months = [31,28,31,30,31,30,31,31,30,31,30,31]
in
if day1 > day2
then []
else what_month(day1)::month_range(day1 + 1,day2)
end
(*11*)
fun oldest(dates:(int * int * int) list) =
if null dates
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 dates)
end
(*12*)
fun number_in_months_challenge(dates:(int * int * int) list , months:int list) =
let
fun remove(key:int,xs:int list) =
if null xs
then []
else if hd xs = key
then remove(key,tl xs)
else hd xs::remove(key,tl xs)
fun removeDup(xs:int list) =
if null xs
then []
else hd xs::removeDup(remove(hd xs,tl xs))
in
number_in_months(dates,removeDup(months))
end
fun dates_in_months_challenge(dates:(int * int * int) list , months:int list) =
let
fun remove(key:int,xs:int list) =
if null xs
then []
else if hd xs = key
then remove(key,tl xs)
else hd xs::remove(key,tl xs)
fun removeDup(xs:int list) =
if null xs
then []
else hd xs::removeDup(remove(hd xs,tl xs))
in
dates_in_months(dates,removeDup(months))
end
(*13*)
fun reasonable_date(date:int * int * int) =
let
fun isLeap(y:int) =
if y mod 4 = 0 andalso y mod 100 <> 0
then true
else y mod 400 = 0
val months = [31,28,31,30,31,30,31,31,30,31,30,31]
fun max_date(month:int,xs:int list) =
if month = 1
then hd xs
else max_date(month - 1,tl xs)
in
if #1 date <= 0
then false
else if #2 date <= 0 orelse #2 date > 12
then false
else
if isLeap(#1 date) andalso #2 date = 2
then
if #3 date <= 0 orelse #3 date > max_date(#2 date,months) + 1
then false
else true
else
if #3 date < 0 orelse #3 date > max_date(#2 date,months)
then false
else true
end