#lang racket ; CS 60 Assignment 1 Functional Programming Warmup 100 points total ; ; Author: Always_replace_this_with_your_own_name ; ; ALWAYS: put your own name after the header. ; ; Due Wed. 8 September 2010 at 11:59 p.m. at the web submission site: ; ; http://www.cs.hmc.edu/~submissions/submissions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ABSOLUTE REQUIREMENT: ; ; ; ; All answers MUST be use pure functional programming. ; ; ; ; Do not use assignment! ; ; Do not use conventional iteration. It isn't needed. ; ; The emphasis here is on constructing and composing functions. Non-compliant ; ; solutions will be counted as wrong. If you don't know how to approach a ; ; problem in the prescribed way, please seek help at your earliest opportunity.; ; ; ; Include comments and use meaningful identifiers where possible. ; ; Make your solutions elegant and clear as possible. ; ; We are interested in style, rather than simply answers. ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (require htdp/testing) ; Incant to get check-expect, check-within, generate-report ; IMPORTANT: ; ; The first time you use Dr. Racket, go to the menu bar, select Language, ; then select "Use the language declared in the source." ; ; Add your solution definitions to this file, by replacing the placeholder ; definitions, such as 0, with your own expressions. ; Submit the whole file when you are happy with the results. ; You may submit multiple times. Only the last submission will be graded. ; ; When run as is, all tests will fail. By replacing the definitions ; with correct ones, you should gradually get more tests to succeed. ; Eventually all tests should succeed. ; ; We provide at least one unit test for every function. You may wish to add ; some more tests of your own, to check yourself. You may leave your unit tests ; in the submitted file. ; ; We will be testing your definitions on examples that you haven't seen, so ; the more testing you do to enhance your confidence in the solutions, the better. ; ; You do not have to worry about checking for malformed input. We will not be ; using any test cases such as that. ; ; You should pay attention to elegance, readability, and comments where needed. ; Formatting should be straightforward if you use Dr. Racket, since it indents ; for you. ; DO NOT, under any circumstances, present a large definition on just a single line. ; We hate this, and will ream your score for doing it. ; Ideally our lines are at most 80 characters long, but some of these go to 90 or so. ; Try not to use more than that. Your code should be viewable on a standard ; 8.5 x 11 sheet in portrait mode, without any line wrapping. ; Problem 1: [10 points] ; ; Heron's elformula for the area of a triangle given its three sides is ; a beautiful little formula. You find its definition on the wikipedia ; http://en.wikipedia.org/wiki/Heron%27s_formula ; ; Devise a comparably beautiful Racket function 'heron' with three arguments ; that computes the area based on this formula. Use a 'let' for the value ; of s so that you don't repeat sub-expressions. The built-in 'sqrt' can be ; used to extract the square root. (define (heron a b c) 0) ;; Replace with the correct definition ; Unit tests for heron (check-expect (heron 3 4 5) 6) (check-expect (heron 12 13 5) 30) (check-expect (heron 42 29 29) 420) (check-within (heron 1e10 1e10 1) 5e9 1) (check-within (heron 1 1 1) (/ (sqrt 3) 4) 1e-16) ; Note that we use check-expect when answers can be compared exactly (e.g. integers). ; When floating point (i.e. scientific notation, such as 1e10) is involved, Racket ; will not let you use check-expect. Instead, use check-within, which has a third ; argument, the tolerance allowed for the answer. ; Use a 'let to avoid recomputation. ; Problem 2: [20 points] ; ; Look up Zeller's congruence in the wikipedia. This is a formula for finding the day ; of the week of any day in the Gregorian calendar (the calendar we usually use) given the ; year, month, and date. Give a Racket definition of function 'zeller', wherein the ; year, month, and day are numbers, as indicated on the web page, and the returned value ; is the number of the day of a week, starting with 0 for Saturday, 1 for Sunday, etc. ; Note that the translation of "January and February are counted as months 13 and 14 ; of the previous year" is a little tricky. In effect, the previous year must be used when ; these months arise. This can be handled by over-riding year using a 'let'. ; Note that 'quotient is the integer division function, and 'modulo is remainder. ; Note: This is an exercise in using 'let, so use use it. (define (zeller year month day) 0) ;; Replace with the correct definition ; Unit tests for zeller (check-expect (zeller 1975 7 20) 1) (check-expect (zeller 1991 5 1) 4) (check-expect (zeller 2000 1 11) 3) ; Problem 3: [10 points] ; ; Use the builtin function 'assoc to define a function ; 'month-number that returns the number of a symbolic month, given the ; Racket symbol for the month. The month symbols are to be 3-letter symbols, ; 'jan, 'feb, ... ; and the numbers run from 1 to 12. ; Note: This is an exercise in assoc. If you don't use it, you lose points. (define (month-number month-name) 12) ;; Replace with the correct definition ; Unit tests for month-number (check-expect (month-number 'sep) 9) (check-expect (month-number 'jul) 7) (check-expect (month-number 'jan) 1) ; Problem 4: [10 points] ; ; Define a function 'day-name' that returns a 3-letter day symbol, given the number to ; which the day would correspond as the output of 'zeller'. ; Note: You might think we want to use assoc here. No. Try using list-ref instead. (define (day-name day-number) 'fri) ;; Replace with the correct definition ; Unit tests for day-name (check-expect (day-name 3) 'tue) (check-expect (day-name 0) 'sat) (check-expect (day-name 1) 'sun) ; Problem 5: [10 points] ; ; Compose the functions in your previous definitions to give a more user-friendly ; version of 'zeller', which we call 'day-of-week'. This takes a year, ; a month symbol, and a day of the month and returns a day-of-the-week symbol. ; Maybe test it on your own birthday. (define (day-of-week year month-name day) 'fri) ;; Replace with the correct definition ; Unit tests for day-of-week (check-expect (day-of-week 1975 'jul 20) 'sun) (check-expect (day-of-week 1979 'dec 2) 'sun) (check-expect (day-of-week 2000 'jan 11) 'tue) (check-expect (day-of-week 1944 'jun 12) 'mon) ; Problem 6: [5 points] ; ; Given below is an association list that gives a Scrabble letter score for ; each of the 26 letters of the alphabet. Use this association list to create a ; function 'score-letter' that will return the score of its argument letter. ; Have your function return 0 if the argument is not a letter. (define scrabble-letter-scores '((#\a 1) (#\b 3) (#\c 3) (#\d 2) (#\e 1) (#\f 4) (#\g 2) (#\h 4) (#\i 1) (#\j 8) (#\k 5) (#\l 1) (#\m 3) (#\n 1) (#\o 1) (#\p 3) (#\q 10)(#\r 1) (#\s 1) (#\t 1) (#\u 1) (#\v 4) (#\w 4) (#\x 8) (#\y 4) (#\z 10) )) (define (score-letter letter) -1) ;; Replace with the correct definition ; Unit tests for score-letter (check-expect (score-letter '#\w) 4) (check-expect (score-letter '#\z) 10) (check-expect (score-letter '_) 0) ; Problem 7: [10 points] ; ; Construct a function score-word that scores an entire word represented as a symbol. ; Use higher-order functions such as foldr and map to do any necessary iteration implicitly. ; Note that symbols are not the same as strings. However, the built-in function ; symbol->string will convert a symbol into a string of characters, and the built-in ; function string->list will convert a string into a list of its characters. ; Consider creating symbol->list which is the composition of those two functions. ; It might be handy. (define (score-word word) 0) ;; Replace with the correct definition ; Unit tests for score-word (check-expect (score-word 'foo) 6) (check-expect (score-word 'aeiou) 5) (check-expect (score-word 'abcdefghijklmnopqrstuvwxyz) 87) (check-expect (score-word 'bcdfghjklmnpqrstvwxyz) 82) ; Problem 8: [25 points] ; ; Construct a function that finds the highest-scoring word in a list of symbols, ; returning both the word and the score as a list of two elements. This may require ; the invention of some helper functions. For the case that the list of symbols is empty, ; return the following dummy value: '(_ 0) (define (highest-word-score list-of-words) '(foo 0)) ;; Replace with the correct definition ; Unit tests for highest-word-score (check-expect (highest-word-score '(two words)) '(words 9)) (check-expect (highest-word-score '(one_word)) '(one_word 11)) (check-expect (highest-word-score '(the quick brown fox just plays with my very lazy dog)) '(quick 20)) (check-expect (highest-word-score '(now is the time for each good person to come to the aid of his or her party)) '(party 10)) (check-expect (highest-word-score '()) '(_ 0)) ; Extra Credit Problem 9: [25 points extra] ; ; Construct a function best-word that returns the highest Scrabble-scoring symbol ; among the symbols in the second argument that can be created by using each letter ; in the first argument at most once. ; If there is a tie, an arbitrary one of the symbols in the list with maximal ; score can be returned. (In grading your problems, we will make sure that the chosen word ; in each test case is unique.) Examples of successful unit tests are given after the stub ; definition. ; Notice that in the second example, two p's of apple were used to form 'pape, while in the ; third example, 'pape could not be made because of too few p's in 'pale. Try to give ; some attention to efficiency in your solution. For example, enumerating all permutations ; of the letters in the first argument would not be a good idea, because perhaps relatively ; few of those permutations occur in the second argument list. ; ; Hint: You might make use of a recursively-defined helper function for this one. (define (best-word symbol list-of-words) '()) ; Uncomment these unit tests if you do the exta credit problem: ; ;(check-expect (best-word 'academy '(ace ade cad cay day)) '(cay 8)) ; ;(check-expect (best-word 'apple '(peal peel ape pape)) '(pape 8)) ; ;(check-expect (best-word 'pale '(peal peel ape pape)) '(peal 6)) ; ; The following will give the overall number of tests correct and incorrect: (generate-report)