CMSC 15100: Lab 1Tuesday 10/1, Wednesday 10/2
CS151 Coursework | CS151 HomeLab 1 is a self-guided set of exercises intended to increase yourfamiliarity with the command line, subversion, and DrRacket. Eventhough you will commit a file to your subversion repository as part ofthis work, there is no official submission associated with lab 1 and youwill not be evaluated on it. (You will be evaluated on all subsequentlab exercises.)Follow the steps below and ask questions as needed as you go along.
1. Change to the root directory by typing cd /.Type pwd and ls and have a look around.Type cd with no arguments. Type pwd to see where you are.Try cd .. and pwd.Try cd - and pwd.
2. Type cd with no arguments.Type ls to see what's there.Type ls -1 (that's the numeral 1) to display the contents of the workingdirectory, one per line.Notice the difference between the output of ls and the output of ls -F.You can combine the effects of the options 1 and F in several ways: try ls-1 -F, ls -F -1, ls -1F and ls -F1.Try ls -lFG.There are many options to the ls command. Type man ls and read aboutsome of them. Press q to exit man.
3. Change to your home directory.Create a batch of empty files by typing touch file1.empty file2.emptyfile3.empty file4.empty file5.empty.Type ls *.empty.
1 / 66
Type ls file*.Type ls -lFG file*.Type ls -hla file*.Type rm file*.empty.Type echo *.Type echo *.*.Type echo ~.
4. Change to your home directory.Create a batch of empty files by typing (note the capitals)touch FILE1.empty file2.empty FILE3.empty file4.empty FILE5.empty.Type ls *.empty.Type ls F*.empty.Type ls f*.empty.Type ls [Ff]*.empty.Type ls [Ff].empty.Type rm [Ff]*.empty.Type ls *.empty.
5. Change to your desktop.Type for I in {1..500} ; do touch FILE$I.empty; done.Type ls FILE*.empty.Type rm FILE*.empty.
6. Type echo "a".Type echo "b".Type echo "c".Type echo "a" > file1.file.Type ls.Type cat file1.file.Type echo "b" >> file1.file.Type ls.Type cat file1.file.
2 / 66
Type echo "c" >> file1.file.Type cat file1.file.Type wc file1.file.Type wc -l file1.file (that's a lowercase l as in, well, lowercase).Type man wc and read a bit. Press q to exit man.Type echo "d" > file1.file.Type wc -l file1.file.What happened?Type cat file1.file.Type rm file1.file.
7. Type date.Type NOW=`date` (those are backquotes).Type echo NOW.Type echo $NOW.Type pwd.Type CURRDIR=`pwd`.Type echo CURRDIR.Type echo $CURRDIR.Type mkdir -p "$CURRDIR/banana".Type B="$CURRDIR/banana".Type echo $B.Type cd $B.Type cd ~.Type pwd.Type rmdir $B.
8. Change to your desktop.Check out a local copy of your repository with
svn checkouthttps://phoenixforge.cs.uchicago.edu/svn/CNET-cs151-aut-13
but, when you do so, use your own actual CNet ID, not CNET.At this point, if you don't have a subversion repository for some reason,
3 / 66
please let the TA know, and continue with the exercises as best you can.You can circle back and do the subversion part of Lab 1 once yourrepository exists.Type ls to make sure the local copy did indeed arrive.Change into the local copy of your repository.Type echo "This is a test." > test.file.Type svn add test.file.Type svn commit test.file -m "Adding a test file.".Type svn mkdir lab1. This will create a directory lab1 inside yourrepository where you can store your lab 1 work.
9. Start DrRacket.DrRacket may at some point ask you to choose a "language level." Forthis week, select the "Beginning Student" level.In order to make use of DrRacket's functional graphics system, you needto "require" an additional graphics library. This requirement is the firstline of the code sample below.Type the following code into DrRacket's definitions window:
(require 2htdp/image)
(square 50 "solid" "blue")
(circle 10 "solid" "purple")
(beside (square 50 "solid" "blue") (circle 10 "solid" "purple"))
(above (square 50 "solid" "blue") (circle 10 "solid" "purple"))
Click the "Run" button at the top of the DrRacket window, and make sureyou understand what you see.Add the following expression to the definitions window:
(beside/align "bottom" (square 50 "solid" "blue") (circle 10 "solid" "purple"))
Run the code again and observe the results.Now, try substituting different numbers in place of 50 and 10, anddifferent colors in place of blue and purple. Try some expressions thatuse "top" in place of "bottom" in beside/align, and try above/align with"left" and "right".Search DrRacket's help system for 2htdp/image for a full catalog of
4 / 66
image operations.
10. You will now use Racket to render a simple illustration of a landmark ofthe Chicago skyline, the Willis Tower (formerly the Sears Tower).You will begin with the following crude approximation of the Willistower. Start a fresh Racket file, and type the following code into thedefinitions window:
(require 2htdp/image)
(define tower (above (rectangle 2 8 "solid" "black") (rectangle 20 100 "solid" "black")))
Save this file under the name lab1.rkt into the lab1 directory youcreated in the local copy of your repository.Consult images of the Willis tower online, and improve your ownrendering of the tower accordingly.
11. To push your lab1.rkt file into your subversion repository, you need toadd it first, then commit it. Note that once you've added a file, you do notneed to add it again, although you will (usually) commit it again manytimes.To do this, change into your repository at the command line. Then typethese instructions:
$ svn add lab1/lab1.rkt $ svn commit lab1 -m "committing lab1"
5 / 66
CMSC 15100: Lab 2Wed 10/9, Thurs 10/10
CS151 Coursework | CS151 HomeLab 2 will be collected from your subversion repository on Thursday,October 10, at 11:59pm.
Language Level: Beginning Student;; no libraries to require
As per the box above, set your language level to Beginning Student inDrRacket. You may not require any libraries for these exercises.Please create a lab 2 directory in your subversion repository with
$ svn mkdir lab2
Work in the file lab2/lab2.rkt. It is important that this file has exactlythis name and location; we will be looking for your work under thisname at collection time.This week, you will practice working with data structures and programdesign by implementing some common useful operations on calendardates.We present a formula for computing the day of the week (below). Theformula only works for the 20th and 21st centuries, so your dates will berestricted to that range.
First write a function leap? to compute whether or not a year is a leapyear. Leap years are not simply every fourth year. The precise rule is asfollows:
A year is a leap year if it is divisible by 4 and not divisible by100, or if it is divisible by 400.
Here is a data definition for dates:;; a date is a;; (make-date m d y) where;; - m is a number in [1, 12],;; - d is a number in [1, 31], and;; - y is a number in [1900, 2099](define-struct date (month day year))
6 / 66
Defining the date structure creates the constructor make-date, which istoo permissive: it allows dates like September 31st, or, for that matter,September 32nd. Write the following smart constructor to check thevalidity of a date before constructing the value.
;; checked-make-date : num num num -> date
In the case of a valid date specification, checked-make-date shouldreturn a date. Otherwise, it should raise an error by evaluating thefollowing expression:
(error 'checked-make-date "invalid date")
You can check error cases with check-error (see the documentation).
Now write two comparison functions, one to test whether two dates areexactly the same, and one to see if, among two dates, the first occursbefore the other. These functions should have the following names andtypes:
date=? : date date -> boolean
date
where floor(y/4) is the integer quotient of y divided by 4. (For example,floor(401/4) is 100). Let w be the remainder of n divided by 7. Then if w= 0, the day is Sunday; if w = 1, the day is Monday; ...; if w = 6, the day isSaturday.Write
;; day-of-week : date -> string
which returns a string ("Sunday", "Monday", etc.)TIP: Explore the terminal command cal. When you construct tests forthis function, you can use cal to check your answers easily.
Finally, write a function to generate a convenient string representationof a date.
date->string : date -> string
The date string should have the following form: the day of the week, aspace, the date, a space, a three-letter abbreviation of the month, aspace, and the year. Some examples follow:
> (date->string (make-date 1 1 2000))"Saturday 1 Jan 2000"> (date->string (make-date 7 8 1980))"Tuesday 8 Jul 1980"> (date->string (make-date 10 9 2013))"Wednesday 9 Oct 2013"
To implement date->string, you will need to use the built-in operationsstring-append and number->string. Note that string-append, like +,overlay and many other Racket operations, is of variable arity: itconsumes 0 or more arguments. All of the arguments to string-appendmust be strings.
Every function must be preceded by a contract and a purpose and befollowed by check tests. On this point, we do not differentiate between"helper functions" and "main functions" toss that distinction away:functions are just functions.With respect to subversion: don't forget to commit your work; adding isnot enough! When you add a file, you announce to the system yourintention to upload that file into the central repository, but only whenyou commit does that upload actually occur. Remember: add once,commit many times. And commit early and often.
8 / 66
CMSC 15100: Lab 3Tues 10/15, Wed 10/16
CS151 Coursework | CS151 HomeLab 3 will be collected from your subversion repository on Thursday,October 17, at 11:59pm.
Language Level: Intermediate Student;; no libraries to require
Please create a lab 3 directory in your subversion repository with$ svn mkdir lab3
Work in the file lab3/lab3.rkt. It is important that this file has exactlythis name and location; we will be looking for your work under thisname at collection time.This week, you will practice list programming while implementing alinear regression calculator for data sets. The problem is well-suited tobeing decomposed into a set of related functions. The lab exercisedescription does not specify too closely which individual functions youshould write; this is to give you practice with program design.
Modeling DatasetsYou will need two data definitions in order to do this exercise: datasetand lineq (for "linear equation"). A posn (which is a built-in struct)consists simply of an x and a y. A dataset is a list of posns. A lineq is aslope and a y-intercept (m and b from the linear equation formy = mx + b). Write a full data definition, including define-struct, forlineq structures.A linear regression analysis is applied to a set of data; its result is theline that best fits the data (provably so) as it would appear on a two-dimensional plot. Your goal today is to write a function linreg whosecontract is
;; linreg: dataset -> lineq
Linear RegressionIn the following discussion, assume that n is the number of datums in
9 / 66
the given dataset.The best-fit slope for the linear model of a dataset is given by
The y-intercept for the linear model of a dataset is given by
The two formulas above can be expressed as functions, with thefollowing contracts:
;; slope : dataset -> num
;; intercept : dataset -> num
Your design will inevitably involve helper functions. The helperfunctions you will need to write in order to get linreg to work willmostly be structurally recursive functions that follow the How to DesignPrograms template closely.When you have finished linreg, you have finished the lab. Commit asusual.
NotesLinear regression analysis is not meaningful on any data setcontaining fewer than two points. In such cases, you should raisean error.Define a few simple test datasets for your tests. They'll savespace and increase clarity.Use a spreadsheet's SLOPE and INTERCEPT functions to check yourtest results. Excel, OpenOffice and Google Docs are all suitablechoices.You might want to write sum : (listof num) -> num.The mathematical notation in this lab is terse. If you find thenotation confusing or unclear, ask TAs and fellow students (it'swell within academic honesty boundaries to ask fellow studentsfor help with notation) for explanation.
AcknowledgementsThis programming exercise is based on similar exercises developed incollaboration with faculty (of whom I (ams) was one) at the Dwight-
10 / 66
Englewood School in Englewood, NJ.
11 / 66
CMSC 15100: Lab 4Tues 10/22, Wed 10/23
CS151 Coursework | CS151 HomeLab 4 will be collected from your subversion repository on Thursday,October 24, at 11:59pm.
Language Level: Intermediate Student(require 2htdp/image)(require 2htdp/batch-io)
Please create a lab 4 directory in your subversion repository with$ svn mkdir lab4
Work in the file lab4/lab4.rkt. It is important that this file has exactlythis name and location; we will be looking for your work under thisname at collection time.Today you will build a useful piece of software out of various relatedcomponents. By combining your linear regression code from last week'sexercise, and some new graphics routines you will write today, you willbuild a tool for consuming a dataset from a text file and producing avisualization of linear regression analysis on that dataset.
PreliminariesProcure your linear regression code, including the computation of r2from the last homework, and copy it into a file lab4.rkt.Use the following data file to test your work: discus.csv. The datagives the gold metal distance for discus throws in the Olympic Gamesfrom 1900 to 1992. The data is strongly linear. The x values are yearssince 1900 and the y values are distances in meters. The data wasobtained from http://exploringdata.cqu.edu.au/oly_gold.htm (nowdefunct!).We also encourage you to create your own csv test files and use thosein your development as well.
Part 1: GraphicsThe first component is a visual tool for linear regression. You will write
12 / 66
a function;; linreg-image: (listof posn) -> image
that, given a dataset, will produce a plot of the data overlaid with thebest-fit line as determined by the analysis, as well as the text of thelinear equation. To simplify the assignment, we assume the givendatasets all lie entirely in the first quadrant, and in each figureproduced, the origin is situated exactly at the lower left corner.Your visual representation of linear regression analysis must include, ata minimum,
axes,datapoints,a sketch of the best-fit line found by your analysis, andthe equation of the best-fit line computed by your analysis, and r .
You may break this problem into smaller pieces as you see fit. Here aresome of the functions in my own implementation:
axes: num num -> image that returns an image of the positive partsof the x- and y-axes up to the given limit, with the origin at thelower left corner. In my draft implementation, 1 pixel correspondsto one unit on the graph. This results in small images. You mayuse a different scale as you see fit; just be sure the scale isconsistent among all functions.plot-point: posn image -> image where the second input to thefunction is the plot onto which to draw a given point. You mayassume that the lower left corner of the given plot image is theorigin. The function overlay/xy is helpful, but note itsinterpretation of the y coordinate differs from the usual plottinginterpretation.plot-dataset: (listof posn) image -> image which plots adataset onto the background specified in the function's secondinput (this can be cleanly implemented with foldr).
For drawing the best fit line on the plot, the 2htdp/image function add-line is helpful, but, once again, be mindful of the interpretation of the ycoordinate.
Part 2: File InputWrite a function
;; dataset-from-file: string -> (listof posn)
to produce a dataset from a csv file. Use the function read-csv-filefrom the batch-io library (see the corresponding require at the top of
2
13 / 66
this page) in combination with string->number.
Part 3: Putting it TogetherFinally, you will put the pieces together into a function
;; main: string string -> bool
which will consume the names of an input data file and an output datafile, respectively, read the data in from the former and save an imageto the latter. Use the 2htdp/image library function
;; save-image : image string -> boolean
(whose string argument is a file name) to save the image.
SamplesAs stated above, your image must include axes, datapoints, the best-fitline, and the text of the linear equation and r2, as follows:
An image like this is sufficient for the purposes of this exercise.If you are feeling more ambitious, you can enrich the appearance ofyour image with various features, as in the following illustration:
14 / 66
CommentsPlease note that we may test your code on a different data set than this.If so, all the data will lie in the first quadrant, as here.Don't worry about intelligent placement of the text of the analysis; if itcovers part of the data or the trendline, so be it.
15 / 66
CMSC 15100: Lab 5Tues 11/5, Wed 11/6
CS151 Coursework | CS151 HomeLab 5 will be collected from your subversion repository on Thursday,November 7, at 11:59pm.
Language Level: Intermediate Studentwith lambda(require 2htdp/image)(require racket/match)
Please create a lab 5 directory in your subversion repository with$ svn mkdir lab5
Work in the file lab5/lab5.rkt. It is important that this file has exactlythis name and location; we will be looking for your work under thisname at collection time.Today you will implement a address book data structure as a binarysearch tree of "vcard" structures (loosely related to the actual vCardfile format); furthermore you will write function to build images ofthose trees to be able to visualize them clearly.
Binary Search Tree BasicsCopy the following data definitions into your lab5.rkt.
;; a vcard is a (make-vcard lname fname email tel);; where lname, fname, email and tel are strings(define-struct vcard (lname fname email tel))
;; a vtree is either;; - empty, or;; - (make-vtree c lsub rsub) where c is a vcard, lsub and rsub are vtrees(define-struct vtree (c lsub rsub))
Implement the following comparison functions, which must consideronly last name and first name in their comparisons.
;; vcard
functions given above. Vcards that are less than (per the comparisonfunction above) the vcard at the root belong in the left subtree; vcardsgreater than the root go into the right subtree. The policy on vcards thatare equal to another vcard in the tree (per last name and first name) isas follows: if a vcard is inserted into a vtree where a vcard with thesame name is already present in the tree, the new vcard (the one beinginserted) should replace the existing one.
;; insert : vcard vtree -> vtree;; note: when the name on the given vcard is already present in the vtree,;; the new vcard displaces the old one
Write a function, given a last name and a first name (in that order) and avtree, return either the vcard in the tree with those names, or false ifthere is no such vcard present. Note the return type in the contract of thisfunction: the + notation means the function returns either a vcard or thevalue false.
;; find : string string vtree -> (+ vcard false);; note: *do not* search both trees recursively, which defeats the purpose;; of having constructed a search tree in the first place.
The following functions will visualize the vcard, providing an easy wayto observe the structure of the object. Read the comments carefully,which specify how you will go about it.
;; vcard-img : num vcard -> image;; Draw a rectangular image of the vcard. ;; The given number is the minimum width of the image.;; Ensure the rectangle is at least that wide.;; Include all four elements on the image of the card: the first;; and last names, the email address, and the phone number.;; Within these constraints, you have freedom to design how a vcard ;; is visualized; you need not ask us lots of questions about how ;; precisely they should look.
;; vtree-img : vtree -> image;; - The image of the empty tree must not be the empty image -- it;; must be something visible (we don't care exactly what). In my ;; (Adam's) draft implementation, I use ;; (rectangle 40 10 "solid" "maroon");; - Follow this algorithm to draw the tree: recursively draw both;; subtrees; put them beside one another, aligned at the top; draw ;; the root vcard above that, where with min width of the root vcard ;;; is the total width of the images of the two subtrees.
CommentsYou may find pattern matching especially convenient whenprogramming with trees.
17 / 66
CMSC 15100: Lab 6Tues 11/12, Wed 11/13
CS151 Coursework | CS151 HomeLab 6 will be collected from your subversion repository on Thursday,November 14, at 11:59pm.
Language Level: Intermediate Studentwith lambda(require 2htdp/image)(require racket/match)(require 2htdp/universe)
Please create a lab 6 directory in your subversion repository with$ svn mkdir lab6
Work in the file lab6/lab6.rkt. It is important that this file has exactlythis name and location; we will be looking for your work under thisname at collection time.Today you will implement an interactive click-and-tally counter tocount objects in an image. With simple modifications, you will be ableto use this tool for any type of object in any image. However, today, fora bit of local color, you will use the tool to count geese in nearbyWashington Park.
18 / 66
Universe BasicsToday we will use DrRacket's "universe" library to build interactivesoftware. Universe is a capacious library with many interestingfeatures; we will zero in on a few fundamental ones in today's exercise.The first thing one needs to do to create a universe project is to decideon a model of the state of the world. It can be any data -- a number, aBoolean constant, a list -- or a special data structure containing amixture of relevant items. We will take the latter approach and define aworld as follows.;; a world is a (make-world i cs r m show? done?) where ;; - i is an image, ;; - cs (the clicks) is a (listof posn),;; - r is a num, ;; - m is a string, ;; - show? is a bool, and ;; - done? is a bool(define-struct world (i cs r m show? done?))
(Actually naming this struct a world -- or defining a struct at all -- is notrequired, as long as your code is internally consistent.) Copy this datadefinition into your source file. Some comments:
i is the image being clicked upon.cs is the current list of clicks, initially empty.r is the radius of each click circle.m is the current message. It can be whatever you want it to be(within the bounds of taste and decency, please). We suggest youuse it to give feedback to the user on their most recent action.
19 / 66
show? indicates the current state of "show mode" (initially true)(more on this below).done? indicates doneness (initially false).
Once you have decided on what a world is, you can create a "newuniverse," as it were, with the function big-bang. big-bang takes theinitial state of the world as its argument, and it is then followed by anumber of clauses, in any order, defining how the universe behaves.What happens in a universe is essentially this: the world begins in itsinitial state, and as the user takes actions such as clicking the mouse ortyping on the keyboard, a new world, in a (possibly) different state, isconstructed as the result of the action. Furthermore, the current world isredrawn in its window when it differs from its world predecessor.Here is a sketch of a call to big-bang, with types, displayed inside anglebrackets, in place of actual values. Look at the types carefully -- in eachcase the type tells you a great deal about the value that goes there.(big-bang [to-draw image>] [on-key world>] [on-mouse world>] [stop-when bool>])
Comments on the key and mouse-event types: both key values andmouse-event values are strings, so string comparison and stringmatching work on them as such. For simple alphabetic and symbolickeys, a key is simply a string containing the corresponding character:"q", "n", "+" and so on. You can use string=? or key=? to inspect a key(both operators do the same thing), or pattern match against stringconstants, as you prefer. A mouse-event is one of the following strings:"button-down", "button-up", "drag", "move", "enter", or "leave". Youcan also use string=? or pattern matching on mouse-event values (thefunction mouse-event=? seems not to exist). The only mouse-event thatwill change the world in the current exercise is "button-up".
The Appearance of the WorldVisually, the world should appear as the image, whose upper-leftcorner should be at the upper-left corner of its window, and directlybelow it, various textual presentations as follows. Underneath theimage, it must display the number of clicks in the current click list, andit must display the current message (of the world). Underneath thoseelements, you may, if you wish, display instructions on how to use thesoftware. Friends: we don't care exactly how you arrange the elementsor what precisely they look like, so please don't shower us withquestions along those lines. Just use common sense and your ownjudgment. In other words: make it look nice.If show mode is true, any clicks in the current click list should be
20 / 66
displayed at their locations by circles with the given current click radius(and in any color you like). If show mode is false, no clicks should bedisplayed. When coloring the circles, you might like to use the alphachannel for some transparency (it's a pleasing effect).
Event HandlingWrite a click handler to behave as follows:On "button-up", if the world is in show mode and the click is within thebounds of the image, then the current click should be added to list ofclicks.
Write a key handler that responds to keys in the following ways:z (related to the common key for Undo) should erase the most recentclick from the list. You should be able to type z repeatedly and erasemore and more clicks as you go. Striking z when there are no clicksshould have no effect; specifically, it must not crash the program.c should clear all clicks from the current click list.t should toggle the "show mode." When show mode is on, all clicksshould be displayed and any new clicks should be added to the list.When show mode is off, no clicks should be displayed and new clicksshould be ignored.+ should increment the radius of the click circles by 1. There is nomaximum click circle radius (yay!).- should decrement the radius of the click circles by 1, but the clickcircle radius must never go lower than 1.q should quit.
To run the program , include a call to big-bang at the bottom of thesource code. When DrRacket gets there, it will evaluate the expressionand start the universe running in its own window.
Sample ImagesYou can import either or both of these images into your code usingDrRacket's "Insert | Image..." menu item. Then you will be free toinclude either one in your initial world.Newbies might prefer to count geese in this photo:
21 / 66
For extreme, unapologetic, your-friends-pretend-not-to-care-but-actually-wish-they-were-you goose clicking, try this:
(All photos taken Tues Nov 12 2013 around 9am in Washington Park byAdam Shaw.)
22 / 66
CMSC 15100: Lab 7Tues 11/19, Wed 11/20
CS151 Coursework | CS151 HomeLab 7 will be collected from your subversion repository on Thursday,November 21, at 11:59pm.This is your last lab exercise of the quarter. Say thanks to your lab TAon the way out! Erik, Nedelina, Nick and Charisee each work hard onyour behalf.
Language Level: Intermediate Studentwith lambda(require 2htdp/image)(require racket/match)
Please create a lab 7 directory in your subversion repository with$ svn mkdir lab7
Work in the file lab7/lab7.rkt. It is important that this file has exactlythis name and location; we will be looking for your work under thisname at collection time.
Gobblers SymmetriesGobblet Gobblers is full of symmetries. For example, consider thesetwo boards B1 and B2:
B1 B2
Assuming the squares on the board have indices 0, 1, 2, ..., 8 (as in ourproject code) these boards are represented differently, so, in as sense,they are different. However, from the point of view of game strategy,they are identical; one is simply a clockwise rotation of the other by 90degrees. Each board can be rotated in this way three times beforecoming back around to its original position.
23 / 66
Each board can not only be rotated without changing its strategicmeaning; it can also be flipped (or mirrored) as follows. Here is B1 fromabove, and its "vertical flip" or "vertical mirroring," labeled B3.
B1 B3
In total, each board can by rotated and flipped into as many as eightdistinct positions, like so:
This set of boards represents an equivalence class with respect to strategy;that is, any strategy that applies to any one of these boards appliesequally well to any other. The reason each such set contains as many aseight rather than eight positions is that some boards are identical underrotating and flipping; consider any board with pieces only in the centersquare, for example.There is still more symmetry to exploit. If the colors on a board areinverted, the resulting board is exactly the same as the original board,expect for the fact that the interests of blue and orange are swapped.That is to say, that the equivalence class below, the inversion of theequivalence class above, is identical to its inversion except for the factthat the players' interests are exactly exchanged.
24 / 66
The strategy logic you will write for project 3 will exploit thesesymmetries and inversions in order to do more computation in a shortertime and, ultimately, choose better Gobblers moves.
ExerciseIn addition to the data definitions provided (since project 1) for piece andboard, you must write a board-set data definition, and implement thefollowing operations:
;; board-set-insert : board board-set -> board-set
;; board-set-member? : board board-set -> bool
For your set implementation, simply use a list of boards. Faster setimplementations exist, of course, but for such small sets as these, whereso few operations* are needed, and in the interest of expedience, listswill do. Please note that it is not necessary to define a struct to defineboard-set. The important feature of the set is that it must never containduplicate values. *A proper set implementation would be crafted to supportefficient common set operations like union, intersection, and set difference.Write the function board-invert to switch all the colors of all pieces onthe board.
;; board-invert : board -> board
Write the function board-equiv-class to build the equivalence class forthe given board. Every board is in its own equivalence class. A givenboard's equivalence class contains all clockwise rotations* of theoriginal board, and all rotations of the vertical flip of the original board.
;; board-equiv-class : board -> board-set
*A clockwise rotation is as illustrated above in the table showing B1 and B2.Write board-equiv?. Two boards are equivalent if they inhabit the sameequivalence class.
;; board-equiv? : board board -> bool
25 / 66
RemarksVisualization, though very helpful, is not part of this exercise. You mayinclude visualization code if you like, including code pasted in from theproject 2 seed code, but it will not be graded.These problems all have terse solutions. If you find yourself writinghundreds upon hundreds of lines of code, reconsider your approach.Look for commonalities, and use and/or write higher-order functionswhere possible. As a rule of thumb, 200 lines or so should suffice for theentire exercise (not counting any visualization code).You might wish to include the following definitions in your code forconvenience:
(define o1 (make-piece 1 'orange))(define o2 (make-piece 2 'orange))(define o3 (make-piece 3 'orange))(define b1 (make-piece 1 'blue))(define b2 (make-piece 2 'blue))(define b3 (make-piece 3 'blue))
Enjoy!
26 / 66
CMSC 15100: Introduction toComputer Science IUniversity of Chicago, Autumn 2012
CS151 Coursework | CS151 Home
Homework 1Homework 1 is due Monday, October 7, 2013 at 11:59pm.
Beginning Student w/ List Abbrev.(require 2htdp/image)
These exercises will help you develop the ability to write simplefunctions in Racket, become familiar with the DrRacket programmingenvironment, and practice the particular discipline of program designtaught by and advocated for by the textbook.You will submit your work with filename hw1.rkt in a directory calledhw1. The following commands, when run from within a copy of yourrepository, will get you started. Note the third instruction, touchhw1.rkt, will create a (blank) file of that name. Also, the commandcd .. goes "up" one directory from the current working directory.$ svn mkdir hw1$ cd hw1$ touch hw1.rkt$ svn add hw1.rkt$ cd ..$ svn commit hw1 -m "getting ready for homework1"
After having done this, work in the file hw1/hw1.rktAt the moment this assignment is published, we have not yet taught youall you need to know to complete this work. Friday's lecture, incombination with the text, will provide you everything you need toknow.For the present, do not worry about functions being passed bogusinputs, e.g., a sphere with a negative radius. We will deal witherroneous arguments to functions later in the quarter.
27 / 66
Homework ProblemsFor every function you write, you must write a contract, a purpose, andtests with check-* utilities. Do write helper functions where it seems likea good idea to do so. All functions need contracts, purposes and tests,*even if they are "only" helper functions.*Note that writing check-expect tests for the flag-drawing functions is not reallypossible. In cases such as the flag functions, namely, functions that producecomplex images, "eyeball tests" (which we will discuss in class) are sufficient.
Problem 1Write the following conversion functions:
lb->kg and kg->lb to convert between pounds and kilograms,mi->km and km->mi to convert between miles and kilometers, andf->c and c->f to convert between degrees Fahrenheit and degreesCelsius.
Problem 2Three numbers a, b and c are a Pythagorean triple when a2 + b2 = c2. Forexample, (3, 4, 5) is a Pythagorean triple, as is (4, 3, 5), but (3, 4, 6) is not.Write the function pythagorean? to consume three numbers and returntrue if they are a Pythagorean triple. You may assume that the numbersentered by the user are all positive integers. Furthermore, assume thatthe third argument to the function is the largest; that is, it is the would-behypotenuse of the group.
Problem 3Assume a forty-hour work week. A worker with hourly wage w (dollarsper hour) makes w dollars for each hour up to an including the fortieth,and one and a half times w for all hours over forty. This arrangement issometimes known as "time-and-a-half overtime."Write the function weekly-pay. It must consume exactly two arguments,both numbers: a worker's wage in dollars per hour, and a number ofhours. It must compute the total amount, in dollars, the worker earnedthat week, assuming a time-and-a-half overtime compensationagreement.
Problem 4Assume the local convention for tipping cab drivers is to add a 15% tipto the fare, and then round up to the nearest dollar. By this scheme, for acab fare of $8, the fare plus tip is $10, and for a cab fare of $16, the fare
28 / 66
plus tip is $19.Write the function cab-fare-with-tip. It should consume one number, acab fare in dollars.
Problem 5Let d(n) be the number of digits (base 10) in nn. Its input must be apositive integer. Write the function d with type num -> num.In the implementation of d, you may at no point convert a number to astring. In other words, you must solve this problem using numericaloperations exclusively.
Problem 6A spherical shell is the volume enclosed between two concentricspheres. In other words, it is the 3-dimensional generalization of theannulus. Real-world volumes that are similar to spherical shells includetennis balls and coconuts.Let a hemishell be the volume obtained by cutting a spherical shellexactly in half. The following is an illustration of a hemishell.
Write two functions to compute with hemishells: hemishell-volume andhemishell-surface-area. Each function must consume two numbers,the radius of the outer sphere and the thickness of the hemishell wall, inthat order. The functions may assume the numbers are sensible: that is,that the radius and thickness are both positive numbers, and that thethickness does not exceed the radius. In your computations, use built inpi for the value of .Two hints: 1) write helper functions, and 2) subtract. Furthermore, makesure that you've considered the whole surface in computing the surfacearea.
Problem 7Write functions to draw the flags of Norway and Iceland, given thewidth in pixels of the desired image. Assume the ratios in the two flagsare the same, that is, that they have exactly the same pattern in different
29 / 66
are the same, that is, that they have exactly the same pattern in differentcolors (in truth the ratios in the two flags differ very slightly). Hint: useoverlay/align.
Flags of Norway (left) and Iceland.
Problem 8Write the function wider? to consume a pair of images and produce truewhen the first image is wider than the second. Similarly, write thefunction narrower?. These have concise implementations. You may callone from the other, but be careful.
Submit Your WorkSubmit your work by committing hw1/hw1.rkt to your CS151 subversionrepository by Monday, October 7 at 11:59pm. All your work must becontained in that one file.You should commit your work early and often. Intermediate commits that is, commits made along the way to the final commit arestrongly encouraged; only your last commit before the deadline will beevaluated by your graders.
30 / 66
CMSC 15100: Introduction toComputer Science IUniversity of Chicago, Autumn 2012
CS151 Coursework | CS151 Home
Homework 2Homework 2 is due Monday, October 14, 2013 at 11:59pm.
Intermediate Student(require 2htdp/image)
These exercises will give you practice designing compound datastructures and computing with them, and also writing various simplefunctions on different types of lists.Please submit your work with filename hw2.rkt in a directory calledhw2.At the moment this assignment is published, we have not yet taught youall you need to know to complete this work. Friday's lecture, incombination with the text, will provide you everything you need toknow.
Homework ProblemsFor every function you write, you must write a contract, a purpose, andtests with check-* utilities. Do write helper functions where it seems likea good idea to do so. All functions need contracts, purposes and tests,even if they are "only" helper functions.
Problem 1First, write the data definition for a compound data structure torepresent vectors in 3-space. The structure should be called vec3 and itscomponents x, y and z.Once you have defined the vec3 structure, define the followingstandard vector operations on it. We have given the name and a briefdescription of each. Where we have omitted the type of the operation,decide on the correct type and write the precise contract for eachoperation on your own.
vec3-negate negate allcomponents ofthe vector
vec3-add add twovectors,
31 / 66
yielding a newvector
vec3-sub subtract thesecond vectorfrom the first
vec3-scale : num vec3 -> vec3 scale allcomponents ofthe vector bythe givenscalar
vec3-dot compute thedot product oftwo vectors,which is thesum of thecomponentwiseproducts
vec3-mag compute themagnitude(length) of avector
vec3-norm normalize thevector: that is,compute a unitvector pointingin the samedirection
Problem 2The names and types of various list operations are given below. Pleaseimplement them. Use the types given to understand how each isdesigned to behave.
halves : (listof num) -> (listof num) divide all numbers by twomultiply-by : num (listof num) -> (listof num) multiply all numbers by the given scalar;
for example,(multiply-by 7 (list 1 2 3)) mustproduce (list 7 14 21)
negatives? : (listof num) -> (listof num) keep negative numbers, discard others; forexample,(negatives? (list 0 -1 1 -2 3)) mustproduce (list -1 -2)
larger-than : num (listof num) -> (listof num) keep numbers above threshold, discardothers; for example(larger-than 7 (list 6 7 8 9 8 7 6))must produce (list 8 9 8)
taller-than : num (listof image) -> (listof image) keep images taller than given threshold,discard others
32 / 66
list-product : (listof num) -> num compute the product of all numbers in thelist
list-xor : (listof bool) -> bool must return true is exactly one item in thelist is true, false otherwise
tower : (listof image) -> image stack all images on top of one another, withthe first image at the top, the second imageimmediately under it, etc. Note that there isa special built-in value empty-image which issuitable for the base case here.
that-many : (listof num) -> (listof (listof num)) build a list of lists containing "that many" ofeach; for example,(that-many (list 2 1 3)) must produce(list (list 2 2) (list 1) (list 3 3 3)).You may assume every number in theinput list is nonnegative.
Submit Your WorkSubmit your work by committing hw2/hw2.rkt to your CS151 subversionrepository by Monday, October 14 at 11:59pm. All your work must becontained in that one file.A reminder: commit your work early and often. Intermediate commits that is, commits made along the way to the final commit arestrongly encouraged; only your last commit before the deadline will beevaluated by your graders.
33 / 66
CMSC 15100: Introduction toComputer Science IUniversity of Chicago, Autumn 2012
CS151 Coursework | CS151 Home
Homework 3Homework 3 is due Monday, October 21, 2013 at 11:59pm.
Intermediate Student(require 2htdp/image)
Please submit your work with filename hw3.rkt in a directory in yourrepository called hw3.
Homework ProblemsFor every function you write, you must write a contract, a purpose, andtests with check-* utilities, with the usual exception for functions thatproduce complex images, for which "eyeball tests" are appropriate.Write helper functions where they are needed. All functions needcontracts, purposes and tests, even if they are "only" helper functions.
Problem 1Write concat-with : string (listof string) -> string toconcatenate all strings with the given separator. Examples: (concat-with "," (list "Crosby" "Stills" "Nash")) => "Crosby,Stills,Nash"
(concat-with "" (list "Crosby" "Stills" "Nash")) => "CrosbyStillsNash"
(concat-with "" (list "Crosby")) => "Crosby"
Problem 2Write chessboard : num num color color -> image. The functionshould consume the following arguments, in order:
the number of squares in each row/column,the side length of each individual square,
34 / 66
the light square color, andthe dark square color.
A chessboard should be oriented such that the lower right square is lightcolored.
Problem 3Write pascal : num -> (listof (listof num)) to compute the first nrows of Pascal's triangle (for n 0).
Problem 4Linear regression analysis computes a slope and an intercept no matterwhat dataset it's given, even when the data is not really linear at all.(Think of points lying on a parabola, or just randomly scattered about.)A full linear regression analysis includes the computation of a linearcorrelation coefficient that quantifies the strength of the data's linearity.This coefficient is usually referred to as r and is a measure, roughlyspeaking, of "how linear the data is."Typically a linear regression analysis provides the value r , which lieson the interval [0,1]. The closer r is to 1, the stronger the correlationbetween the data and the line modeling the data. An r close to 0 meansthat the analysis has calculated a linear equation that bears nomeaningful relationship to the data at hand.An analysis will be a struct consisting of two parts: a lineq and a num,the latter being the value of r . Write a full linear regression analysiswith the contract
;; full-linreg: dataset -> analysis
Copy your lab 3 code to compute the slope and intercept.The linear correlation coefficient r is given by the following:
An overbar indicates the arithmetic mean of the term underneath. Alowercase sigma () indicates the standard deviation (as defined below)of the subscript term.
The standard deviation is the square root of the variance, wherethe variance of a set of numbers is the is the mean of the squaresminus the square of the mean.
Note: the formula above gives r; the full analysis returns r .
22
2
2
2
35 / 66
You can use the common spreadsheet function RSQ to check yourresults.
Problem 5Here is a function to draw an asymmetric square design. Here is(design 128):
and here is the code.;; design : num -> img;; draw square design, not symmetrical, with given side length(define (design s) (overlay (square s "outline" "maroon") (above (beside (rectangle (/ s 2) 1 "solid" "darkgray") (overlay (circle (/ s 6) "solid" "gray") (circle (/ s 5) "solid" "maroon"))) (rectangle 1 (/ s 2) "solid" "darkgray")) (square s "solid" "darkgray")))
Copy and paste this code into your homework file.Write a function recursive-tiles : num -> img to consume a givenside length and produce the following recursive tiling of the design. Theimage below is the result of calling (recursive-tiles 512).
36 / 66
This is not a fractal (why not?). By inspecting the image carefully, youcan discover everything you need to know about its construction. Youshould write helper functions.Make sure the image you produce is of the right height and width:
> (image-width (recursive-tiles 512))512> (image-height (recursive-tiles 512))512
In your implementation of recursive-tiles (and helpers), never calldesign with an argument less than 2.Note: arguments that are powers of 2 are best for recursive-tiles,because of the repeated halvings of the number. We will not judge yourcode for how it works on numbers not powers of 2.Note: it shouldn't take too long for the system to draw this. On mymachine, which is a 2011 MacBook Pro, I get
> (time (recursive-tiles 512))cpu time: 1141 real time: 1164 gc time: 155
These units are milleseconds, so that's a bit more than 1 second. If yourprogram takes much longer than that, something is probably wrong.You will boost your program's performance by defining an image
37 / 66
locally when you know you need more than one identical copy of it (andthat is the case here in many instances).This exercise was inspired by a section in Abelson and Sussman's Structure andInterpretation of Computer Programs.
38 / 66
CMSC 15100: Introduction toComputer Science IUniversity of Chicago, Autumn 2012
CS151 Coursework | CS151 Home
Homework 4Homework 4 is due Monday, October 28, 2013 at 11:59pm.
Intermediate Student with lambda(require 2htdp/image)(require racket/match)
Please submit your work with filename hw4.rkt in a directory in yourrepository called hw4.
Homework ProblemsFor every function you write, you must write a contract, a purpose, andtests with check-* utilities, with the usual exception for functions thatproduce complex images, for which "eyeball tests" are appropriate.Write helper functions where they are needed. All functions needcontracts, purposes and tests, even if they are "only" helper functions.
Problem 1Implement the following functions as calls to map, filter, foldr or somecombination thereof. Write helper functions when needed. You may uselambda where appropriate. Copy over your vec3 data definition andrelevant operations for use in certain problems below.;; sum-of-squares : (listof num) -> num
add the squares of all numbers in a list;; within : num (listof posn) -> (list of posn)
keep those points whose distance to the origin is strictly less thanthe given threshold, discard the rest
;; vec3-sum : (listof vec3) -> vec3
compute the sum of all given vectors under vector addition39 / 66
;; vec3-total-magnitude : (listof vec3) -> num
compute the total magnitude of all given vectors;; wider-than : num (listof image) -> (listof image)
keep the images wider than the given threshold, discard the rest;; total-area : (listof image) -> num
using the image-width and image-height of each image in the list,compute the total area in pixels of all images in the list
Problem 2Consider the following recursive functions, each of which consumes anatural number.
;; sum-upto : nat -> nat;; compute the sum from 0 to n(define (sum-upto n) (cond [(zero? n) 0] [(positive? n) (+ n (sum-upto (sub1 n)))]))
;; string-upto : nat -> string;; build the string of naturals up to given bound;; ex: (string-upto 3) => "0123"(define (string-upto n) (cond [(zero? n) "0"] [(positive? n) (string-append (string-upto (sub1 n)) (number->string n))]))
;; countdown : nat -> (listof nat);; build the list of naturals from n down to 0(define (countdown n) (cond [(zero? n) (list 0)] [(positive? n) (cons n (countdown (sub1 n)))]))
These functions share a basic structure in common. Just as it is possibleto generalize various common list-consuming functions with foldr, it ispossible to generalize over these natural number functions as well.Write natfold : (nat alpha -> alpha) alpha nat -> alpha togeneralize these functions. Then reimplement sum-upto, string-uptoand countdown, as above, as calls to natfold. Furthermore, implementfact : num -> num (for factorial) as a call to natfold.
Problem 3A numerical integral is computed by fitting rectangles (or trapezoids)under the curve of a function, and computing the total area of thoserectangles. Such integrals are known as Riemann sums.Here is a sketch of a left-rectangle Riemann sum:
40 / 66
Write a function riemann/lr : (num -> num) num num num -> num tocompute the left-rectangle integral of a given function. The fourarguments to riemann/lr must be
a function,the width of each rectangle under the curve,the left endpoint of the integral, andthe right endpoint of the integral.
For the purposes of this problem, the integral from left endpoint a toright endpoint b is 0 where a b. You may use this fact as the terminatingbase case in your recursion. Note that the results are increasinglyaccurate as the width of the rectangles decreases.Here are some examples to check against:
> (riemann/lr identity 0.1 0 10)49.5> (riemann/lr identity 0.01 0 10)49.95> (riemann/lr identity 0.001 0 10)49.995> (riemann/lr cos 0.1 0 (/ pi 2))#i1.0502004622913053> (riemann/lr cos 0.01 0 (/ pi 2))#i1.0049953312208086> (riemann/lr cos 0.001 0 (/ pi 2))#i1.0004999977618816> (riemann/lr sin 0.1 0 pi)#i1.999547959712598> (riemann/lr sin 0.01 0 pi)#i1.9999900283082455> (riemann/lr sin 0.001 0 pi)#i1.9999999540409892
Problem 4Write the function show-pascal : nat color color -> image to renderan image of the first n rows of Pascal's triangle. Each row must displayeach number in order left-to-right, and each row must appear centeredabove the row below it. The color arguments are the colors to use todisplay the odd numbers and the even numbers, respectively.
41 / 66
Comments:The image of 0 rows of Pascal's triangle is the empty image.Use text and number->string to render images of numbers.The functions odd? and even? are built in; feel free to use them.You may use a very small font to render the numbers, so you cansee more of the image at once.
Yes, you may copy your Pascal's triangle code from last week.
Problem 5Write a function cal : num num -> img to consume a month and a yearand produce a calendar image for that month. For the month argument,1 means January, 2 February, and so on until 12 for December. Youneed only deal with the 20th and 21st centuries. You may copy codefrom previous weeks into the current homework as you see fit.The calendar image must meet the following requirements:
the very top of the image should display the month and year astext, (e.g., October 2013),the first row in the calendar itself must display abbreviations forthe seven days of the week, starting with Sunday at the left edge,all days must appear as numbered boxes, andthe first row of days must be padded with 0 or more empty boxesat the left, as needed.
Please note we are not specifying the size of the image produced bycal. Use your judgment, and make sure the image and the fonts arelarge enough that we can easily see all details and read all text.To check the accuracy of your results (with respect to the dates), youwill find it helpful to use the built-in command cal in a console.Think carefully about how to write this function. Do not write anenormous, brute-force implementation where you consider everypossible case in turn. Seek a solution that is both concise and elegant(there are many).
42 / 66
CMSC 15100: Introduction toComputer Science IUniversity of Chicago, Autumn 2012
CS151 Coursework | CS151 Home
Homework 5Homework 5 is due Monday, November 11, 2013 at 11:59pm.
Intermediate Student with lambda(require 2htdp/image)(require racket/match)
Please submit your work with filename hw5.rkt in a directory in yourrepository called hw5.
Homework ProblemsFor every function you write, you must write a contract, a purpose, andtests with check-* utilities, with the usual exception for functions thatproduce complex images, for which "eyeball tests" are appropriate.Write helper functions where they are needed. All functions needcontracts, purposes and tests, even if they are "only" helper functions.
Polymorphic PairsYou will need to construct pairs in various places throughout this work.Copy the following data definition into your hw5.rkt:
;; a (pair ) is a (make-pair x y);; where x is an , y is a (define-struct pair (first second))
Problem 1We present selection sort as an algorithm for sorting integers intoascending order (without loss of generality). The algorithm is asfollows.
The empty list is trivially sorted, so simply return it.For non empty lists containing n>0 elements, proceed as follows.
43 / 66
Split the list into two parts: the minimum, and a list of length n-1containing everything but the minimum. Recursively sort the latterlist, and cons the minimum onto the front of it. Return the result.
To implement selection sort, write the following operation first:;; select-min : (listof num) -> (pair num (listof num))
Make sure that the time cost of select-min is linear and not exponential(or, for that matter, anything worse than linear).Having written select-min, write
;; selection-sort : (listof num) -> (listof num)
The following is an unofficial part of this work, with nothing to submit. WithoutGoogling or running off to Wikipedia, give some thought to the timecost needed to run selection sort. Does it seem like a fast sortingalgorithm? Does it remind you of any other sorting algorithms we'veseen? Try to analyze its cost on paper, with a recurrence relation.
Problem 2As presented in class, quicksort rearranges lists of numbers intoascending order. Generalize quicksort so that it can sort any kind of datainto any order, given an appropriate comparison test, by writing thefollowing higher-order sorting function:
;; quicksort-by : ( -> bool) (listof ) -> (listof )
Use quicksort-by to implement the following sorting functions:desc-sort : (listof num) -> (listof num) to order a list ofnumbers from largest to smallest.If a name is a structure from (define-struct name (fnamelname)), write name-sort : (listof name) -> (listof name) toorder a list of names in standard last name, first namealphabetical order. (Note string
For the first color to be "less than" the second, its red component mustbe less than the other's, or the reds must be equal and the green mustbe less than the other's, or the reds and greens must be equal and theblue must be less than the other's. Otherwise, the first color is not lessthan the second.These ordering functions are necessary to build binary search trees ofcolors, per the following data definition:
;; a cct ("color count tree") is either;; - empty, or;; - a (make-cct c n lsub rsub) ;; where c is a color, n is a number, and lsub and rsub are ccts(define-struct cct (c n lsub rsub))
A well-formed cct is constructed such that every color in the leftsubtree is less than the root, and every color in the right subtree isgreater than the root. The number n at each node is a count, to bediscussed further below.Write a function cct-insert : color cct -> cct to insert a color into acct. To insert into a given nonempty tree, if a color is less than the root, itshould be inserted into the left subtree; if a color is greater than the root,it should be inserted into the right subtree; and if a color is equal to theroot, the count at the root node should be increased by one. In this way,a cct tracks not only what colors are in a list of colors, but also howmany times each color appears.To insert a color into an empty tree, construct a singleton tree with twoempty subtrees and count 1.Having written cct-insert, write
;; image->cct : image -> cct
to build a cct from the pixels of a given image. For example, the cct of(square 10 "solid" (make-color 255 0 0)) is a singleton tree with onecolor node with count 100.Also, write
;; color-count : color cct -> num
to return the count corresponding to the color in the given cct. Take carenot to search both subtrees recursively at every step (which forfeits thebenefit of the search tree structure). Return 0 when the color is notpresent in the tree.
Problem 4Run-length encoding is a data-compression scheme for lists. A run-length encoded list is a list of pairs, whereby each pair includes an itemof data and a number, indicating how many of that item there are in thecurrent "run."
45 / 66
For example, consider the following list of nine items.(list 'A 'A 'B 'B 'B 'B 'C 'C 'C)
This list contains a run of two As, then 4 Bs, then three Cs. Its run-lengthencoded equivalent is as follows:
(list (make-pair 'A 2) (make-pair 'B 4) (make-pair 'C 3))
Run-length encoding can compress certain lists extremely well, othersnot at all. Think of the characteristics of a list that make it either well orpoorly suited to run-length encoding.Implement the following functions:
;; rle : ( -> bool) (listof ) -> (listof (pair num))
;; rld : (listof (pair num)) -> (listof )
The function rle (run-length encode) must consume two arguments: anequality test on items of some type and a list of , and produce thecorresponding run-length encoding. For the example in the lastparagraph, the run-length encoding is written
(rle symbol=? (list 'A 'A 'B 'B 'B 'B 'C 'C 'C))
The second function rld (run-length decode) should perform the inverseoperation. Note that no equality function is necessary to perform thisoperation.
Problem 5(This problem is closely related to lectures given in week 3.)Many interesting image transformations can be done a pixel at a time.For example, color photographs can be converted to black and white byapplying the same operation to each pixel. In such transformations, thesame infrastructure -- the code that unfurls the image into a list ofcolors, transforms all those colors, then packs the colors back into animage -- can be shared.First, write a higher-order function
;; map-image : (color -> color) image -> image
This function must call image->color-list, map and color-list->bitmap.The luminance of a color is a measure of its brightness. Given colorcomponents r, g, and b, the luminance is calculated according to thefollowing formula:
0.2126 * r + 0.7152 * g + 0.0722 * bWrite the function luminance : color -> num to compute this numberfor any color.
46 / 66
Implement the following pixel-by-pixel transformations as calls to map-image (and see the remarks that follow below):
grayscale : image -> image
negative : image -> image
grayscale-negative : image -> image
Remarks:To construct a grayscale image, for each color c, compute itsluminance m and replace it with a color (a shade of gray) whosered, green and blue components are each m (or, more precisely,the integer nearest m).To construct a negative, replace each color (r,g,b) with itscomplement (255-r,255-g,255-b).A grayscale negative is what it sounds like, per the two definitionsabove. Take care in your implementation of grayscale-negativethat, for efficiency's sake, you traverse each pixel only once, nottwice. That is to say, even though this function can be correctlyimplemented as (grayscale (negative i)) for some image i,you should avoid that implementation because it makes twocomplete passes over the image in question.
47 / 66
CMSC 15100: Introduction toComputer Science IUniversity of Chicago, Autumn 2012
CS151 Coursework | CS151 Home
Homework 6Homework 6 is due Tuesday, November 26, 2013 at 11:59pm.
Advanced Student(require racket/match)
This week, you should submit two files. Please submit a pdf forproblem 1, named hw6-p1.pdf. Please submit code for problems 2 and3 as usual in file hw6.rkt. Both should be in a directory in yourrepository called hw6.
Homework ProblemsFor every function you write, you must write a contract, a purpose, andtests with check-* utilities, with the usual exception for functions thatproduce complex images, for which "eyeball tests" are appropriate.Write helper functions where they are needed. All functions needcontracts, purposes and tests, even if they are "only" helper functions.
Problem 1Sets are essential to a huge variety of algorithms. This problemconsiders the efficiency of certain set operations when sets arerepresented as unordered lists. Without loss of generality, we willconsider sets of symbols (as opposed to some other kind of data).First, here is a data definition for symbol-set:
;; a symbol-set is a (listof symbol) containing no duplicate symbols
Here is a test for set membership under this data definition.;; set-mem? : symbol symbol-set -> bool(define (set-mem? s ss) (cond [(empty? ss) false]
48 / 66
[else (or (symbol=? s (first ss)) (set-mem? s (rest ss)))]))
Write out a time cost analysis for set-mem?. Your cost model shouldcount applications of symbol=?, which you may assume takes somefixed amount of time. Your conclusion should be that set-mem? runseither in constant, logarithmic, linear, n log n, quadratic, or exponential time.Here is set insertion, guarding against insertion of duplicates.
;; insert : symbol symbol-set -> symbol-set(define (insert s ss) (if (set-mem? s ss) ss (cons s ss)))
The cost of insert is simply the cost of set-mem?; you do not need towrite out an analysis for this.Here is a function for building a set of symbols from a list of symbols.(You could think of this as a duplicate elimination function.)
;; list->sym-set : (listof symbol) -> symbol-set(define (list->sym-set ss) (cond [(empty? ss) empty] [else (insert (first ss) (list->sym-set (rest ss)))]))
Write out a time cost analysis for list->sym-set. Your cost modelshould count the cost of insert. Your conclusion should be that list->sym-set runs either in constant, logarithmic, linear, n log n, quadratic, orexponential time.
Problem 2Piazza post 456 presented code for generic backtracking search. Thefollowing code is the same as the code at that post, with slightmodifications (some comments have been added and some variablenames changed).
;; is a type variable, a mnemonic for "state."
;; search : ( -> (or (listof ) 'goal)) -> (or false);; generic backtrack search starting from the start state. The next;; function either returns 'goal, when its argument is a goal state,;; '() when its argument is a dead end, or else a list of successor;; states.(define (search start next) (local {;; look : -> (or false) ;; starting from given state, return a goal state or false (define (look s) (match (next s) ['goal s] [next-states (local {;; lp : (listof ) -> (or false) ;; look for a goal from list of states; ;; return first goal encountered, or false (define (lp ss) (cond
49 / 66
[(empty? ss) false] [else (match (look (first ss)) [#f (lp (rest ss))] [g g])]))} (lp next-states))]))} (look start)))
Post 456 subsequently shows how this generic search can be applied tosearching binary trees, and also searching for a solution in the space ofall possible n-queens solutions (for any n).Here are two more problems that can be solved by genericbacktracking search, by defining, in each case, a state type, a value ofthat type representing the start state, and a next function to feed to thesearch function.
Problem 2a
The following coin puzzle comes fromhttp://www.puzzles.com/puzzleplayground/KeepItEven/KeepItEven.htm.Given a four by four square arrangement of coins (see the figure),remove any six coins such that each row and column contains an evennumber of coins.
Define a type cp-state (for "coin-problem state") and a function cp-nextof the appropriate type (examine the type of search above). Also, definea value cp-solution that calls search to find a solution to the problem.Note there are no successor states after six coins have been removedfrom the board; cp-next should behave accordingly.
Problem 2b
A 3x3 magic square is an arrangement of nine numbers such that thesum of each row, column and diagonal of numbers is the same. Here isa quasi-magic square populated with 1s:
1 1 1
1 1 1
50 / 66
1 1 1
Let the type ms-state (for "magic square state") be defined as follows:;; an ms-state is a (make-ms-state placed to-place) where;; - placed is a (listof (or num false)) of length 9, and;; - to-place is a (listof num) of length 0 to 9
The list placed must include the value false in each empty square andnumbers otherwise, and to-place is the list of numbers yet to be placedin the possible solution. The start state for the magic square consistingof all 1s is as follows:
(make-ms-state (make-list 9 false) (make-list 9 1))
Write ms-next, and define a value ms-solution-1-9 that calls search tobuild a 3x3 magic square containing the numbers from 1 to 9.
Problem 3Write the following functions that operate on vectors.The function vec-max should return the maximum value in a non-emptyvector of numbers.
;; vex-max : (vec num) -> num;; return the max value of a vector of numbers
The function vec-reduce consumes a commutative operator, andidentity, and a vector, and reduces the whole vector by that operator.The function is like a restricted fold. The fact that the operator iscommutative is not enforced by the function; it's the caller'sresponsibility. You may reduce either left to right or right to left.
;; vec-reduce : ( -> ) (vec ) -> ;; reduce the vector given a commutative operator and an identity
The function vec-indices should consume a test and a vector, andreturn the indices of the items in the vector for which the test is true.
;; vec-indices : ( -> bool) (vec ) -> (listof num);; return the list of indices of values for which the test is true, ;; in ascending order
51 / 66
CMSC 15100: Project 1Tues 10/29
CS151 Coursework | CS151 HomeProject 1 will be collected from your subversion repository on Monday,November 4 at 11:59pm.
Language: Intermediate Student withlambda(require 2htdp/image)(require racket/match)
Please create a project directory in your subversion repository with$ svn mkdir project
Work in the file project/proj1.rkt. It is important that this file hasexactly this name and location; we will be looking for your work underthis name at collection time.This week, you will build some of the foundational infrastructure of aprogram to play the game Gobblet Gobblers (presented in lectures onMonday Oct 28). Later in the quarter, you will write programs to playthe game "intelligently" by selecting good moves, but before we get tothat task, we need to establish what the game is: what data structuresrepresent it, what its rules are, what constitutes a victory, etc.
Modeling the GamePlease copy the following data definitions into your proj1.rkt file.Comments follow.;; a size is either 1, 2, or 3,;; representing small, medium, large in that order
;; a player is either 'blue or 'orange
;; a square is a natural number between 0 and 8 inclusive
;; a piece is a (make-piece s p) where;; - s is a size, and;; - p is a player(define-struct piece (size player))
;; an intro is a (make-intro p s) where;; - p is a piece, and;; - s is a square
52 / 66
(define-struct intro (piece square))
;; a shift is a (make-shift src dst) where;; - src and dst are both squares(define-struct shift (src dst))
;; a move is either;; - an intro, or;; - a shift
;; an inventory is a (listof piece)
;; a board is a (listof (listof piece)) of length exactly 9;; representing the squares of the board. Each square is represented;; by a list of pieces, where the pieces are ordered from outermost;; (i.e., biggest) to innermost (smallest). An square with no pieces;; is represented by the empty list.
;; The order of the 9 items in the list corresponds to the ;; squares on the board as follows:;; 0 1 2;; 3 4 5;; 6 7 8
;; a game is a (make-game next oinv binv board) where;; - next is a player, ;; - oinv ("orange inventory") is an inventory,;; - binv ("blue inventory") is an inventory, and;; - board is a board (per definition above)(define-struct game (next oinv binv board))
Some comments about the game structure:The game struct represents the complete state of the game at aparticular moment. Note that this includes more than just theboard. At any moment in the game, each player has an inventory(those pieces not yet on the board), and there is a playerdesignated to move next.In any functions that produce an image of the board (see below),the numbered squares must appear in the following layout(corresponding to their list order):
0 1 23 4 56 7 8
Game LogicWorking from the definitions above, implement the following functionsthat support the basic game logic:;; new-game : player -> game
This function generates an initial game state, where both players havefull inventories and the board has no pieces on it. The player argumentto new-game is the player who is to move first. Each player starts with sixpieces in their inventory: two of each size. Note that the fact that theboard is initially empty does not mean it is initially empty.
53 / 66
;; pieces-at : board square -> (listof piece)
Return the list of (from zero to three) pieces at the given square.;; pieces-valid? : game -> bool
Test that the collection of pieces in the game (on the board or in aninventory) includes exactly the pieces it should (that is, two of each sizeand six of both colors), and that each inventory contains only pieces ofthe right color.;; squares-valid? : board -> bool
Test whether all squares on the board are in a legal state: that is, thatthere are zero to three pieces on each square, and that all gobbling iswell-founded (every piece that gobbles another piece is strictly largerthan what it gobbles). Note that (as stated above) the list of pieces ateach square is in outer-to-inner order.;; square-available? : piece square board -> bool
A square is available to a given piece if it is either empty, or non-emptybut able to be gobbled by that piece.;; move-legal? : move game -> bool
Test whether a given move is legal in a given game state: that theplayer to move actually possesses the piece in question (in the case ofan intro), and that the destination square is available (per the previousfunction).;; victory? : player game -> bool
Test whether the given player is victorious in the given game state.;; apply-move : move game -> game
Apply the given move to the game and return the game's subsequentstate. Note that an intro move has the effect of both adding a piece tothe board and removing it from an inventory. If the proposed move isillegal, raise an error.Note that if the move is a shift that results in a "revealed" victory forthe non-moving player, the next game state should be the victory for thenon-moving player (since the game never reaches the state of thecompleted shift). In such a case, you can stash the would-be shiftedpiece back into its player's inventory in the game that results.
VisualizationsThe second part of the assignment is to implement several functions forvisualizing the state of the game.;; board-image: board -> image
54 / 66
Draw view of the board from directly above "as a person would see it"in the orientation given (see above). That is to say, you should see onlythe outermost "gobbling" piece in each square. You do not need to drawlittle faces on the pieces, or felt tufts on their tops; blue and orangecircles are adequate.;; xray-board-image: board -> image
This should draw an image like the previous function, but you shouldbe able to see all pieces in this view, not just the outermost ones (hence,xray). Concentric rings are adequate for this purpose.;; game-image : bool game -> image
Visualize the entire game state, including a visualization of the twoplayers' inventories and some indication of whose turn is next. Theboolean argument to the function indicates true for an xray boardimage, false for the standard board image with opaque pieces. As longas you represent the whole game clearly in your image, you have someliberty designing it. However, if you prefer to follow a specification,here is one:
Draw the board (in either opaque or xray mode, per theargument). Underneath the board, draw the orangeinventory as a row of images of pieces (i.e., orange circles).Underneath that, draw blue's inventory the same way.Underneath that, use text to write either orange is next orblue is next accordingly.
CommentsYou should write helper functions in abundance.Seek concise, clear solutions. If you find yourself copying and pastinglarge chunks of code, ask yourself whether there is a more elegantsolution, possibly involving higher-order programming.
55 / 66
CMSC 15100: Project 2Saturday 11/16
CS151 Coursework | CS151 Home
Language: Intermediate Student withlambda(require racket/match)(require 2htdp/image)(require 2htdp/universe)
Work in the file project/proj2.rkt. It is important that this file hasexactly this name and location; we will be looking for your work underthis name at collection time.Project 2 is due Monday, November 25 at 11:59pm.
Project 2Seed CodeLook in your repositories, under the folder project, for the fileproj2-seed.rkt. This file contains (slightly modified) Gobbler datadefinitions, game logic (along the lines of project 1), world verificationcode (also like project 1), and GUI code in the style of 2htdp/universe.This code is very close to complete, but we have left part of it to you.Part of the challenge of this project is to read and understand someoneelse's nontrivial code base (ours) such that you can extend it andcomplete it as needed.First, here are slightly modified Gobblers data definitions to build upon(the differences are called out in comments below):;;;;;;;;;;;;;;;;;;;; PLAYER, MOVE, AND GAME DATA DEFINITIONS ;;;;;;;;;;;;;;;;;;;;
;; a (pair X Y) is a (make-pair x y), where ;; x is an X and y is a Y(define-struct pair (fst snd))
;; a size is either 1, 2, or 3,;; representing small, medium, large in that order
;; a player is either 'blue or 'orange
;; a square is a natural number between 0 and 8 inclusive
;; a piece is a (make-piece s p) where56 / 66
;; - s is a size, and;; - p is a player(define-struct piece (size player))
;; an intro is a (make-intro p s) where;; - p is a piece, and;; - s is a square(define-struct intro (piece square))
;; a shft is a (make-shft src dst) where;; - src and dst are both squares;; NOTE: the name of this data structure has changed;; to avoid conflict with the name "shift" in universe(define-struct shft (src dst))
;; a move is either;; - an intro, or;; - a shft
;; an inventory is a (listof piece) ordered by increasing size
;; a board is a (listof (listof piece)) representing a rectangular;; grid of squares. The playing board is a 3x3 grid, while the;; inventory boards are 3x2 grids. Each square is represented;; by a list of pieces, where the pieces are ordered from outermost;; (i.e., biggest) to innermost (smallest). An square with no pieces;; is represented by the empty list. The order of the squares in;; this list is row-major order; for example, the playing board;; squares are ordered as follows:;;;; 0 1 2;; 3 4 5;; 6 7 8
;; a game is a (make-game next inv board) where;; - next is a player, ;; - inv is a pair (make-pair oinv binv), where;; - oinv ("orange inventory") is an inventory,;; - binv ("blue inventory") is an inventory, and;; - board is a board (per definition above);; NOTE: the inventories are stored in a pair structure now;;; this differs from the project 1 design(define-struct game (next inv board))
We have modified these data definitions as follows:what was called shift is now called shft (no i) because theformer is already defined in universe, andthe game now stores a pair of lists as an inventory, rather than twoseparate lists.
Game LogicImplement the following two functions:;; possible-moves : game -> (listof move)
If the game is in a victory state for one of the players, return the emptylist. Otherwise, return a list of all possible legal moves starting from thecurrent state of the game. Note this is not a list of all possible goodmoves, but rather all moves whether they are advantageous or not
57 / 66
(including shifts that cause an immediate loss).Except for victorious board positions, there are always moves possiblein this game. There are many ways to prove this: here is one. Thelargest pieces (size 3 pieces) can be blocked on at most three squares,since there are only three other pieces in the game that can block them.Every such piece is either in the inventory or on the board. If the piece isin the inventory, there must be at least six squares (of the nine) availableto it for an intro move. If the piece is already on the board, there mustbe at least five squares (of the other eight) available to it for a shiftmove.;; random-move : game -> (or move false)
The function should return a randomly-selected legal move fromamong possible legal moves. It should do so with equal probabilityamong its choices. Writing random-move follows immediately fromhaving written possible-moves; simply select from among the list ofpossible moves at random. Use the built-in function;; random : num -> num to do so. You do not have to prove that youactually achieve equal probability; you may rely on built-in random. Ifthere are no legal moves, return false.Note the return type of random-move, with its application of or to twotypes, states that the return of this function is either a move or the valuefalse (the sole inhabitant of an implied false type). Types of this sort(or false) appear throughout the Gobblers GUI code and are, ingeneral, common. The predicate false? is built in to Racket and can beapplied to any value (not just booleans).
Completing the GUIImplement run-game with the following contract and purpose:;; run-game : player (game -> move) -> world;; given a first player and a move-choosing function,;; call big-bang and run the application
The body of run-game is simply a call to big-bang with appropriateclauses to-draw, on-mouse, on-key, on-tick, check-with, and stop-when.What each of these clauses must contain is discussed in turn below.Since big-bang itself returns a world (it returns the world as it was whenthe universe came to an end), if you call big-bang inside run-game, youwill return a value of the right type without doing anything else.The big-bang clauses are specified here:
to-draw
call the function that draws the world (provided)on-mouse
call the function that handles mouse events (provided)58 / 66
on-key
call a key-handling function that handles mouse events(not provided, discussed below)
on-tick
call the tick-handing function (provided, but discussedfurther below) with a tick interval of 1 second
check-with
call the function that checks if the world is valid(provided)
stop-when
test if the game play is done (no such functionprovided; just look for the 'quit state)
You might also include name and state clauses as you prefer (see theuniverse documentation if interested). A word of warning: theperformance of state is pretty awful in the presence of such an activemouse handler as ours.Please note the design of the provided tick-handling function:
;; tick-fn : (game -> move) -> (world -> world)
This is a curried function; given one argument of type game -> move, itreturns a world -> world function suitable for use with on-tick. Theargument it consumes is a move-choosing function, to be used by thecomputer on a tick event exactly when the world state is'waiting-for-computer.The key handler must behave as follows:
if the game is in a drag state, ignore all keystrokes.if the user strikes q, quit.if the user strikes r, reset the game.if the user strikes x, toggle xray mode. (The drawing will appearas an "xray" immediately, via our provided code, in lockstep withthe relevant boolean value in the current world.)if the game has just ended on victory, and the user strikes y, start anew game.if the game has just ended on victory, and the user strikes n, quit.
Other than that, keystrokes should have no effect.
CommentsPlease note that writing the assigned game logic and GUI functions(though few in number) will entail writing many helper functions.
59 / 66
Testing available-moves is complicated because there are so manyresults, and furthermore the results need to be presented in the sameorder in any check-expects if you're doing list-to-list comparison. Youcan test things about the results, like how many results there are, ormake sure that a given list of results includes a particular move or two.But the usual testing criteria don't apply. Use your judgment and becreative about testing it. Testing random-move is also complicated; youcan just test it in Interactions and convince yourself it works. And testingrun-game the check-expect way is impossible. The helper functionsmight be easy to test for each, though; test those the usual waywhenever possible.Seek concise, clear solutions. If you find yourself copying and pastinglarge chunks of code, ask yourself whether there is a more elegantsolution, possibly involving higher-order programming.
60 / 66
CMSC 15100: Project 3Wednesday 11/27
CS151 Coursework | CS151 Home
Language: Advanced Student(require racket/match)(require 2htdp/image)(require 2htdp/universe)
Work in the file project/proj3.rkt. It is important that this file hasexactly this name and location; we will be looking for your work underthis name at collection time.Project 3 is due Tuesday, December 10 at 11:59pm.
Project 3For project 2, you wrote
;; random-move : game -> (or move false)
The goal of project 3 is to write a program to make strategic rather thanrandom choices, to allow you to build a competitive Gobblers player.You may start with the project 3 seed code that will have been added toyour repository.
Game Strategy with MinimaxMinimax is an algorithm for game strategy. It depends on having someway to assign a numeric value to a game state.The following function assigns a number to each board position.
;; score : game -> num(define (score g) (cond [(victory? 'orange g) 1] [(victory? 'blue g) -1] [else 0]))
In automated game playing, functions like this are known as heuristicfunctions. This is as simple as a heuristic function can be, yet it is stilluseful. (More sophisticated heuristic functions have a greater variety ofpossible return values, not just identifying victories but also quantifying
61 / 66
the relative strength of intermediate positions as well.) In a zero-sumgame like Gobblers, one player (in this case, orange) wants the board toachieve the maximum possible score, while the opposed player wantsthe minimum.The minimax algorithm assigns a number to a game state as follows.Call one player the max player, and the other the min player (inGobblers, orange and blue respectively). If the game is finished, simplyassign the game a score per the chosen heuristic function. If the game isnot finished, consider all possible moves from the current game state,and recursively evaluate all the games that result from applying thosemoves. From among those, if it is the max player's (orange's) turn,choose the highest score, and if it is the min player's (blue's) turn, choosethe lowest score. To choose a move, the automated player simplyselects the most desirable move from among the possible moves thatleads to the game state with the highest or lowest score (for the maxplayer and min player, respectively).That is a simple statement of the minimax algorithm. For small games -- those with few possible states (for example, tic-tac-toe) -- a programcan enumerate the whole game in a few seconds, and proceedaccordingly. For larger games, exploration of the whole game space isinfeasible; one needs a way (or several) to limit the amount ofcomputation that needs to be done.For Gobblers, we will constrain the minimax algorithm such that it looksahead only a finite number of moves. A level of look-ahead is widelycalled the ply, as in, this program does a 3-ply search (meaning it looks3 moves ahead). According to our Racket prototypes, a 2-ply Gobblersplayer plays quickly and reasonably well and with some apparentcleverness, although it makes obvious mistakes. A 3-ply player playsbetter than 2 and takes noticeably longer, and a 4-ply player plays verywell (not perfectly) but takes a long time (dozens of seconds or moreper move).For the first part of project 3, implement
;; minimax : nat game -> integer
to consume the ply (the number of moves to look ahead) and a game,and assign a score using the heuristic function above per the minimaxalgorithm. Then implement
;; minimax-choose-move : nat game -> move
to choose a move given a ply and a game.In testing minimax and minimax-choose-move, u