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

本文主要是介绍Programming Languages A(Coursera / University of Washington) Assignment 2,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文件已上传到GitHub: 点这里
分数是80分(刚好通过)(用了一点限制函数)

第二次作业,主要是练习 pattern match
这真是很棒的feature,能够很好的控制scope,达到closure效果
也能领会ml的 referential transparency、lazy evaluation、statically typed 等 feature
在和别人交流的过程中,还学到了guard,存在ocaml,F#中的一种特性,但是sml没有,所以sml不内置支持range match 如下图所示

在这里插入图片描述

文章目录

    • 函数签名
    • 第一题
    • 第二题
    • 第三题

函数签名

第二次作业非challenge部分是写11个函数
分别是

val all_except_option = fn : string * string list -> string list option
val get_substitutions1 = fn : string list list * string -> string list
val get_substitutions2 = fn : string list list * string -> string list
val similar_names = fn : string list list * {first:string, last:string, middle:string}
-> {first:string, last:string, middle:string} list
val card_color = fn : card -> color
val card_value = fn : card -> int
val remove_card = fn : card list * card * exn -> card list
val all_same_color = fn : card list -> bool
val sum_cards = fn : card list -> int
val score = fn : card list * int -> int
val officiate = fn : card list * move list * int -> int

第一题

This problem involves using first-name substitutions to come up with alternate names. For example,
Fredrick William Smith could also be Fred William Smith or Freddie William Smith. Only part (d) is
specifically about this, but the other problems are helpful.
(a) Write a function all_except_option, which takes a string and a string list. Return NONE if the
string is not in the list, else return SOME lst where lst is identical to the argument list except the string
is not in it. You may assume the string is in the list at most once. Use same_string, provided to you,
to compare strings. Sample solution is around 8 lines.
(b) Write a function get_substitutions1, which takes a string list list (a list of list of strings, the
substitutions) and a string s and returns a string list. The result has all the strings that are in
some list in substitutions that also has s, but s itself should not be in the result. Example:
get_substitutions1([["Fred","Fredrick"],["Elizabeth","Betty"],["Freddie","Fred","F"]],
"Fred")
(* answer: ["Fredrick","Freddie","F"] *)
Assume each list in substitutions has no repeats. The result will have repeats if s and another string are
both in more than one list in substitutions. Example:
get_substitutions1([["Fred","Fredrick"],["Jeff","Jeffrey"],["Geoff","Jeff","Jeffrey"]],
"Jeff")
(* answer: ["Jeffrey","Geoff","Jeffrey"] *)
Use part (a) and ML’s list-append (@) but no other helper functions. Sample solution is around 6 lines.
(c) Write a function get_substitutions2, which is like get_substitutions1 except it uses a tail-recursive
local helper function.
(d) Write a function similar_names, which takes a string list list of substitutions (as in parts (b) and
(c)) and a full name of type {first:string,middle:string,last:string} and returns a list of full
names (type {first:string,middle:string,last:string} list). The result is all the full names you
can produce by substituting for the first name (and only the first name) using substitutions and parts (b)
or (c). The answer should begin with the original name (then have 0 or more other names). Example:
similar_names([["Fred","Fredrick"],["Elizabeth","Betty"],["Freddie","Fred","F"]],
{first="Fred", middle="W", last="Smith"})
(* answer: [{first="Fred", last="Smith", middle="W"},
{first="Fredrick", last="Smith", middle="W"},
{first="Freddie", last="Smith", middle="W"},
{first="F", last="Smith", middle="W"}] *)
Do not eliminate duplicates from the answer. Hint: Use a local helper function. Sample solution is
around 10 lines.

(*1.a*)
fun all_except_option(str,xs) =case xs of[] => NONE| y::ys' => if same_string(str,y) thenif null ys'thenSOME []elseSOME ys'elsecase all_except_option(str,ys') ofNONE => NONE|_  => let val tmp = all_except_option(str,ys')inSOME (y::(valOf tmp))end(*1.b*)
fun get_substitutions1(li:(string list)list,s) =case li of[] => []| y::ys' =>let val tmp = all_except_option(s,y)inif isSome tmpthen (valOf tmp)@get_substitutions1(ys',s)else []@get_substitutions1(ys',s)end (*1.c It's a trade-off*)
fun get_substitutions2(lli:(string list)list,ss:string) =let fun helper(li,s)=case li of[] => (tl s)| y::ys' => let val tmp = all_except_option(hd s,y)inif isSome tmpthen helper(ys',s@(valOf tmp))else helper(ys',s)endinhelper(lli,[ss])end(*1.d *)(*val similar_names = fn : string list list * {first:string, last:string, middle:string}-> {first:string, last:string, middle:string} list*)fun similar_names(li,s:{first:string, last:string, middle:string})=let fun fix(xs,s:{first:string, last:string, middle:string}) =case xs of[] => []| x::xs' => [case s of {first=_,last=b,middle=c}=>{first=x,last=b,middle=c}]@fix(xs',s)in[s]@fix(get_substitutions1(li,(case s of {first=a,last=_,middle=_}=>a)),s)end(*
card_color = fn : card -> color
card_value = fn : card -> int
remove_card = fn : card list * card * exn -> card list
all_same_color = fn : card list -> bool
sum_cards = fn : card list -> int
score = fn : card list * int -> int
officiate = fn : card list * move list * int -> int
*)

第二题

This problem involves a solitaire card game invented just for this question. You will write a program that
tracks the progress of a game; writing a game player is a challenge problem. You can do parts (a){(e) before
understanding the game if you wish.
A game is played with a card-list and a goal. The player has a list of held-cards, initially empty. The player
makes a move by either drawing, which means removing the first card in the card-list from the card-list and
adding it to the held-cards, or discarding, which means choosing one of the held-cards to remove. The game
ends either when the player chooses to make no more moves or when the sum of the values of the held-cards
is greater than the goal.
The objective is to end the game with a low score (0 is best). Scoring works as follows: Let sum be the sum
of the values of the held-cards. If sum is greater than goal, the preliminary score is three times (sum−goal),
else the preliminary score is (goal − sum). The score is the preliminary score unless all the held-cards are
the same color, in which case the score is the preliminary score divided by 2 (and rounded down as usual
with integer division; use ML’s div operator).
(a) Write a function card_color, which takes a card and returns its color (spades and clubs are black,
diamonds and hearts are red). Note: One case-expression is enough.
(b) Write a function card_value, which takes a card and returns its value (numbered cards have their
number as the value, aces are 11, everything else is 10). Note: One case-expression is enough.
(c) Write a function remove_card, which takes a list of cards cs, a card c, and an exception e. It returns a
list that has all the elements of cs except c. If c is in the list more than once, remove only the first one.
If c is not in the list, raise the exception e. You can compare cards with =.
(d) Write a function all_same_color, which takes a list of cards and returns true if all the cards in the
list are the same color. Hint: An elegant solution is very similar to one of the functions using nested
pattern-matching in the lectures.
(e) Write a function sum_cards, which takes a list of cards and returns the sum of their values. Use a locally
defined helper function that is tail recursive. (Take \calls use a constant amount of stack space" as a
requirement for this problem.)
(f) Write a function score, which takes a card list (the held-cards) and an int (the goal) and computes
the score as described above.
(g) Write a function officiate, which \runs a game." It takes a card list (the card-list) a move list
(what the player \does" at each point), and an int (the goal) and returns the score at the end of the
game after processing (some or all of) the moves in the move list in order. Use a locally defined recursive
helper function that takes several arguments that together represent the current state of the game. As
described above:
• The game starts with the held-cards being the empty list.
• The game ends if there are no more moves. (The player chose to stop since the move list is empty.)
• If the player discards some card c, play continues (i.e., make a recursive call) with the held-cards
not having c and the card-list unchanged. If c is not in the held-cards, raise the IllegalMove
exception.
• If the player draws and the card-list is (already) empty, the game is over. Else if drawing causes
the sum of the held-cards to exceed the goal, the game is over (after drawing). Else play continues
with a larger held-cards and a smaller card-list.
Sample solution for (g) is under 20 lines.
(*2.a*)fun card_color(cd:card) =case cd of(Spades,_) => Black| (Clubs,_) => Black| (Diamonds,_) => Red| (Hearts,_) => Red(*2.b*)
(*	card_value = fn : card -> int	*)	  
fun card_value(cd:card):int =case cd of(_,Num(a)) => a| (_,Ace) => 11| (_,_) => 10(*2.c*)fun remove_card(xs:card list,c,e)=let fun check(xs:card list,c)=case xs of[] => false| y::ys' => if y=c then trueelse check(ys',c);fun getValue(xs:card list,c)=case xs of[] => []| y::ys' => if y=c then ys'elsey::getValue(ys',c)inlet val flag = check(xs,c)inif false=flag thenraise eelse getValue(xs,c)endend(*2.d*)
fun all_same_color(xs:card list)=case xs of[] => true| y::ys' => case ys' of[] => true| k::ks' => if  card_color(y)=card_color(k)thenall_same_color(ys')elsefalse;(*2.e*)fun sum_cards(li:card list) =let fun helper(li:card list,sum:int)=case li of[] => sum| y::ys' => helper(ys',sum+(card_value(y)))inhelper(li,0)end;(*2.f score = fn : card list * int -> int
officiate = fn : card list * move list * int -> int*)fun score(li:card list,goal:int ) =let val sum = sum_cards(li);val jud = all_same_color(li)inlet val pre_score =(if sum>goal then 3*(sum-goal) else (goal-sum))incase jud offalse => pre_score| true =>  pre_score div 2endend
; (*2.g*)fun officiate(li:card list,nx:move list,goal : int) =letfun helper(tmpList:card list,append:card) = tmpList@[append];fun runGame(lli:card list,nnx:move list,myList:card list) =if sum_cards(myList)>goal then score(myList,goal)elsecase nnx of[] =>  score(myList,goal)(*no operation*)| y::ys' => case y ofDraw =>  (case lli of[] => score(myList,goal) (*no card*)| z :: zs' => runGame(zs',ys',myList@[(z:card)]) (*continue*))| Discard(a,b) =>  runGame(lli,ys',remove_card(myList,(a,b),IllegalMove))inrunGame(li,nx,[])end

第三题

Challenge Problems:
(a) Write score_challenge and officiate_challenge to be like their non-challenge counterparts except
each ace can have a value of 1 or 11 and score_challenge should always return the least (i.e., best)
possible score. (Note the game-ends-if-sum-exceeds-goal rule should apply only if there is no sum that
is less than or equal to the goal.) Hint: This is easier than you might think.
(b) Write careful_player, which takes a card-list and a goal and returns a move-list such that calling
officiate with the card-list, the goal, and the move-list has this behavior:
• The value of the held cards never exceeds the goal.
• A card is drawn whenever the goal is more than 10 greater than the value of the held cards. As a
detail, you should (attempt to) draw, even if no cards remain in the card-list.
• If a score of 0 is reached, there must be no more moves.
• If it is possible to reach a score of 0 by discarding a card followed by drawing a card, then this
must be done. Note careful_player will have to look ahead to the next card, which in many card
games is considered \cheating." Also note that the previous requirement takes precedence: There
must be no more moves after a score of 0 is reached even if there is another way to get back to 0.
Notes:
• There may be more than one result that meets the requirements above. The autograder should
work for any correct strategy | it checks that the result meets the requirements.
• This problem is not a continuation of problem 3(a). In this problem, all aces have a value of 11.

这篇关于Programming Languages A(Coursera / University of Washington) Assignment 2的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/924018

相关文章

2014 Multi-University Training Contest 8小记

1002 计算几何 最大的速度才可能拥有无限的面积。 最大的速度的点 求凸包, 凸包上的点( 注意不是端点 ) 才拥有无限的面积 注意 :  凸包上如果有重点则不满足。 另外最大的速度为0也不行的。 int cmp(double x){if(fabs(x) < 1e-8) return 0 ;if(x > 0) return 1 ;return -1 ;}struct poin

2014 Multi-University Training Contest 7小记

1003   数学 , 先暴力再解方程。 在b进制下是个2 , 3 位数的 大概是10000进制以上 。这部分解方程 2-10000 直接暴力 typedef long long LL ;LL n ;int ok(int b){LL m = n ;int c ;while(m){c = m % b ;if(c == 3 || c == 4 || c == 5 ||

2014 Multi-University Training Contest 6小记

1003  贪心 对于111...10....000 这样的序列,  a 为1的个数,b为0的个数,易得当 x= a / (a + b) 时 f最小。 讲串分成若干段  1..10..0   ,  1..10..0 ,  要满足x非递减 。  对于 xi > xi+1  这样的合并 即可。 const int maxn = 100008 ;struct Node{int

2015多校联合训练第一场Assignment(hdu5289)三种解法

题目大意:给出一个数列,问其中存在多少连续子序列,子序列的最大值-最小值< k 这题有三种解法: 1:单调队列,时间复杂度O(n) 2:RMQ+二分,时间复杂度O(nlogn) 3:RMQ+贪心,时间复杂度O(nlogn) 一:RMQ+二分 RMQ维护最大值,最小值,枚举左端点i,二分找出最远的符合的右端点j,答案就是ans += j - i+1;(手推一下就知道) 比如1 2 3

Accept CS Ph.D. Offer from Stony Brook University,去SUNY石溪大学的CS Ph.D.啦

前言:在2017年3月24日,正式决定去纽约州立大学石溪分校(State University of New York, Stony Brook,简称石溪大学),CS Ph.D. 项目。本科直博,DIY申请,全额奖学金,第一年5.1万美元(免学费2.2万,2017 fall, 2018 spring 的TA 1.93万,2018 summer RA 1万,没有 Fellowship) Abs

2015 Multi-University Training Contest 5 1009 MZL#39;s Border

MZL's Border  Problem's Link:  http://acm.hdu.edu.cn/showproblem.php?pid=5351   Mean:  给出一个类似斐波那契数列的字符串序列,要你求给出的f[n]字符串中截取前m位的字符串s中s[1...i] = s[s.size()-i+1....s.size()]的最大长度。 analyse:   过计算

Nordic Collegiate Programming ContestNCPC 2021

Date:October 9, 2021 Dashboard - 2021-2022 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2021) - Codeforces Problem - C - Codeforces--Customs ControlsProblem - C - Codeforces- 题意:给定一个n个点,m条边

纪念一下第二个assignment 100分

感悟就是:坚持,才能从good到great。精益求精就是要不断打磨产品。 Princeton的课就是好,一个作业可以牵扯到很多算法。复习了shuffle算法和Resevoir Sampling算法,还有linkedin,array implement deque,iterator的用法,确实不错的课程,经典就是经典!刷题不在乎刷题数目多少,而在于刷背后知识点的深度和广度。加油!我觉得我刷完A

纪念一下自己的Coursera Princeton Algorithm的课程第一个assignment

今天终于完成了第一个Union-Find的assignment,之前觉得特别的难,可是最后自己也搞定了。而且是100%满分。 自己后来plot了一下自己的分数,也许这就是学习曲线吧。刚开始不会,到后来中期显著提高,但是要到100%,那就要经历更多的波折,甚至是下降都有可能。最后才能达到100%满分。 我觉得最有用的还是下面这段源代码: /*************************

2014 Multi-University Training Contest 1/HDU4861_Couple doubi(数论/规律)

解题报告 两人轮流取球,大的人赢,,, 贴官方题解,,,反正我看不懂,,,先留着理解 关于费马小定理 关于原根 找规律找到的,,,sad,,, 很容易找到循环节为p-1,每一个循环节中有一个非零的球,所以只要判断有多少完整循环节,在判断奇偶,,, #include <iostream>#include <cstdio>#include <cstring>