PS4: FirstClass Fun
 Due: It is in your best interest to finish this before Fall Break on Fri 05 Oct, but the grace period for this pset extends through Wed 10 Oct. PS5 will not be posted until Wed 10 Oct.
 Notes:
 This pset has a total of 105 points.
 This pset contains a solo problem worth 25 points with several subproblems
 You have seen the material for Problems 1 and 2; the material for Problem 3 is covered in the FirstClass Functions slides; and the material for Probelms 4 and 5 is covered in the HigherOrder List Functions Slides that will be started on Tue. Oct. 02.
 The problems needn’t be done in order. Feel free to jump around.

Times from Spring ‘18
Times Problem 1 Problem 2 Problem 3 Problem 4 Problem 5 Total average time (hours) 1.9 1.6 3.1 1.4 0.9 8.0 median time (hours) 1.8 1.5 2.8 1.2 0.7 8.3 25% took more than 2.0 2.0 4.0 1.8 1 10 10% took more than 3.1 2.6 4.4 2.1 1.5 10.5  Submission:
 In your yourFullName CS251 Fall 2018 Folder, create a Google Doc named yourFullName CS251 PS4.
 At the top of your yourFullName CS251 PS4 doc, include your name, problem set number, date of submission, and an approximation of how long each problem part took.
 For all parts of all problems, include all answers (derviations, code, etc.) in your PS4 google doc. Please format your evaluation derivations so that they’re easy to read. Format smallstep derivations and Racket code using a fixedwidth font, like Courier New. You can use a small font size if that helps.
 For Problem 1 (Solo Problem: Recursive List Functions)
 Be sure that all function definitions in
yourAccountNameps4solofunctions.rkt
also appear in your Google Doc (so that I can comment on them)  Drop a copy of your
yourAccountNameps4solofunctions.rkt
in your~/cs251/drop/ps04
drop folder on cs.wellesley.edu.
 Be sure that all function definitions in
 For Problems 3 through 5:
 Be sure that all function definitions in
yourAccountNameps4functions.rkt
also appear in your Google Doc (so that I can comment on them)  Drop a copy of your
yourAccountNameps4functions.rkt
in your~/cs251/drop/ps04
drop folder on cs.wellesley.edu.
 Be sure that all function definitions in
1. Solo Problem: Recursive List Functions (25 points)
This is a solo problem. This means you must complete it entirely on your own without help from any other person and without consulting resources other than course materials or online documentation. You may ask Lyn for clarification, but not for help.
In this problem you will define three recursive functions on lists. Some ground rules:
 Define all of your functions in a new file named
yourAccountNameps4solofunctions.rkt
that you create in Dr. Racket.  You should use explicit recursion on lists in all of your definitions.
 In all of your definitions, you should use the divide/conquer/glue strategy taught in class that you practiced in PS3.
 You should not use any higherorder list operations (e.g.,
map
,filter
,foldr
,foldl
,iterate
, orgenlist
) in this problem.  The only builtin Racket list operators you may use in your definitions are:
null
,null?
,cons
,list
,append
,first
,second
,third
, andrest
. (You may also use any Racket math or logic operators, such as+
,max
, etc.)  You should use Racket’s
let
construct to avoid evaluating an expression more than once. 
In this problem, you should define and use the following
prob1mapcons
helper function:(define (prob1mapcons x yss) (if (null? yss) null (cons (cons x (first yss)) (prob1mapcons x (rest yss)))))
(This has the special name
prob1mapcons
so as not to conflict with themapcons
function you will define in Problem 3.)  Other than
prob1mapcons
, you should not use any other helper functions in this problem.

(5 points) A lengthn prefix of a list is a list containing its first n elements in the same relative order. For example:
 The length0 prefix of
'(5 8 4)
is'()
 The length1 prefix of
'(5 8 4)
is'(5)
 The length2 prefix of
'(5 8 4)
is'(5 8)
 The length3 prefix of
'(5 8 4)
is'(5 8 4)
Define a function
prefixes
that takes a list as its single argument and returns a list of all of its prefixes ordered from shortest to longest. For example:> (prefixes '(5 8 4)) '(() (5) (5 8) (5 8 4)) > (prefixes '(2 5 8 4)) '(() (2) (2 5) (2 5 8) (2 5 8 4)) > (prefixes '(7 2 5 8 4)) '(() (7) (7 2) (7 2 5) (7 2 5 8) (7 2 5 8 4)) > (prefixes (range 0 11)) '(() (0) (0 1) (0 1 2) (0 1 2 3) (0 1 2 3 4) (0 1 2 3 4 5) (0 1 2 3 4 5 6) (0 1 2 3 4 5 6 7) (0 1 2 3 4 5 6 7 8) (0 1 2 3 4 5 6 7 8 9) (0 1 2 3 4 5 6 7 8 9 10))
 The length0 prefix of

(8 points) Define a function
summaxsquaresEvens
that takes a list of integers its single argument and returns a triple (i.e., a threeelement list) whose three elements are (1) the sum of the numbers in the list; (2) the maximum of the numbers in the list and (3) a list of the squares of all the even numbers in the list (maintaining relative order).> (summaxsquaresEvens '(9 2 8 5 4 7 1 6 3)) '(45 9.0 (4 64 16 36)) > (summaxsquaresEvens '(2 8 5 4 7 1 6 3)) '(36 8.0 (4 64 16 36)) > (summaxsquaresEvens '(8 5 4 7 1 6 3)) '(34 8.0 (64 16 36)) > (summaxsquaresEvens '(5 4 7 1 6 3)) '(26 7.0 (16 36)) > (summaxsquaresEvens '(9 2 8 5 4 7 1 6 3)) '(15 5.0 (4 64 16 36)) > (summaxsquaresEvens '(6 3 10 5 8)) '(32 3.0 (36 100 64)) > (summaxsquaresEvens (append (range 1 101 7) (range 201 0 2))) '(10951 201.0 (64 484 1296 2500 4096 6084 8464))
Your
summaxsquaresEvens
function should make a single pass over the input list to produce the output triple. I.e., you should not have separate recursions for calculating each of the three parts. 
(5 points) Suppose that we represent a set in Racket as a list without duplicates. Define a function
subsets
that takes as its single argument a set and returns a list of all subsets of a given set. The subsets within the result list can be in any order, but the order of elements within each set should have the same relative order as inset
.For example here are some of the (huge number of) possible answers for
(subsets '(3 1 2))
, any single one of which would be considered correct:'(() (1) (2) (3) (1 2) (3 1) (3 2) (3 1 2)) '((3 1 2) (3 2) (3 1) (1 2) (3) (2) (1) ()) '(() (2) (1) (1 2) (3) (3 2) (3 1) (3 1 2)) '((3 1 2) () (3 1) (2) (3) (1 2) (1) (3 2))
However, lists containing subsets like
(2 1)
,(1 3)
,(3 2 1)
, or(1 2 3)
could not be solutions, since the elements of these subsets are not in the same relative order as in(3 1 2)
. 
(7 points) A lengthn suffix of a list is a list containing its last n elements in the same relative order. For example:
 The length0 suffix of
'(5 8 4)
is'()
 The length1 suffix of
'(5 8 4)
is'(4)
 The length2 suffix of
'(5 8 4)
is'(8 4)
 The length3 suffix of
'(5 8 4)
is'(5 8 4)
Based on this definition, imagine a function
suffixes
that takes a list as its single argument and returns a list of all of its suffixes ordered from longest to shortest. For example:> (suffixes '(5 8 4)) '((5 8 4) (8 4) (4) ()) > (suffixes '(2 5 8 4)) '((2 5 8 4) (5 8 4) (8 4) (4) ()) > (suffixes '(7 2 5 8 4)) '((7 2 5 8 4) (2 5 8 4) (5 8 4) (8 4) (4) ()) > (suffixes (range 1 11)) '((1 2 3 4 5 6 7 8 9 10) (2 3 4 5 6 7 8 9 10) (3 4 5 6 7 8 9 10) (4 5 6 7 8 9 10) (5 6 7 8 9 10) (6 7 8 9 10) (7 8 9 10) (8 9 10) (9 10) (10) ())
In this problem, you are not asked to define
suffixes
, but are instead asked to define a related function namedweightedsuffixes
, which is assumed to take a list of numbers. The result ofweightedsuffixes
is a list similar to that returned bysuffixes
except that each nonempty sublist in the result ofweightedsuffixes
is the result of scaling all numbers in the corresponding nonempty sublist in the result ofsuffixes
by its first element. (The empty sublist insuffixes
yields the empty sublist inweightedsuffixes
).For example,
(weightedsuffixes '(7 2 5 8 4))
returns'((49 14 35 56 28) (4 10 16 8) (25 40 20) (64 32) (16) ())
because:(49 14 35 56 28)
is the result of scaling(7 2 5 8 4)
by7
(4 10 16 8)
is the result of scaling(2 5 8 4)
by2
(25 40 20)
is the result of scaling(5 8 4)
by5
(64 32)
is the result of scaling(8 4)
by8
(16)
is the result of scaling(4)
by4
()
is the sublist in the result ofweightedsuffixes
that corresponds to the sublist()
in the result ofsuffixes
Here are more examples of
weightedsuffixes
, the last two of which illustrate negative numbers:> (weightedsuffixes (range 3 8)) '((9 12 15 18 21) (16 20 24 28) (25 30 35) (36 42) (49) ()) > (weightedsuffixes (range 1 11)) '((1 2 3 4 5 6 7 8 9 10) (4 6 8 10 12 14 16 18 20) (9 12 15 18 21 24 27 30) (16 20 24 28 32 36 40) (25 30 35 40 45 50) (36 42 48 54 60) (49 56 63 70) (64 72 80) (81 90) (100) ()) > (weightedsuffixes '(2 6 1 3 8 4 7 5)) '((4 12 2 6 16 8 14 10) (36 6 18 48 24 42 30) (1 3 8 4 7 5) (9 24 12 21 15) (64 32 56 40) (16 28 20) (49 35) (25) ()) > (weightedsuffixes (range 3 4)) '((9 6 3 0 3 6 9) (4 2 0 2 4 6) (1 0 1 2 3) (0 0 0 0) (1 2 3) (4 6) (9) ())
In this problem, you will need to define a recursive list helper function in addition to
weightedsuffixes
. Recall that you cannot use the higherordermap
function here.  The length0 suffix of
2. Wacky Lists (15 points)
This problem shows that functions can be used to implement data structures like pairs and lists. Consider the following alternatives to Racket’s usual builtin cons
, car
, cdr
, null
, and null?
:
(define kons (λ (x y) (λ (s) (s #f x y))))
(define kar (λ (k) (k (λ (b l r) l))))
(define kdr (λ (k) (k (λ (b l r) r))))
(define knil (λ (s) (s #t 0 0)))
(define knil? (λ (k) (k (λ (b l r) b))))

(2 points) Use the smallstep substitution model (i.e., using ⇒) to show the evaluation of the value bound to the name
p
by the following declaration:(define p (kons 3 4))
Show every step. Do not abbreviate steps via ⇒*.
 (9 points) Use the smallstep substitution model (i.e., using ⇒) to show the evalulation of each of the following expressions. In these steps, you should use an environment env containing that contains the binding p↦λ_p, where λ_p is your value from part a. You should assume env also contains bindings for
kons
,kar
,kdr
,knil
, andknil?
.(kar p)
(kdr p)
(knil? p)
(knil? knil)
Show every step. Do not abbreviate steps via ⇒*.

(2 points) The following
sumto
function uses helper functionssum
anddownfrom
defined in terms of the listlike entities involvingkons
and friends. Does it actually calculate the sum of the integers from 1 ton
(inclusive)? Explain why or why not.(define (sumto n) (sum (downfrom n))) (define (sum nums) (if (knil? nums) 0 (+ (kar nums) (sum (kdr nums))))) (define (downfrom n) (if (<= n 0) knil (kons n (downfrom ( n 1)))))

(2 points) Can we replace all instances of
cons
/car
/cdr
/null
/null?
in Racket bykons
/kar
/kdr
/knil
/knil?
? Are there any ways in whichkons
/kar
/kdr
/knil
/knil?
do not behave likecons
/car
/cdr
/null
/null?
. Some things to think about in this context: What is the value of
(car null)?
(kar knil)`?  Can
cons
and friends interoperate withkons
and friends?
 What is the value of
3. Higherorder List Functions (35 points)
In this and the following problems you will revisit some functions from PS3 Problem 3, as well as see some new ones. However, rather than expressing them as recursions, you will express them in terms of higherorderlistoperators.
Notes:

For Problems 3 through 5, you should use Dr. Racket to create a single file named
yourAccountNameps4functions.rkt
that contains all the functions (including helper functions) that you define for these problems. 
In your definitions, you are not allowed to use recursion anywhere. (The one exception is the
insertsrec
helper function you are given in Problem 3l.) 
In your definitions, unless otherwise instructed, you should not introduce any new named helper functions, but you can (1) liberally use anonymous functions and (2) use functions you defined in previous parts in later parts.

(2 points) Using Racket’s
map
, define a functionmapremainder
that takes two arguments (an integerdivisor
and a listints
of integers) and returns an integer list the same length asints
in which every element is remainder of dividing the corresponding element ofints
bydivisor
.> (mapremainder 2 '(16 23 42 57 64 100)) '(0 1 0 1 0 0) > (mapremainder 3 '(16 23 42 57 64 100)) '(1 2 0 0 1 1) > (mapremainder 5 '(16 23 42 57 64 100)) '(1 3 2 2 4 0) > (mapremainder 17 '(16 23 42 57 64 100)) '(16 6 8 6 13 15)

(2 points) Using Racket’s
filter
, define a functionfilterdivisibleby
that takes two arguments (an integerdivisor
and a listints
of integers) and returns a new integer list containing all the elements ofints
that are divisible bydivisor
.> (filterdivisibleby 2 '(16 23 42 57 64 100)) '(16 42 64 100) > (filterdivisibleby 3 '(16 23 42 57 64 100)) '(42 57) > (filterdivisibleby 4 '(16 23 42 57 64 100)) '(16 64 100) > (filterdivisibleby 5 '(16 23 42 57 64 100)) '(100) > (filterdivisibleby 17 '(16 23 42 57 64 100)) '()
Use the following helper function, which is helpful in this problem and some of the following ones.
(define divisibleby? (lambda (num divisor) (= (remainder num divisor) 0)))

(3 points) Using Racket’s
foldr
, define a functioncontainsmultiple?
that takes an integerm
and a list of integersns
that returns#t
ifm
evenly divides at least one element of the integer listns
; otherwise it returns#f
. Usedivisibleby?
from above to determine divisibility.> (containsmultiple? 5 '(8 10 14)) #t > (containsmultiple? 3 '(8 10 14)) #f > (containsmultiple? 5 '()) #f

(3 points) Using Racket’s
foldr
, define a functionallcontainmultiple?
that takes an integern
and a list of lists of integersnss
(pronounced “enziz”) and returns#t
if each list of integers innss
contains at least one integer that is a multiple ofn
; otherwise it returns#f
. Usecontainsmultiple?
in your definition ofallcontainmultiple?
.> (allcontainmultiple? 5 '((17 10 2) (25) (3 8 5))) #t > (allcontainmultiple? 2 '((17 10 2) (25) (3 8 5))) #f > (allcontainmultiple? 3 '()) #t ; said to be "vacuously true"; there is no counterexample!

(2 points) Using Racket’s
foldr
, define a functionsnoc
that takes a valuex
and a listys
and returns the new list that results from addingx
to the end ofys
.> (snoc 4 '(7 2 5)) '(7 2 5 4) > (snoc 4 '()) '(4)

(2 points) Using Racket’s
foldr
, define a functionmyappend
that takes two lists,xs
andys
, and returns the new list that contains all the elements ofxs
followed by all the elements ofys
.> (myappend '(7 2 5) '(4 6)) '(7 2 5 4 6) > (myappend '() '(4 6)) '(4 6) > (myappend '(7 2 5) '()) '(7 2 5) > (myappend '() '()) '()
Note: You may not use Racket’s
append
in your definition. 
(2 points) Using Racket’s
foldr
, define a functionappendall
that takes a list of listsxss
and returns a new list that contains all the elements of the sublists ofxss
in their relative order.> (appendall '((1 2) (3) (4 5 6))) '(1 2 3 4 5 6) > (appendall '((1 2) (3))) '(1 2 3) > (appendall '((1 2))) '(1 2) > (appendall '()) '() > (appendall '(((1 2) (3 4 5)) ((6)) ((7 8) () (9)))) '((1 2) (3 4 5) (6) (7 8) () (9))
Note: You may use
append
ormyappend
in your definition. 
(2 points) Using Racket’s
map
, define a functionmapcons
that takes any valuex
and an nelement listys
and returns an nelement list of all pairs'(x . y)
wherey
ranges over the elements ofys
. The pair'(x . y)
should have the same relative position in the resulting list asy
has inys
.> (mapcons 17 '(8 5 42 23)) '((17 . 8) (17 . 5) (17 . 42) (17 . 23)) > (mapcons 3 '((1 6 2) (4 5) () (9 6 8 7))) '((3 1 6 2) (3 4 5) (3) (3 9 6 8 7)) > (mapcons 42 '()) '()

(3 points) Using Racket’s
foldr
, define a functionmycartesianproduct
that takes two listsxs
andys
and returns a list of all pairs'(x . y)
wherex
ranges over the elements ofxs
andy
ranges over the elements ofys
. The pairs should be sorted first by thex
entry (relative to the order inxs
) and then by they
entry (relative to the order inys
).> (mycartesianproduct '(1 2) '("a" "b" "c")) '((1 . "a") (1 . "b") (1 . "c") (2 . "a") (2 . "b") (2 . "c")) > (mycartesianproduct '(2 1) '("a" "b" "c")) '((2 . "a") (2 . "b") (2 . "c") (1 . "a") (1 . "b") (1 . "c")) > (mycartesianproduct '("c" "b" "a") '(2 1)) '(("c" . 2) ("c" . 1) ("b" . 2) ("b" . 1) ("a" . 2) ("a" . 1)) > (mycartesianproduct '("a" "b") '(2 1)) '(("a" . 2) ("a" . 1) ("b" . 2) ("b" . 1)) > (mycartesianproduct '(1) '("a")) '((1 . "a")) > (mycartesianproduct '() '("a" "b" "c")) '()
Note: You may use
mapcons
andappend
ormyappend
in your definition. 
(2 points) Using Racket’s
foldr
, define a functionmyreverse
that takes a listxs
and returns a new list whose elements are the elements ofxs
in reverse order. You may not use the builtinreverse
function.> (myreverse '(1 2 3 4)) '(4 3 2 1) > (myreverse '(1)) '(1) > (myreverse '()) '()
Note:
 We ask you to name your function
myreverse
because Racket already provides the same function namedreverse
(which you cannot use, of course).  You may use
snoc
orappend
ormyappend
in your definition.
 We ask you to name your function

(3 points) Assume that the elements of a list are indexed starting with 0. Using Racket’s
foldr
, define a functionalts
that takes a listxs
and returns a twoelement list of of lists, the first of which has all the evenindexed elements (in the same relative order as inxs
) and the second of which has all the oddindexed elements (in the same relative order as inxs
).> (alts '(7 5 4 6 9 2 8 3)) '((7 4 9 8) (5 6 2 3)) > (alts '(5 4 6 9 2 8 3)) '((5 6 2 3) (4 9 8)) > (alts '(4 6 9 2 8 3)) '((4 9 8) (6 2 3)) > (alts '(3)) '((3) ()) > (alts '()) '(() ())
Note: There is no need to treat evenlength and oddlength cases differently, nor is there any need to treat the singleton list specially.

(5 points) Using Racket’s
foldr
, define a functioninsertsfoldr
that takes a valuex
and an nelement listys
and returns an n+1element list of lists showing all ways to insert a single copy ofx
intoys
.> (insertsfoldr 3 '(5 7 1)) '((3 5 7 1) (5 3 7 1) (5 7 3 1) (5 7 1 3)) > (insertsfoldr 3 '(7 1)) '((3 7 1) (7 3 1) ( 7 1 3)) > (insertsfoldr 3 '(1)) '((3 1) (1 3)) > (insertsfoldr 3 '()) '((3)) > (insertsfoldr 3 '(5 3 1)) '((3 5 3 1) (5 3 3 1) (5 3 3 1) (5 3 1 3))
Notes:
 The
mapcons
function from above is useful here.  Think very carefully about the base case and the combination function for the recursive case.

Your definition should have exactly this pattern:
(define (insertsfoldr x ys) (foldr ; binary combiner goes here ; null value goes here ys))
 The

(4 points) Using Racket’s
foldr
, define a functionmypermutations
that takes as its single argument a listxs
of distinct elements (i.e., no duplicates) and returns a list of all the permutations of the elements ofxs
. The order of the permutations does not matter.> (mypermutations '()) '(()) > (mypermutations '(4)) '((4)) > (mypermutations '(3 4)) '((3 4) (4 3)) ; order doesn't matter > (mypermutations '(2 3 4)) '((2 3 4) (3 2 4) (3 4 2) (2 4 3) (4 2 3) (4 3 2)) > (mypermutations '(1 2 3 4)) '((1 2 3 4) (2 1 3 4) (2 3 1 4) (2 3 4 1) (1 3 2 4) (3 1 2 4) (3 2 1 4) (3 2 4 1) (1 3 4 2) (3 1 4 2) (3 4 1 2) (3 4 2 1) (1 2 4 3) (2 1 4 3) (2 4 1 3) (2 4 3 1) (1 4 2 3) (4 1 2 3) (4 2 1 3) (4 2 3 1) (1 4 3 2) (4 1 3 2) (4 3 1 2) (4 3 2 1))
Note: It is helpful to use
appendall
,map
, andinsertsfoldr
in your solution. If you are unable to defineinsertsfoldr
from the previous subproblem, you may use the following recursive version of theinserts
function from PS2 Problem 4:(define (insertsrec x ys) (if (null? ys) (list (list x)) (cons (cons x ys) (mapcons (first ys) (insertsrec x (rest ys))))))
4. forall?
, exists?
, find
, and zip
(20 points)
Below are some listprocessing functions that are not built in to Racket, but are handy in many situations:
(define (forall? pred xs)
(or (null? xs)
(and (pred (first xs))
(forall? pred (rest xs)))))
(define (exists? pred xs)
(and (not (null? xs))
(or (pred (first xs))
(exists? pred (rest xs)))))
(define (find pred notfound xs)
(if (null? xs)
notfound
(if (pred (first xs))
(first xs)
(find pred notfound (rest xs)))))
(define (zip xs ys)
(if (or (null? xs) (null? ys))
'()
(cons (cons (first xs) (first ys))
(zip (rest xs) (rest ys)))))
;; Can also define zip using Racket's mutlilist map
;; (but need to make both list args have same length;
;; otherwise Racket map will generate error if theyr don't)
;;
;; (define (zip xs ys)
;; (let ((minlen (min (length xs) (length ys))))
;; (map cons (take xs minlen) (take ys minlen))))
forall?
, exists?
, and find
are higherorder list functions involving a predicate.

forall?
returns#t
if the predicate is true on all elements of the list, and otherwise returns#f
.> (forall? (λ (x) (> x 0)) '(7 2 5 4 6)) #t > (forall? (λ (x) (> x 0)) '(7 2 5 4 6)) #f

exists?
returns#t
if the predicate is true on at least one element of the list, and otherwise returns#f
.> (exists? (λ (x) (< x 0)) '(7 2 5 4 6)) #t > (exists? (λ (x) (< x 0)) '(7 2 5 4 6)) #f

find
returns the first element of the list for which the predicate is true. If there is no such element, it returns the value supplied as thenotfound
argument.> (find (λ (x) (< x 0)) #f '(7 2 5 4 6)) 5 > (find (λ (x) (< x 0)) #f '(7 2 5 4 6)) #f
The zip
function is not higher order, but combines two lists by pairing (using cons
) the corresponding elements of the two lists. If the lists do not have the same length, zip
returns a list of pairs whose length is the length of the shorter of the two input lists:
> (zip '(1 2 3) '("a" "b" "c"))
'((1 . "a") (2 . "b") (3 . "c"))
> (zip '(1 2 3 4 5) '("a" "b" "c"))
'((1 . "a") (2 . "b") (3 . "c"))
> (zip '(1 2 3) '("a" "b" "c" "d" "e"))
'((1 . "a") (2 . "b") (3 . "c"))
In this problem, you will use the forall?
, exists?
, find
, and zip
functions to define other functions. Begin this problem by copying the definitions of these four functions into the top of your yourAccountNameps4functions.rkt
file.

(3 points) Using
exists?
, define a functionmember?
that determines if an elementx
appears in a listys
.> (member? 4 '(7 2 5 4 6)) #t > (member? 3 '(7 2 5 4 6)) #f > (member? '(7 8) '((1 2) (3 4 5) (6) (7 8) () (9))) #t > (member? '() '((1 2) (3 4 5) (6) (7 8) () (9))) #t > (member? '(5 6) '((1 2) (3 4 5) (6) (7 8) () (9))) #f
Note: Use
equal?
to compare the equality of two values. 
(5 points) Using
forall?
andexists?
, define a functionallcontainmultiplealt?
that is an alternative implementation of theallcontainmultiple?
function from Problem 3.> (allcontainmultiplealt? 5 '((17 10 2) (25) (3 8 5))) #t > (allcontainmultiplealt? 2 '((17 10 2) (25) (3 8 5))) #f > (allcontainmultiplealt? 3 '()) #t ; said to be "vacuously true"; there is no counterexample!
Note: You may use the
divisible_by
function from above, but not thecontainsmultiple?
function, and you may not define any new helper functions. 
(4 points) An association list is a list of pairs that represents a mapping from key to value. Each pair of key and value is represented by a cons cell, with the key in the
car
and the value in thecdr
. For example, the association list:'((2 . 3) (5 . 1) ("mountain" . #t))
maps the key
2
to the value3
, the key5
to the value1
, and the key"mountain"
to the value#t
.Using
find
, define a functionlookup
that takes a keyk
and an association listas
and returns:#f
if no mapping with keyk
was not found in the list; and a cons cell whose
car
isk
and whosecdr
is the corresponding value for the shallowest mapping ofk
in the association list.
For example:
> (lookup 5 '((2 . 3) (5 . 1) ("mountain" . #t))) '(5 . 1) > (lookup 1 '((2 . 3) (5 . 1) ("mountain" . #t))) #f > (lookup '(6 4) '((2 . 3) (5 . 1) ((6 4) . 8) (5 . 1) (17 23 42))) '((6 4) . 8) > (lookup 17 '((2 . 3) (5 . 1) ((6 4) . 8) (5 . 1) (17 23 42))) '(17 23 42) ; '(17 23 42) has a car of 17 and a cdr of '(23 42) > (lookup 23 '((2 . 3) (5 . 1) ((6 4) . 8) (5 . 1) (17 23 42))) #f
Note: Use
equal?
to test for equality of keys. This will support keys more interesting than just simple values. 
(5 points) Using
forall?
andzip
, define a functionsorted?
that determines if a list of numbersns
is in sorted order from low to high.> (sorted? '(7 4 2 5 4 6)) #f > (sorted? '(2 3 3 5 6 7)) #t > (sorted? '(2)) #t > (sorted? '()) #t > (sorted? (range 1000)) #t > (sorted? (append (range 1000) '(1001 1000))) #f > (sorted? (range 1000 0 1)) #f
Note: You will need to have a special case for the empty list.

(3 points) It is possible to define alternative versions of
forall?
andexists?
in terms offoldr
, as show below.(define (forallalt? pred xs) (foldr (λ (x subres) (and (pred x) subres)) #t xs)) (define (existsalt? pred xs) (foldr (λ (x subres) (or (pred x) subres)) #f xs)) > (forallalt? (λ (x) (> x 0)) '(7 2 5 4 6)) #t > (forallalt? (λ (x) (> x 0)) '(7 2 5 4 6)) #f > (existsalt? (λ (x) (< x 0)) '(7 2 5 4 6)) #t > (existsalt? (λ (x) (< x 0)) '(7 2 5 4 6))
However, just because it’s possible to define a function in terms of
foldr
does not mean its a good idea. Give a concrete example of a situation in whichforall?
is better thanforallalt?
.Note: For this problem, it’s critical to understand that
(and e1 e2)
desugars to(if e1 e2 #f)
5. foldrternop
(10 points)
Sometimes it is difficult to express a recursive list accumulation in terms of foldr
because the binary combiner function needs more information from the list than its first element. The following foldrternop
higherorder list function solves this problem by having the combiner function be a ternary (i.e., threeargument) function that takes both the first and rest of the given list in addition to the result of recursively processing the list:
(define (foldrternop ternop nullvalue xs)
(if (null? xs)
nullvalue
(ternop (first xs)
(rest xs)
(foldrternop ternop nullvalue (rest xs)))))
In this problem, you will use foldrternop
to implement two list functions that are challenging to implement in terms of foldr
(you already did insertsfoldr
above; see the extra credit problem for sorted?foldr
below). Begin this problem by copying the definition of foldrterntop
into the top of your yourAccountNameps4functions.rkt
file.

(5 points) Using
foldrternop
, define a functioninsertsfoldrternop
that takes a valuex
and an nelement listys
and returns an n+1element list of lists showing all ways to insert a single copy ofx
intoys
.> (insertsfoldrternop 3 '(5 7 1)) '((3 5 7 1) (5 3 7 1) (5 7 3 1) (5 7 1 3)) > (insertsfoldrternop 3 '(7 1)) '((3 7 1) (7 3 1) ( 7 1 3)) > (insertsfoldrternop 3 '( 1)) '((3 1) (1 3)) > (insertsfoldrternop 3 '()) '((3)) > (insertsfoldrternop 3 '(5 3 1)) '((3 5 3 1) (5 3 3 1) (5 3 3 1) (5 3 1 3))
Notes:

Your definition should have exactly this pattern:
(define (insertsfoldrternop x ys) (foldrternop {ternarycombiner} {nullvalue} ys))

You may use
mapcons
in your ternarycombiner function.


(5 points) Using
foldrternop
, define a functionsortedalt?
that is an alternative implementation of thesorted?
function from Problem 4.> (sortedalt? '(7 4 2 5 4 6)) #f > (sortedalt? '(2 3 3 5 6 7)) #t > (sortedalt? '(2)) #t > (sortedalt? '()) #t > (sortedalt? (range 1000)) #t > (sortedalt? (append (range 1000) '(1001 1000))) #f > (sortedalt? (range 1000 0 1)) #f
Note:

Your definition should have exactly this pattern:
(define (sortedalt? xs) (foldrternop ; ternarycombiner goes here ; nullvalue goes here xs))

Extra Credit: Using foldr
to define sorted?
(8 points)
This problem is optional. You should only attempt it after completing all the other problems.
As noted in Problem 5, it is challenging to define sorted
in terms of foldr
, but it turns out that it is stil possible to do this.
Using foldr
, define a function sorted?foldr
that is an alternative implementation of the sorted?
function from Problem 5.
> (sorted?foldr (list 7 4 2 5 4 6))
#f
> (sorted?foldr (list 2 3 3 5 6 7))
#t
> (sorted?foldr (list 2))
#t
> (sorted?foldr (list))
#t
Note:

Your definition should have exactly the following pattern:
(define (sorted?foldr ys) (cdr (foldr ; binary combiner goes here (cons ; nullvalue1 ; nullvalue2 ) ys)))
The idea is to accumulate a pair of (1) the first element of the rest of the list (or
#f
if there is none) and (2) a boolean indicating whether the rest of the list is sorted.