Structure and Interpretation of Computer Programs

Similar documents
Structure and Interpretation of Computer Programs

Structure and Interpretation of Computer Programs Summer 2014 Midterm 2

Structure and Interpretation of Computer Programs Summer 2014 Midterm 1

Structure and Interpretation of Computer Programs

Structure and Interpretation of Computer Programs

Structure and Interpretation of Computer Programs

Interpreters and Tail Calls Fall 2017 Discussion 8: November 1, 2017 Solutions. 1 Calculator. calc> (+ 2 2) 4

Structure and Interpretation of Computer Programs

CS 61A Interpreters, Tail Calls, Macros, Streams, Iterators. Spring 2019 Guerrilla Section 5: April 20, Interpreters.

Summer 2017 Discussion 10: July 25, Introduction. 2 Primitives and Define

MORE SCHEME. 1 What Would Scheme Print? COMPUTER SCIENCE MENTORS 61A. October 30 to November 3, Solution: Solutions begin on the following page.

Structure and Interpretation of Computer Programs

Structure and Interpretation of Computer Programs

Structure and Interpretation of Computer Programs

Structure and Interpretation of Computer Programs

SCHEME 10 COMPUTER SCIENCE 61A. July 26, Warm Up: Conditional Expressions. 1. What does Scheme print? scm> (if (or #t (/ 1 0)) 1 (/ 1 0))

Structure and Interpretation of Computer Programs

INTERPRETERS 8. 1 Calculator COMPUTER SCIENCE 61A. November 3, 2016

Structure and Interpretation of Computer Programs

YOUR NAME PLEASE: *** SOLUTIONS ***

Fall 2017 December 4, Scheme. Instructions

CSE341 Spring 2017, Final Examination June 8, 2017

Fall 2017 December 4, 2017

SCHEME 8. 1 Introduction. 2 Primitives COMPUTER SCIENCE 61A. March 23, 2017

Structure and Interpretation of Computer Programs Spring 2015 Midterm 2

Intro. Scheme Basics. scm> 5 5. scm>

Delayed Expressions Fall 2017 Discussion 9: November 8, Iterables and Iterators. For Loops. Other Iterable Uses

Structure and Interpretation of Computer Programs

Structure and Interpretation of Computer Programs

April 2 to April 4, 2018

Structure and Interpretation of Computer Programs Summer 2015 Midterm 2

SCHEME 7. 1 Introduction. 2 Primitives COMPUTER SCIENCE 61A. October 29, 2015

TAIL RECURSION, SCOPE, AND PROJECT 4 11

Fall 2017 Discussion 7: October 25, 2017 Solutions. 1 Introduction. 2 Primitives

Structure and Interpretation of Computer Programs


CSE341 Spring 2017, Final Examination June 8, 2017

CS61A Midterm 2 Review (v1.1)

SCHEME AND CALCULATOR 5b

Structure and Interpretation of Computer Programs Summer 2015 Midterm 1

Scheme Basics > (butfirst '(help!)) ()

Structure and Interpretation of Computer Programs

Structure and Interpretation of Computer Programs

INTERPRETERS AND TAIL CALLS 9

CONCEPTS OF PROGRAMMING LANGUAGES Solutions for Mid-Term Examination

Spring 2018 Discussion 7: March 21, Introduction. 2 Primitives

CSE341 Autumn 2017, Final Examination December 12, 2017

Structure and Interpretation of Computer Programs Spring 2017 Mock Midterm 1

Final Exam Solutions. Structure and Interpretation of Computer Programs. Fall 2011 /12 /16 /12 /18 /10 /12 /80 INSTRUCTIONS

Structure and Interpretation of Computer Programs

;; definition of function, fun, that adds 7 to the input (define fun (lambda (x) (+ x 7)))

Structure and Interpretation of Computer Programs Spring 2014 Final (with corrections)

Structure and Interpretation of Computer Programs

Fall 2018 Discussion 8: October 24, 2018 Solutions. 1 Introduction. 2 Primitives

CSE413 Midterm. Question Max Points Total 100

Structure and Interpretation of Computer Programs

Structure and Interpretation of Computer Programs

This exam is worth 70 points, or about 23% of your total course grade. The exam contains 15 questions.

CS 61A, Fall, 2002, Midterm #2, L. Rowe. 1. (10 points, 1 point each part) Consider the following five box-and-arrow diagrams.

Structure and Interpretation of Computer Programs

Sample Final Exam Questions

TAIL CALLS, ITERATORS, AND GENERATORS 11

Deferred operations. Continuations Structure and Interpretation of Computer Programs. Tail recursion in action.

University of Massachusetts Lowell

A Brief Introduction to Scheme (II)

Structure and Interpretation of Computer Programs

Computer Science 21b (Spring Term, 2015) Structure and Interpretation of Computer Programs. Lexical addressing

CSE 413 Midterm, May 6, 2011 Sample Solution Page 1 of 8

Below are example solutions for each of the questions. These are not the only possible answers, but they are the most common ones.

Structure and Interpretation of Computer Programs

Structure and Interpretation of Computer Programs

Functional Programming. Pure Functional Programming

Structure and Interpretation of Computer Programs Fall 2016 Midterm 2

CS61A Summer 2010 George Wang, Jonathan Kotker, Seshadri Mahalingam, Eric Tzeng, Steven Tang

Structure and Interpretation of Computer Programs Spring 2019 Midterm 2

Macros & Streams Spring 2018 Discussion 9: April 11, Macros

Structure and Interpretation of Computer Programs

Midterm Review. CS61A Summer Katya Stukalova Jerome Baek

Structure and Interpretation of Computer Programs

TUPLES AND RECURSIVE LISTS 5

Procedural abstraction SICP Data abstractions. The universe of procedures forsqrt. Procedural abstraction example: sqrt

Write a procedure powerset which takes as its only argument a set S and returns the powerset of S.

Fall Semester, The Metacircular Evaluator. Today we shift perspective from that of a user of computer langugaes to that of a designer of

Midterm Exam 1 Solutions

ITERATORS AND STREAMS 9

CS 415 Midterm Exam Spring SOLUTION

A random five-digit number: a b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3

SCHEME INTERPRETER GUIDE 4

CSE341, Spring 2013, Final Examination June 13, 2013

Name EID. (calc (parse '{+ {with {x {+ 5 5}} {with {y {- x 3}} {+ y y} } } z } ) )

SCHEME The Scheme Interpreter. 2 Primitives COMPUTER SCIENCE 61A. October 29th, 2012

LINKED LISTS AND MIDTERM REVIEW

SQL AND FINAL REVIEW

COMPUTER SCIENCE IN THE NEWS. CS61A Lecture 21 Scheme TODAY REVIEW: DISPATCH DICTIONARIES DISPATCH DICTIONARIES 7/27/2012

Homework 1. Reading. Problems. Handout 3 CSCI 334: Spring, 2012

CS 415 Midterm Exam Fall 2003

CS 1110 Final, December 9th, Question Points Score Total: 100

Comp 311: Sample Midterm Examination

CS 275 Name Final Exam Solutions December 16, 2016

CS 314 Principles of Programming Languages. Lecture 16

Transcription:

CS 61A Summer 2014 Structure and Interpretation of Computer Programs Final Solutions INSTRUCTIONS ˆ You have 3 hours to complete the exam. ˆ The exam is closed book, closed notes, and closed electronics, except three 8.5 11 cheat sheets, and The Environment Diagram Rules. ˆ Mark your answers ON THE EXAM ITSELF. Answers outside of the space allotted to problems will not be graded. If you are not sure of your answer you may wish to provide a brief explanation. Full name SID Login TA & section time Name of the person to your left Name of the person to your right All the work on this exam is my own. (please sign) 0. (2 points) Your thoughts? What s been fun? What are you grateful for?

2 1. (18 points) What will Python output? Include all lines that the interpreter would display. If it would display a function, then write Function. If it would cause an error, write Error. Assume that you have started Python 3 and executed the following. These are entered into Python exactly as written. class Cat : name = " meow " def init (self, fish ): self. fish = fish def iter ( self ): while len ( self. fish ) > 0: yield lambda : self. fish [0]. getname () self. fish = self. fish [1:] class SuperCat ( Cat ): def init ( self ): self. lives = 9 def next ( self ): if len ( self. fish ) == 0: raise StopIteration return self. fish class Fish : def init (self, name ): self. name = name def len ( self ): fish = [ 'fish1 ', 'fish2 ', 'fish3 '] return len ( self. fish ) + 2 def getname ( self ): print ( self. name )

Login: 3 Expression Interactive Output print ( 'Cats are cool! ') Cats are cool! dory = Fish ( 'Dory ') marlene = Fish ( ' Marlene ') dory. name dari = Cat ([ dory, marlene, Fish ( 'Nemo ')]) print ( dari. fish [2]. getname ()) Dory Nemo None fishes = iter ( dari ) next ( fishes ) pusheen = SuperCat () pusheen. fish Cat. init ( pusheen, dari. fish ) next ( pusheen ). getname () for a in pusheen : a() dari. getname = Fish. getname dari. getname ( dory ) print ( len ( pusheen. fish )) print ( Fish. len ( pusheen )) Function Error: Attr Error Error: Attr Error Dory Marlene Nemo Dory 0 2

4 Expression lst1 = [ i for i in range (1, 3)] lst2 = list ( range (4, 6)) lst1 + lst2 x = [[ lst1 ], [ lst2 ]][0] x [0] is lst1 y = lambda : lambda lst1 : lambda : lst1 y ()( x )() is lst1 lst3 = lst1. append ( lst2 ) print ( lst3 ) lst1 lst1[2] is lst2 lst1[:1] lst1[2:] is lst1[2:] lst2[1] lst1 [ ] + lst2 [ ] + \ [0:0],[0:1],[1:2],[1:2] lst1 [ ] + lst2 [ ] Interactive Output [1, 2, 4, 5] True False None [1, 2, [4, 5]] True [1] False 5 [4, 2, 5]

Login: 5 2. (8 points) Alakazam! Fill in the environment diagram that results from executing the code below until the entire program is finished, an error occurs, or all frames are filled. You may not need to use all of the spaces or frames. You may want to keep track of the stack on the left, but this is not required. A complete answer will: ˆ Add all missing names, labels, and parent annotations to all local frames. ˆ Add all missing values created during execution. ˆ Show the return value for each local frame. ˆ The first function created by lambda should be labeled λ 1, the next one should be λ 2, and so on.

6 3. (4 points) Counting Song Let s write a song with generators! The song goes like this: 1, 1 2 1, 1 2 3 2 1... Write counting song, a function which yields each line of the song represented as a list (see the doctests). There are multiple ways to solve this. def counting_ song (): >>> cs = counting_ song () >>> next (cs) [1] >>> next (cs) [1, 2, 1] >>> next (cs) [1, 2, 3, 2, 1] >>> next (cs) [1, 2, 3, 4, 3, 2,1] song = [1] while True : yield song song = [1] + [ x + 1 for x in song ] + [1] # OR song = [1] while True : yield song + song [:: -1][1:] song. append ( song [ -1] + 1) 4. (5 points) Final tale of Waldo Write waldo-tail, a tail-recursive version of the wheres-waldo function you saw on Midterm 2. As a reminder, waldo-tail is a Scheme procedure that takes in a Scheme list and outputs the index of waldo if the symbol waldo exists in the list. Otherwise, it outputs the symbol nowhere. STk > ( waldo - tail '( moe larry waldo curly )) 2 STk > ( waldo - tail '(1 2)) nowhere ( define ( waldo - tail lst ) ( define ( helper lst index ) ( cond (( null? lst ) ' nowhere ) (( equal? 'waldo ( car lst )) index ) ( else ( helper ( cdr lst ) (+ index 1))))) ( helper lst 0))

Login: 7 5. (6 points) Guess-Tree Many popular guessing games have the following format: We start with a single question, such as Is it an animal? If the answer is yes, we ask a new question assuming what we re guessing is an animal ( Is it a dog? ). If the answer is no, we ask a new question assuming what we re guessing is not an animal ( Is it a place? ). We keep repeating this process until we are ready to make a guess. One possible representation of this game is using nested dictionaries. The dictionary has one key - the original question. Its value is another dictionary with at MOST two keys: a yes key and a no key (either of those keys may be missing). Each of those leads to another dictionary, and so on until we hit Success! or run into an empty dictionary. Another possible representation is as a BinaryTree. Your task is to write make guess tree, which takes in a nested dictionary representation and converts it into a BinaryTree representation: class BinaryTree : def init (self, entry, left =None, right = None ): self. entry = entry self. left = left self. right = right def make_ guess_ tree ( guess ): results = {'Is it an animal? ': \ {' yes ': {'Is it a dog? ': \ {' yes ': ' Success! '} }, \ 'no ': {'Is it a place? ': \ {'no ': {'Is it a person? ': \ {}}, 'yes ': {'Is it LA? ': \ {}} }}}} >>> t = make_ guess_ tree ( results ) >>> t. pretty_print () Is it an animal? / \ Is it a dog? Is it a place? / / \ Success! Is it LA? Is it a person? def make_ guess_ tree ( guess ): if type ( guess )!= type ({}): return Tree ( ' Success! ') question = list ( guess. keys ())[0] new_ tree = Tree ( question ) if 'yes ' in guess [ question ]: new_tree. left = make_guess_tree ( guess [ question ][ 'yes ']) if 'no ' in guess [ question ]: new_tree. right = make_guess_tree ( guess [ question ][ 'no ']) return new_ tree

8 6. (3 points) What Will Scheme Output? (Streams) For each of the following Scheme expressions, write the Scheme value to which it evaluates. If evaluation causes an error, write ERROR. If evaluation never completes, write FOREVER. Assume that you have started STk and executed the following statements in order. ( define ones ( cons- stream 1 ones )) ( define a ( cons- stream 1 ( cons-stream 3 b ))) ( define b ( cons-stream 2 a)) ( define happy ( cons- stream 2 ( stream-map * happy ( stream-cdr happy )))) Expression Interactive Output (ss ones) (1 1 1 1 1 1 1 1 1 1...) (1 2 3 1 2 3 1 2 3 1...) (ss (interleave a b)) (stream-car happy) (stream-car (stream-cdr happy)) 2 FOREVER 7. (5 points) Skipping Streams Define a stream of streams where every ith element in the larger stream is a stream of the multiples of i. Assume that the stream naturals and the function add-streams that we defined in the Streams discussion are given to you, in addition to the predefined functions in STk (such as stream-map, stream-filter, interleave, etc.) Do not add in any additional lines. Do not use any additional define expressions (but you may use lambda expressions). STk > ( ss naturals ) (1 2 3 4 5 6 7 8 9 10...) STk > ( ss ( add- streams naturals naturals )) (2 4 6 8 10 12 14 16 18 20...) STk > ( ss nth- multiples 4) ((1 2 3 4...) (2 4 6 8...) (3 6 9 12...) (4 8 12 16...)...) STk > ( ss ( stream- car ( stream- cdr nth- multiples ))) (2 4 6 8 10 12 14 16 18 20...) ( define nth- multiples ( cons- stream naturals ( stream-map ( lambda (s) ( add- streams naturals s)) nth- multiples )))

Login: 9 8. (6 points) Everyday I m Shufflin Define shuffle, which takes in a linked list and uses mutation to create a linked list with every pair of elements in the original list swapped (see the doctests). Your function must return a linked list, but that list must be created using only mutation of the rest attribute. You may NOT call the Link constructor. You may NOT assign to the first attribute. The point of this problem is to mutate rest attributes. USE RECURSION. def shuffle ( lst ): >>> shuffle ( Link (1, Link (2, Link (3, Link (4))))) Link (2, Link (1, Link (4, Link (3)))) >>> shuffle ( Link ('s ', Link ('c ', Link (1, Link (6, Link ('a ')))))) Link ('c ', Link ('s ', Link (6, Link (1, Link ('a '))))) if lst == Link. empty or lst. rest == Link. empty : # split points return lst new_ head = lst. rest lst. rest = shuffle ( new_head. rest ) new_ head. rest = lst return new_ head 9. (5 points) Searching the Depths Write member for deep lists in Logic. You may assume there is at most one occurrence of the element we are searching for. Hint: Consider how we could define separate facts to check for the element in either the car of the list or the cdr of the list. logic > ( query ( member 5 (((((((((((5))))))))))))) Success! logic > ( query ( member 4 (3 2 (1 4)))) Success! logic > ( query ( member? what ())) Failed. ( fact ( member?x (?x.?r ))) ( fact ( member?x (?y.?r)) ( member?x?r)) ( fact ( member?x (?y.?r)) ( member?x?y))

10 10. (6 points) Subset Sum Define subset sum, a function which takes in a list of numbers lst and a number n, and returns a subset of the elements in lst that adds up to n if such a subset exists, otherwise it returns None. If there are multiple subsets, return any one of them. Hint: We can choose either to keep the first element of the lst in our subset, or we can choose to not have the first element in our subset. def subset_sum (lst, n): >>> sorted ( subset_sum ([4, 8, 3], 11)) [3, 8] >>> print ( subset_sum ([4, 8, 3], 10)) None >>> sorted ( subset_sum ([5, 8, 10, 7, 23], 40)) [7, 10, 23] if n == 0: return [] elif n < 0 or lst == []: # Base case return None no_first_element = subset_sum ( lst [1:], n) if no_ first_ element is not None : return no_ first_ element using_first_element = subset_sum ( lst [1:], n - lst [0]) if using_ first_ element is not None : return [ lst [ 0]] + using_ first_ element 11. (3 points) Concurrency These two threads are running concurrently starting with x = 1, y = 1, >>> x = x + y >>> y = x ** 2 >>> y = x - 1 >>> x = y + 1 1) Line a1 read x 2) Line a1 read y 3) Line a1 write x 4) Line a2 read x 5) Line a2 write y 6) Line b1 read x 7) Line b1 write y 8) Line b2 read y 9) Line b2 write x Determine whether x = 5, y = 5 are possible values after the code is executed. If not possible, circle impossible. If possible, list the order in which the 9 steps are taken by their step numbers. $ 6,7,1,2,3,8,4,9,5 or 6, 7, 1, 2, 8, 3, 4, 5, 9 (there can be more answers)$

Login: 11 12. (9 points) Interpreters: Implementing Special Forms In the Scheme project, you implemented several special forms, such as if, and, begin, and or. Now we re going to look at a new special form: when. A when expression takes in a condition and any number of other subexpressions, like this: ( when < condition > <exp > <exp >... <exp >) If condition is true, all of the following subexpressions are evaluated in order and the value of the when is the value of the last subexpression. If it is false, none of them are evaluated and the value of the when is okay. For example, (when (= 1 1) (+ 2 3) (* 1 2)) would first evaluate (+ 2 3) and then (* 1 2). (a) (2 pt) Equivalent Scheme Expression Rewrite the when expression below into another Scheme expression which uses only the special forms you already implemented in your project. That is, create a Scheme expression which does the same thing as this when expression without using when. You should use if in your answer. ( when (= days- left 0) ( print ' im-free ) ' jk-final ) You may or may not need to use all of the lines provided. ( if (= days- left 0) ( begin ( print ' im-free ) ' jk-final ))

12 (b) (2 pt) Box and Pointer Remember that do when form, like the other do something form functions in the Scheme project, takes in vals and the env to evaluate in. We will be drawing the box-and-pointer diagram for vals above. As an example, the box-and-pointer diagram for (+ 1 1) would be + 1 1 In the example from the description, vals would be ((= 1 1) (+ 2 3) (* 1 2)). Draw the box-andpointer diagram for this list in the space provided below. * 1 2 + 2 3 = 1 1 (c) (3 pt) Implementing When Now implement do when form. Assume that the other parts of scheme.py have already been modified to accommodate this new special form. You may not need to use all of the lines provided. You do not need to worry about tail recursion. Remember that do when form must return two things - a Scheme expression or value and an environment or None. def do_when_form (vals, env ): return Pair ("if", Pair ( vals. first, Pair ( Pair (" begin ", \ vals. second ), nil ))), env (d) (2 pt) Implementing Another Special Form Now let s implement another special form until, which takes in a condition and a series of expressions, and evaluates the expressions in order only if the condition is NOT true. Implement do until form using do when form. (Remember that Scheme has a built-in not function which your interpreter can evaluate!) def do_until_form (vals, env ): return do_when_form ( Pair ( Pair ('not ', vals. first ), \ vals. second ), env )