Programming Languages A(Coursera / University of Washington) Assignment 1

Coursera有这门课的全部资料,就不放链接了:)
第一个课设一共13道题,都是sml编程题目 challenge没有时间就跳过了

原文件已上传到GitHub: 点这里
分数是90分

  1. Write a function is_older that takes two dates and evaluates to true or false. It evaluates to true if the first argument is a date that comes before the second argument. (If the two dates are the same, the result is false.)
    此处注意调用格式为: is_older([1999,08,28],[2000,08,28]);
fun is_older(xs : int list, ys : int list) =
    if null xs
    then true
    else
	if (hd xs)>(hd ys)
	then false
	else is_older(tl xs,tl ys)
  1. Write a function number_in_month that takes a list of dates and a month (i.e., an int) and returns
    how many dates in the list are in the given month.
fun number_in_month(dates : (int*int*int) list , months : int) =
    if null dates
    then 0
    else
	if #2(hd dates)=months
	then 1+number_in_month(tl dates,months)
	else number_in_month(tl dates,months)

这种格式是错误的:(#不可对变参列表使用)

fun number_in_months_(dates : int list ,  months : int) =
    #months(dates)
  1. Write a function number_in_months that takes a list of dates and a list of months (i.e., an int list)
    and returns the number of dates in the list of dates that are in any of the months in the list of months.
    Assume the list of months has no number repeated. Hint: Use your answer to the previous problem.
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)
  1. Write a function dates_in_month that takes a list of dates and a month (i.e., an int) and returns a
    list holding the dates from the argument list of dates that are in the month. The returned list should
    contain dates in the order they were originally given.
fun dates_in_month(dates : (int*int*int) list , months : int) =
    if null dates
    then []
    else
	if #2(hd dates)=months
	then (hd dates)::dates_in_month(tl dates,months)
	else dates_in_month(tl dates,months)
  1. Write a function dates_in_months that takes a list of dates and a list of months (i.e., an int list)
    and returns a list holding the dates from the argument list of dates that are in any of the months in
    the list of months. Assume the list of months has no number repeated. Hint: Use your answer to the
    previous problem and SML’s list-append operator (@).
fun dates_in_months(dates : (int*int*int) list , months : int list) =
    if null months
    then []
    else
	dates_in_month(tl dates,hd months)@dates_in_months(dates,tl months)
  1. Write a function get_nth that takes a list of strings and an int n and returns the nth element of the
    list where the head of the list is 1st. Do not worry about the case where the list has too few elements:your function may apply hd or tl to the empty list in this case, which is okay
fun get_nth(strings : string list , n : int) =
    if n = 1
    then (hd strings)
    else
	get_nth(tl strings , n-1)
  1. Write a function date_to_string that takes a date and returns a string of the form January 20, 2013(for example). Use the operator ^ for concatenating strings and the library function Int.toString for converting an int to a string. For producing the month part, do not use a bunch of conditionals.
    Instead, use a list holding 12 strings and your answer to the previous problem. For consistency, put a comma following the day and use capitalized English month names: January, February, March, April,May, June, July, August, September, October, November, December.
fun date_to_string(year : int , month : int , day : int) =
    case month of
	1 =>  "January "  ^Int.toString(day)^", "^Int.toString(year)
      | 2 =>  "February " ^Int.toString(day)^", "^Int.toString(year)
      | 3 =>  "March "    ^Int.toString(day)^", "^Int.toString(year)
      | 4 =>  "April "    ^Int.toString(day)^", "^Int.toString(year)
      | 5 =>  "May "      ^Int.toString(day)^", "^Int.toString(year)
      | 6 =>  "June "     ^Int.toString(day)^", "^Int.toString(year)
      | 7 =>  "July "     ^Int.toString(day)^", "^Int.toString(year)
      | 8 =>  "August "   ^Int.toString(day)^", "^Int.toString(year)
      | 9 =>  "September "^Int.toString(day)^", "^Int.toString(year)
      | 10 => "October "  ^Int.toString(day)^", "^Int.toString(year)
      | 11 => "November " ^Int.toString(day)^", "^Int.toString(year)
      | 12 => "December " ^Int.toString(day)^", "^Int.toString(year);
  1. Write a function number_before_reaching_sum that takes an int called sum, which you can assume
    is positive, and an int list, which you can assume contains all positive numbers, and returns an int.
    You should return an int n such that the first n elements of the list add to less than sum, but the first
    n + 1 elements of the list add to sum or more. Assume the entire list sums to more than the passed in
    value; it is okay for an exception to occur if this is not the case.
fun number_before_reaching_sum(sum : int ,lists : int list) =
    if null lists orelse sum <= (hd lists) 
    then 1
    else number_before_reaching_sum(sum-(hd lists),(tl lists))+1
  1. Write a function what_month that takes a day of year (i.e., an int between 1 and 365) and returns
    what month that day is in (1 for January, 2 for February, etc.). Use a list holding 12 integers and your
    answer to the previous problem.
fun what_month(day : int) =
   number_before_reaching_sum(day,[31,28,31,30,31,30,31,31,30,31,30,31]);
  1. Write a function month_range that takes two days of the year day1 and day2 and returns an int list
    [m1,m2,…,mn] where m1 is the month of day1, m2 is the month of day1+1, …, and mn is the month
    of day day2. Note the result will have length day2 - day1 + 1 or length 0 if day1>day2.
fun what_range(day1 : int , day2 : int) =
    if day1 > day2
    then []
    else what_month(day1)::what_range(day1+1,day2);
  1. Write a function oldest that takes a list of dates and evaluates to an (intintint) option. It
    evaluates to NONE if the list has no dates and SOME d if the date d is the oldest date in the list.
fun oldest(d : (int*int*int) list) = 
    if null d
    then NONE
    else
	let val tmp_ans = oldest(tl d)
	in
	    if isSome tmp_ans andalso (#1(valOf tmp_ans)) > (#1(hd d)) andalso (#2(valOf tmp_ans)) > (#2(hd d)) andalso (#3(valOf tmp_ans)) > (#3(hd d))
	    then tmp_ans 
	    else SOME (hd d)
	end
  1. Challenge Problem: Write functions number_in_months_challenge and dates_in_months_challenge
    that are like your solutions to problems 3 and 5 except having a month in the second argument multiple
    times has no more effect than having it once. (Hint: Remove duplicates, then use previous work.)
(* quadratic algorithm rather than sorting which is nlog n *)
fun mem(x : int, xs : int list) =
    not (null xs) andalso (x = hd xs orelse mem(x, tl xs))
fun remove_duplicates(xs : int list) =
    if null xs
    then []
    else
        let 
            val tl_ans = remove_duplicates (tl xs)
        in
            if mem(hd xs, tl_ans)
            then tl_ans
            else (hd xs)::tl_ans
        end

fun number_in_months_challenge(dates : (int * int * int) list, months : int list) =
    number_in_months(dates, remove_duplicates months)

fun dates_in_months_challenge (dates : (int * int * int) list, months : int list) =
    dates_in_months(dates, remove_duplicates months)

fun reasonable_date (date : int * int * int) =
    let    
        fun get_nth (lst : int list, n : int) =
        if n=1
        then hd lst
        else get_nth(tl lst, n-1)
        val year  = #1 date
        val month = #2 date
        val day   = #3 date
        val leap  = year mod 400 = 0 orelse (year mod 4 = 0 andalso year mod 100 <> 0)
        val feb_len = if leap then 29 else 28
        val lengths = [31,feb_len,31,30,31,30,31,31,30,31,30,31]
    in
        year > 0 andalso month >= 1 andalso month <= 12
        andalso day >= 1 andalso day <= get_nth(lengths,month)
    end
  1. Challenge Problem: Write a function reasonable_date that takes a date and determines if it
    describes a real date in the common era. A \real date" has a positive year (year 0 did not exist), a
    month between 1 and 12, and a day appropriate for the month. Solutions should properly handle leap
    years. Leap years are years that are either divisible by 400 or divisible by 4 but not divisible by 100.
    (Do not worry about days possibly lost in the conversion to the Gregorian calendar in the Late 1500s.)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值