Using vector-map!, define a Scheme procedure acronym! that
takes any vector of non-empty strings its argument and, as a side effect,
replaces each string with its initial character.
> (define example (vector "Standard" "Generalized" "Markup" "Language")) > (acronym! example) > example #(#\S #\G #\M #\L)
An accumulation procedure is one that traverses a vector from left to right, replacing each element with the result of performing some given operation on all of the elements up to and including that one. For example, here is a procedure that accumulates partial sums in a vector of numbers:
;;; accumulate-sum!: replace each element of a vector of numbers with the ;;; sum of it and all the elements preceding it ;;; Given: ;;; VEC, a vector of numbers. ;;; Results: ;;; None. ;;; Preconditions: ;;; None. ;;; Postcondition: ;;; For any natural number k less than the length of VEC, the element ;;; at (zero-based) position k is the sum of the elements initially in ;;; positions 0 through k inclusive in VEC. (define accumulate-sum! (lambda (vec) (let ((size (vector-length vec))) (let kernel ((position 0) (sum 0)) (if (< position size) (let ((new-sum (+ sum (vector-ref vec position)))) (vector-set! vec position new-sum) (kernel (+ position 1) new-sum)))))))
The following sample call demonstrates its effect:
> (define sample-vector (vector 3 1 4 1 5 9)) > (accumulate-sum! sample-vector) > sample-vector #(3 4 8 9 14 23)
And here is one that accumulates strings by concatenation:
;;; accumulate-strings!: replace each element of a vector of strings with ;;; the result of concatenating to the concatenation of all the elements ;;; preceding it ;;; Given: ;;; VEC, a vector of strings. ;;; Results: ;;; None. ;;; Preconditions: ;;; None. ;;; Postcondition: ;;; For any natural number k less than the length of VEC, the element ;;; at (zero-based) position k is the concatenation of the elements ;;; initially in positions 0 through k inclusive in VEC. (define accumulate-strings! (lambda (vec) (let ((size (vector-length vec))) (let kernel ((position 0) (so-far "")) (if (< position size) (let ((new-value (string-append so-far (vector-ref vec position)))) (vector-set! vec position new-value) (kernel (+ position 1) new-value)))))))
> (define string-vector (vector "To " "be " "or " "not " "to " "be "))
> (accumulate-strings! string-vector)
> string-vector
#("To "
"To be "
"To be or "
"To be or not "
"To be or not to "
"To be or not to be ")
Develop a higher-order Scheme procedure accumulate! that takes two
arguments -- a procedure proc of arity 2 and a ``seed value'' seed -- and returns an accumulated procedure that, when invoked, applies
proc across a given vector, starting by applying it to seed
and the initial element of the vector, then to the result of the first
application and the next element of the vector, and so on. Like the
accumulation procedures above, the one returned by accumulate!
should, as a side effect, replace all the elements of the vector it is
given with the intermediate results.
> (define accumulate-sum! (accumulate! + 0)) > (define accumulate-strings! (accumulate! string-append "")) > (define powers (make-vector 12 1)) > ((accumulate! (lambda (x y) (* 2 x y)) 1) powers) > powers #(2 4 8 16 32 64 128 256 512 1024 2048 4096)
Standard Scheme does not supply a list-set! procedure, for replacing
the element in a specified position in a given list. Develop one, using
set-car!.
A circular list is either a null list or a pair structure formed
by taking a list ls and replacing the cdr in its last cons cell with
ls itself. (For instance, in the reading, a-box is a
circular list of two elements, the symbols a and b.)
Develop a Scheme procedure circularize that takes a list as argument
and returns a circular list with the same elements, constructed entirely
from newly allocated cons-cells. In other words, copy each element
of the list, using cons to allocate storage at each step, instead of
just advancing to the end of the given list and overwriting the null in the
final cell. Notice that there is no exclamation point at the end of the
name of the procedure -- in this case we do not want circularize to have a side effect on its argument.