Three Homework Problems
March 22, 2016
All of these are simple, and we’ve seen them before. We’ll use arrays, even though it is more natural to use lists in Scheme, and use mutation as is done in the imperative language that most beginning programmers learn. Here’s the program that sums an array by adding each element, from left to right, to an accumulator:
(define (sum vec) (let ((len (vector-length vec)) (sum 0)) (do ((i 0 (+ i 1))) ((= i len) sum) (set! sum (+ sum (vector-ref vec i))))))
> (sum '#(4 9 1 8 3 2 6)) 33
To reverse an array, we set pointers at both ends of the array, swap the values there, move both pointer toward the middle, and repeat, stopping when the pointers meet:
(define (reverse! vec) (let ((len (vector-length vec))) (do ((lo 0 (+ lo 1)) (hi (- len 1) (- hi 1))) ((<= hi lo) vec) (let ((temp (vector-ref vec lo))) (vector-set! vec lo (vector-ref vec hi)) (vector-set! vec hi temp)))))
> (reverse! '#(4 9 1 8 3 2 6)) #(6 2 3 8 1 9 4)
Insertion sort works the same way card players sort their hands: pick an item from the unsorted portion of the array, insert it in its proper location in the sorted portion of the array, and repeat until the entire array is sorted:
(define (sort! vec) (let ((len (vector-length vec))) (do ((i 0 (+ i 1))) ((= i len) vec) (do ((j i (- j 1))) ((or (zero? j) (<= (vector-ref vec (- j 1)) (vector-ref vec j)))) (let ((temp (vector-ref vec j))) (vector-set! vec j (vector-ref vec (- j 1))) (vector-set! vec (- j 1) temp))))))
> (sort! '#(4 9 1 8 3 2 6)) #(1 2 3 4 6 8 9)
Common errors of beginning programmers are integer overflow in the first task, mis-understanding pointers in the second task, and getting the stopping criterion wrong in the third task. You can run the program at http://ideone.com/D1DZYX.
In C.
We can represent an array as a function from integers to values, together with a size, eg. in Javascript { f: f, length: n } can represent an array [f[0],f[1],..,f[n-1]]. We can then define the required operations as: