Homework 6: Higher-Order Procedures Due: 11:59 PM, Oct 16, 2018

Similar documents
Homework 6: Higher-Order Procedures Due: 10:00 PM, Oct 17, 2017

Homework 7: Subsets Due: 11:59 PM, Oct 23, 2018

Homework 3: Recursion Due: 11:59 PM, Sep 25, 2018

Homework 12: Tail Recursion and Analysis Due: 11:59 PM, Dec 4, 2018

Homework 8: Matrices Due: 11:59 PM, Oct 30, 2018

Lab 7: OCaml 12:00 PM, Oct 22, 2017

(Provisional) Lecture 08: List recursion and recursive diagrams 10:00 AM, Sep 22, 2017

(Provisional) Lecture 22: Rackette Overview, Binary Tree Analysis 10:00 AM, Oct 27, 2017

CS61A Notes 02b Fake Plastic Trees. 2. (cons ((1 a) (2 o)) (3 g)) 3. (list ((1 a) (2 o)) (3 g)) 4. (append ((1 a) (2 o)) (3 g))

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

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

User-defined Functions. Conditional Expressions in Scheme

Module 8: Local and functional abstraction

CSCI0170. Today s topics. Predicates Natural Number recursion Recursion Diagrams List recursion A first glance at the design recipe

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

Functional abstraction. What is abstraction? Eating apples. Readings: HtDP, sections Language level: Intermediate Student With Lambda

Functional abstraction

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

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

Repetition Through Recursion

CS 314 Principles of Programming Languages. Lecture 16

The Design Recipe Fall 2018

YOUR NAME PLEASE: *** SOLUTIONS ***

Racket Style Guide Fall 2017

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

Module 5: Lists. Readings: HtDP, Sections 9, 10.

Principles of Programming Languages Topic: Functional Programming Professor L. Thorne McCarty Spring 2003

CSE413 Midterm. Question Max Points Total 100

Functional Programming - 2. Higher Order Functions

CS3L Summer 2011 Final Exam, Part 2 You may leave when finished; or, you must stop promptly at 12:20

CS115 - Module 10 - General Trees

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

The Design Recipe Fall 2017

Lab 10: OCaml sequences, comparators, stable sorting 12:00 PM, Nov 12, 2017

CS61A Notes Week 6: Scheme1, Data Directed Programming You Are Scheme and don t let anyone tell you otherwise

CS115 - Module 9 - filter, map, and friends

Lab 1: Setup 12:00 PM, Sep 10, 2017

Discussion 4. Data Abstraction and Sequences

Functional Programming. Pure Functional Programming

CS 314 Principles of Programming Languages

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))

How to Design Programs

Lab 4: Imperative & Debugging 12:00 PM, Feb 14, 2018

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

A Brief Introduction to Scheme (II)

Lecture 27: (PROVISIONAL) Insertion Sort, Selection Sort, and Merge Sort 10:00 AM, Nov 8, 2017

PAIRS AND LISTS 6. GEORGE WANG Department of Electrical Engineering and Computer Sciences University of California, Berkeley

Sample midterm 1 #1. Problem 1 (What will Scheme print?).

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

Homework: More Abstraction, Trees, and Lists

CS61A Discussion Notes: Week 11: The Metacircular Evaluator By Greg Krimer, with slight modifications by Phoebus Chen (using notes from Todd Segal)

cs1120: Exam 1 Due: Wednesday, 06 October at 3:30pm (in class)

CS 314 Principles of Programming Languages

Scheme. Functional Programming. Lambda Calculus. CSC 4101: Programming Languages 1. Textbook, Sections , 13.7

CS2500 Exam 2 Fall 2011

Working with recursion. From definition to template. Readings: HtDP, sections 11, 12, 13 (Intermezzo 2).

Lisp. Versions of LISP

Working with recursion

CS 135 Fall 2018 Final Exam Review. CS 135 Fall 2018 Final Exam Review 1

Putting the fun in functional programming

Warm-up and Memoization

SCHEME AND CALCULATOR 5b

Project 5 - The Meta-Circular Evaluator

Homework 2: Imperative Due: 5:00 PM, Feb 15, 2019

Project 5 - The Meta-Circular Evaluator

CSE413: Programming Languages and Implementation Racket structs Implementing languages with interpreters Implementing closures

RACKET BASICS, ORDER OF EVALUATION, RECURSION 1

Lecture 5: Implementing Lists, Version 1

CSE 341 Section Handout #6 Cheat Sheet

Introduction to Typed Racket. The plan: Racket Crash Course Typed Racket and PL Racket Differences with the text Some PL Racket Examples

CS 3L (Clancy) Solutions and grading standards for exam 1

UNIVERSITY OF TORONTO Faculty of Arts and Science. Midterm Sample Solutions CSC324H1 Duration: 50 minutes Instructor(s): David Liu.

Typed Racket: Racket with Static Types

Scheme Quick Reference

Project 2: Scheme Interpreter

Organization of Programming Languages CS3200/5200N. Lecture 11

Generative and accumulative recursion. What is generative recursion? Example revisited: GCD. Readings: Sections 25, 26, 27, 30, 31

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

Functional Programming. Pure Functional Languages

CSSE 304 Assignment #13 (interpreter milestone #1) Updated for Fall, 2018

CS3: Introduction to Symbolic Programming. Lecture 14: Lists.

CSU211 Exam 2 Fall 2007

Discussion 11. Streams

PROBLEM SOLVING 11. July 24, 2012

cs1120: Exam 1 Due: Wednesday, 06 October at 3:30pm (in class)

The design recipe. Readings: HtDP, sections 1-5. (ordering of topics is different in lectures, different examples will be used)

Lecture 23: Priority Queues, Part 2 10:00 AM, Mar 19, 2018

15-110: Principles of Computing, Spring 2018

Notes on Higher Order Programming in Scheme. by Alexander Stepanov

CS 342 Lecture 7 Syntax Abstraction By: Hridesh Rajan

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

Module 10: Imperative Programming, Modularization, and The Future

Module 3: New types of data

Assignment: 7. Due: Language level: Allowed recursion:

Scheme: Expressions & Procedures

CS450 - Structure of Higher Level Languages

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

Introduction to Functional Programming in Racket. CS 550 Programming Languages Jeremy Johnson

Lab 2: Object-Oriented Design 12:00 PM, Jan 31, 2018

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

Transcription:

Integrated Introduction to Computer Science Klein Homework 6: Higher-Order Procedures Due: 11:59 PM, Oct 16, 2018 Contents 1 Fun with map (Practice) 2 2 Unfold (Practice) 3 3 Map2 3 4 Fold 4 5 All You Need is... Fold 5 6 Testing/Debugging 7 6.1 Is Contiguous Subsequence................................ 7 6.2 Increasing Subsequence.................................. 8 Introduction We have of course seen lambda expressions but usually in the context of a define, in which a variable is bound to the value of such an expression. However, it is useful to use lambda expressions without binding variables to them. The value of a lambda expression is of course a procedure; when we use such a procedure without binding a variable to it, we call the procedure an anonymous procedure. In this homework, you will learn about certain higher-procedures, procedures that take procedures as arguments, that have become a traditional part of functional programming. When providing the procedure argument to a higher-order procedure, it is often convenient and elegant to use a lambda expression to provide the argument. There is another, more technical reason that anonymous procedures are useful. You might get a hint of that in the coming lab. We do require use of anomyous procedures as arguments to foldr in the second task of Fold and the entirety of All You Need is... Fold. As always, you should add a design recipe for each procedure you write, including a procedure specification (input/output), recursion diagram (only for recursive procedures), and test cases. Note, anonymous procedures do not need design recipes but named procedures that use anonymous procedures still do.

How to Hand In To hand in your solutions to these problems, you must store them in appropriately-named files. Each should be named for the corresponding problem, as follows: ˆ README.txt ˆ map2.rkt ˆ fold.rkt ˆ allfold.rkt ˆ debugging.txt For this assignment, all files you turn in that contain code must be Racket files, so they must end with extension.rkt For this and every future assignment, you should also have a README.txt file whose first line contains only your Banner ID, and optionally with a message to the person grading explaining anything peculiar about the handin. For example: README.txt: B01234567 There s nothing to say except that I m turning in some files plus this README the way the instructions say that I should. To hand in your solutions to these problems, you must upload them to Gradescope. Do not zip or compress them. If you re-submit your homework, you must re-submit all files. If you choose to also store these files on department machines, all your solution files should reside in your /course/cs0170/homeworks/hw06 directory. Practice 1 Fun with map (Practice) map is a built-in procedure that takes in two arguments, a procedure and a list of data. It outputs a list of data where the i th element of the output list is the result of applying the input procedure to the i th element of the input list. By way of example: (map zero? (quote (0 1 0 2 0 3))) => (#t #f #t #f #t #f) (map (lambda (x) (* x x)) (quote (1 2 3))) => (1 4 9) map is specifically a higher-order procedure. A procedure is known as a higher-order procedure if it takes in one or more procedures our outputs a procedure. 2

Task: Uncle Pennybags due to recent inflation wants to be called Mr. Moneybags. Using map, write a procedure correct-name that replaces every occurrence of the symbol Pennybags in a list of symbols with the symbol Moneybags. (correct - name (quote (I met Pennybags at Reading Railroad))) => (I met Moneybags at Reading Railroad) (correct - name (quote (I love Pennybags))) => (I love Moneybags) Task: Sometimes you don t care about the value of an integer, just whether it is positive, negative, or zero. Using map, write a procedure whats-your-sign that consumes a list of integers and produces a list of symbols. The i th entry in the output list should be a symbol corresponding to the sign of the i th integer in the input list; positive if the integer is positive, negative if it is negative, or zero if it is zero. (whats - your - sign (quote (1 2 3))) => (positive positive positive) (whats - your - sign (list - 1 0 1)) => (negative zero positive) 2 Unfold (Practice) Write a procedure unfold, which consumes a one-argument procedure, f, and a natural number, n, and produces a list where the first element is f(n), the second element is f(n 1), the third element is f(n 2), and so on, up until the last element which is f(0). (unfold factorial 5) => (quote (120 24 6 2 1 1)) (unfold summorial 6) => (quote (21 15 10 6 3 1 0)) Problems 3 Map2 Task: Write a procedure map2 which consumes a two-argument procedure, proc, and two lists, alod1 and alod2, of equal length, and which produces a single list whose first element is the result 3

of applying proc to the first elements of alod1 and alod2, whose second element is the result of applying proc to the second elements of alod1 and alod2, and so on. Note: The input lists do not necessarily have to be of the same type! Example: (map2 + (quote (1 2 3)) (quote (3 2 1))) => (4 4 4) Note: Racket s built-in map procedure is very versatile. It can be used like this, for example: (map + (quote (1 2 3)) (quote (3 2 1))) => (4 4 4) As you might have guessed, you cannot use Racket s built-in map procedure to complete this task. Instead, your solution should use recursion explicitly, thereby demonstrating your understanding of the functionality of map (and map2). Task: Using map2, write a one-line procedure pairwise-max which consumes two lists of integers, alon1 and alon2, of equal length, and which produces a list whose ith element is the greater of the ith element of alon1 and the ith element of alon2. Hint: Feel free to use Racket s built-in max procedure. Example: (pairwise - max (quote (1 5 3)) (quote (4 2 6))) => (quote (4 5 6)) (pairwise - max (quote (1 5 3)) (quote - 4 10-6))) => (quote (1 10 3)) 4 Fold Consider a list of numbers: (cons 5 (cons 4 (cons 3 (cons 2 (cons 1 empty))))) What if we replaced every occurrence of cons with a different procedure, say +, and empty with a different value, say 0: (+ 5 (+ 4 (+ 3 (+ 2 (+ 1 0))))) From the point of view of higher-order procedures, these two expressions are equivalent. In each, a (lower-order) two-argument procedure is applied sequentially to a list, as follows: the procedure is first applied to the last element of the list and a base value in that order; the procedure is next applied to the second to last element of the list and the result of the first procedure application in that order; the procedure is then applied to the third to last element of the list and the result of the 4

second procedure application in that order; and so on. This sequence of procedure applications is called folding. Task: Write the procedure fold. It consumes three arguments: a two-argument procedure, a base value, and a list of data; and it applies the fold transformation to the input list using the given procedure and base value. Note: Your procedure should take as input the aforementioned three arguments in the exact order given above. (fold + 0 (quote (3 4 5))) => (+ 3 (+ 4 (+ 5 0))) => 12 (fold * 1 (quote (3 4 5))) => (* 3 (* 4 (* 5 1))) => 60 (fold cons empty (quote (c d e))) => (cons (quote c) (cons (quote d) (cons (quote e) empty))) Note: The fold procedure is also built into Racket but, for reasons that will become apparent later on in the semester, it is called foldr. Task: Write the following procedures using a single call to Racket s built-in fold procedure, foldr. In other words, do not use recursion explicitly. You should use an anonymous procedure or a built-in as an argument to foldr for all subproblems in this task. Note: Once you ve written the two procedures below, feel free to use Racket s built-in versions of append and flatten in your code. 1. my-append, which consumes two lists and produces another list that contains all the elements of the first, in their input order, followed by all the elements of the second, in their input order. You may assume the input lists are both of some type a (my - append (quote (1 2 3)) (quote (4 5 6))) => (1 2 3 4 5 6) (my - append (quote (#true #false)) (quote (#false))) => (#true #false #false) (my - append empty (quote (0 0 0))) => (0 0 0) 2. my-flatten, which consumes a non-empty list of lists, and produces another list that contains all the elements of the first sublist, in order, followed by all the elements of the second sublist, also in order, and so on. You may assume the input lists all contain data of the same type. Feel free to use Racket s built-in append procedure. 5

(my - flatten (quote ((1) (2 3) (4 5 6)))) => (1 2 3 4 5 6) (my - flatten (quote (() () ()))) => () 5 All You Need is... Fold Task: Write each of the procedures below using a single call to Racket s built-in fold procedure, foldr. You should use an anonymous procedure as an argument to foldr for all subproblems in this problem. You should do no explicit recursion yourself. You must follow these rules to earn full credit. Note: After completing this problem, you may use Racket s built-in map and filter procedures. To do so, switch to either Advanced or Intermediate Student with lambda in Dr. Racket. 1. my-map ˆ Input: a one-argument procedure, proc, and a list of data, alod such that proc operates on data of the type in alod ˆ Output: a list of data whose elements are the result of applying proc to each element of alod (my - map even? (quote (1 2 3))) => (quote (#false #true #false)) (my - map sub1 empty) => empty 2. my-filter ˆ Input: a one-argument predicate, pred, and a list of data, alod ˆ Output: a list consisting of all the elements of alod on which pred evaluates to true (filter cons? (quote ((17) () (18 19)))) => (quote ((17) (18 19))) (my - filter even? (quote (38 37 65 63 1 2 3 4 40))) => (quote (38 2 4 40)) 3. any? ˆ Input: a one-argument predicate, pred, and a list of data, alod such that pred operates on data of the type in alod 6

ˆ Output: a boolean indicating if pred evaluates to true for any datum in the list, and false otherwise (any? odd? (quote (1 3 5 7 9))) => true (any? even? empty) => false 4. all? ˆ Input: a one-argument predicate, pred, and a list of data, alod such that pred operates on data of the type in alod ˆ Output: a boolean indicating if pred evaluates to true for all data in the list, and false otherwise. all? produces true on the empty list, regardless of the predicate passed in. Hint: Your implementation of all? should be awfully similar to your implementation of any?. (all? odd? (quote (91 3 5 7 9))) => true (all? (lambda (x) (equal? x (quote banana)) (quote (banana nana banana)))) => false (all? empty? empty) => true 6 Testing/Debugging 6.1 Is Contiguous Subsequence The following code tests two sequences of integers to see whether small is a contiguous subsequence of big. That means that each item in small appears in big, in the same order as in small, all elements contiguous. For instance (1 2) is a subsequence of (1 2 5), but not a subsequence of (1 5 2). Here s the code: (define is - contiguous - subsequence (lambda (small big) (cond [(and (empty? small) (empty? big)) true] [(and (empty? small) (cons? big)) true] [(and (cons? small) (empty? big)) false] 7

[(and (cons? small) (cons? big)) (if (= (first small) (first big)) (is - contiguous - subsequence (cdr small) (cdr big)) (is - contiguous - subsequence small (cdr big)))]))) This code works by saying that if the first item in the two lists match, then we just need to check that the rest do, too, but if they DON T match, then it s still possible for the small list to appear later in the big list. (For instance, (1 2) is a subsequence of (5 1 2).) This program is incorrect. Task: Show that the program exhibits a kind of failure called a false positive, by showing a case where is-contiguous-subsequence evaluates to true, even though small is not a contiguous subsequence of big in the sense described. To do this you should write down a check-expect that fails. Suggestion: you ll get maximal value from this exercise by working it out by hand, rather than by pasting the code into DrRacket and trying to find something that breaks it by trial and error. The point of this exercise is that thinking through such cases before you write a procedure helps you write better check-expects and saves you debugging time. 6.2 Increasing Subsequence We have a sequence of natural numbers, like (2 5 3 6 7); we d like to find a longest increasing subsequence, where this time the elements of the subsequence need not be contiguous. So for our example list, one possible answer is (2 3 6 7). I say a longest instead of the longest because there may be two sequences of equal length. Consider (2 1 3); both (2 3) and (1 3) are longest increasing subsequences of (2 1 3). To solve this problem, we generalize: we write (longest-increasing-subsequence-with-start alon start) which tells us the longest increasing subsequence of alon where the first item in the subsequence is at least as big as start. Assuming we have this, we can write (define longest - increasing - subsequence (lambda (alon) (longest - increasing - subsequence - with - start alon 0))) We write the subprocedure as follows: first, if the list s empty, the answer s empty. Otherwise, if the first element of the list is less than start, we have to ignore it, so we recur on (rest alon). But if it s at least as large as start, we use it as the start of our output. Here s the code (define longest - increasing - subsequence - with - start (lambda (alon start) (cond [(empty? alon) empty] [(cons? alon) (if (< (car alon) start) (longest - increasing - subsequence - with - start (cdr alon) start) (cons (car alon) 8

(longest - increasing - subsequence - with - start (cdr alon) (+ 1 (car alon)))))]))) Notice how when we include the first item of the list, we recursively call our procedure, but we say that the remaining list has to start with a number that s at least (+ 1 (first alon)), so that if the input sequence contains something like 2 3 3 6, we ll only include the first 3. Once again, this code does not work. Task: Find an example of a sequence of natural numbers where the longest increasing subsequence is longer than the one found by this procedure. To do this you should write down a check-expect that fails. Also provide what the procedure will (incorrectly) evaluate to in Racket. Suggestion: you ll get maximal value from this exercise by working it out by hand, rather than by pasting the code into DrRacket and trying to find something that breaks it by trial and error. Please let us know if you find any mistakes, inconsistencies, or confusing language in this or any other CS 17 document by filling out the anonymous feedback form: http://cs.brown.edu/ courses/csci0170/feedback. 9