A First Look at Vectors

Until now we have paid little attention to how much time it takes to retrieve data from structures or lists. Now that we have a tool for stating general judgements, let's take a close look at this basic computation step. Recall the last problem of the preceding part: finding a route in a graph. The program <#67052#><#38279#>find-route<#38279#><#67052#> requires two auxiliary: <#67053#><#38280#>find-route/list<#38280#><#67053#> and <#67054#><#38281#>neighbors<#38281#><#67054#>. We paid a lot of attention to <#67055#><#38282#>find-route/list<#38282#><#67055#> and none to <#67056#><#38283#>neighbors<#38283#><#67056#>. Indeed, developing <#67057#><#38284#>neighbors<#38284#><#67057#> was just an exercise (see~#exfindroute1#38285>), because looking up a value in a list is by now a routine programming task. Here is a possible definition for <#67058#><#38286#>neighbors<#38286#><#67058#>:
<#71547#>;; <#67059#><#38291#>neighbors<#38291#> <#38292#>:<#38292#> <#38293#>node<#38293#> <#38294#>graph<#38294#> <#38295#><#38295#><#38296#>-;SPMgt;<#38296#><#38297#><#38297#> <#38298#>(listof<#38298#> <#38299#>node)<#38299#><#67059#><#71547#>
<#71548#>;; to lookup the <#67060#><#38300#>node<#38300#><#67060#> in <#67061#><#38301#>graph<#38301#><#67061#><#71548#> 
<#38302#>(d<#38302#><#38303#>efine<#38303#> <#38304#>(neighbors<#38304#> <#38305#>node<#38305#> <#38306#>graph)<#38306#> 
  <#38307#>(c<#38307#><#38308#>ond<#38308#> 
    <#38309#>[<#38309#><#38310#>(empty?<#38310#> <#38311#>graph)<#38311#> <#38312#>(error<#38312#> <#38313#>'<#38313#><#38314#>neighbors<#38314#> <#38315#>``can'<#38315#><#38316#>t<#38316#> <#38317#>happen'')]<#38317#> 
    <#38318#>[<#38318#><#38319#>else<#38319#> <#38320#>(c<#38320#><#38321#>ond<#38321#> 
            <#38322#>[<#38322#><#38323#>(symbol=?<#38323#> <#38324#>(first<#38324#> <#38325#>(first<#38325#> <#38326#>graph))<#38326#> <#38327#>node)<#38327#> <#38328#>(second<#38328#> <#38329#>(first<#38329#> <#38330#>graph))]<#38330#> 
            <#38331#>[<#38331#><#38332#>else<#38332#> <#38333#>(neighbors<#38333#> <#38334#>node<#38334#> <#38335#>(rest<#38335#> <#38336#>graph))]<#38336#><#38337#>)]<#38337#><#38338#>))<#38338#> 
The function is similar to <#67062#><#38342#>contains-doll?<#38342#><#67062#> and has roughly the same behavior. More concretely, <#67063#><#38343#>neighbors<#38343#><#67063#> is O(N) when we assume that <#67064#><#38344#>graph<#38344#><#67064#> is a list of <#38345#>N<#38345#> nodes. Considering that <#67065#><#38346#>neighbors<#38346#><#67065#> is used at every stage of the evaluation of <#67066#><#38347#>find-route<#38347#><#67066#>, <#67067#><#38348#>neighbors<#38348#><#67067#> is possibly a bottleneck. As a matter of fact, if the route we are looking for involves <#67068#><#38349#>N<#38349#><#67068#> nodes (the maximum), <#67069#><#38350#>neighbors<#38350#><#67069#> is applied <#38351#>N<#38351#> times, so the algorithm requires #tex2html_wrap_inline73938# steps in <#67070#><#38352#>neighbors<#38352#><#67070#>. In contrast to lists, structures deal with value extractions as a constant time operation. At first glance this observation seems to suggest that we use structures as representations of graphs. A closer look, however, shows that this idea doesn't work easily. The graph algorithm works best if we are able to work with the names of nodes and access a node's neighbors based on the name. A name could be a symbol or the node's number in the graph. In general, what we really wish to have in a programming language is
a class of compound values size with constant lookup time,
based on ``keys.''
Because the problem is so common, Scheme and most other languages offer at least one built-in solution. Here we study the class of <#67071#><#38355#>vector<#38355#><#67071#>s. A vector is a well-defined mathematical class of data with specific basic operations. For our purposes, it suffices to know how to construct them, how to extract values, and how to recognize them:
  1. The operation <#67072#><#38357#>vector<#38357#><#67072#> is like <#67073#><#38358#>list<#38358#><#67073#>. It consumes an arbitrary number of values and creates a compound value from them: a vector. For example, <#67074#><#38359#>(vector<#38359#>\ <#38360#>V-0<#38360#>\ <#38361#>...<#38361#>\ <#38362#>V-n)<#38362#><#67074#> creates a vector from <#67075#><#38363#>V-0<#38363#><#67075#> through <#67076#><#38364#>V-n<#38364#><#67076#>.
  2. DrScheme also provides a vector analogue to <#67077#><#38365#>build-list<#38365#><#67077#>. It is called <#67078#><#38366#>build-vector<#38366#><#67078#>. Here is how it works:
    <#38371#>(build-vector<#38371#> <#38372#>N<#38372#> <#38373#>f)<#38373#> <#38374#>=<#38374#> <#38375#>(vector<#38375#> <#38376#>(f<#38376#> <#38377#>0)<#38377#> <#38378#>...<#38378#> <#38379#>(f<#38379#> <#38380#>(-<#38380#> <#38381#>N<#38381#> <#38382#>1)))<#38382#>
    
    That is, <#67079#><#38386#>build-vector<#38386#><#67079#> consumes a natural number <#67080#><#38387#>N<#38387#><#67080#> and a function <#67081#><#38388#>f<#38388#><#67081#> on natural numbers. It then builds a vector of <#67082#><#38389#>N<#38389#><#67082#> items by applying <#67083#><#38390#>f<#38390#><#67083#> to <#67084#><#38391#>0<#38391#><#67084#>, ..., <#67085#><#38392#>N-1<#38392#><#67085#>.
  3. The operation <#67086#><#38393#>vector-ref<#38393#><#67086#> extracts a value from a vector in constant time. That is, it is O(1). The characteristic equations have the following shape:
    <#38398#>(vector-ref<#38398#> <#38399#>(vector<#38399#> <#38400#>V-0<#38400#> <#38401#>...<#38401#> <#38402#>V-n)<#38402#> <#38403#>i)<#38403#> <#38404#>=<#38404#> <#38405#>V-i<#38405#>
    
    where <#67087#><#38409#>i<#38409#><#67087#> is between <#67088#><#38410#>0<#38410#><#67088#> and <#67089#><#38411#>n<#38411#><#67089#> (inclusive). If <#67090#><#38412#>vector-ref<#38412#><#67090#> is applied to a vector and a natural number that is smaller than <#67091#><#38413#>0<#38413#><#67091#> or larger than <#67092#><#38414#>n<#38414#><#67092#>, <#67093#><#38415#>vector-ref<#38415#><#67093#> signals an error.
  4. The operation <#67094#><#38416#>vector-length<#38416#><#67094#> produces the number of items in a vector:
    <#38421#>(vector-length<#38421#> <#38422#>(vector<#38422#> <#38423#>V-0<#38423#> <#38424#>...<#38424#> <#38425#>V-n))<#38425#> <#38426#>=<#38426#> <#38427#>(+<#38427#> <#38428#>n<#38428#> <#38429#>1)<#38429#>
    
  5. The operation <#67095#><#38433#>vector?<#38433#><#67095#> is the vector-predicate. It produces <#67096#><#38434#>true<#38434#><#67096#> if its argument is a vector and <#67097#><#38435#>false<#38435#><#67097#> otherwise:
    <#38440#>(vector?<#38440#> <#38441#>(vector<#38441#> <#38442#>V-0<#38442#> <#38443#>...<#38443#> <#38444#>V-n))<#38444#> <#38445#>=<#38445#> <#38446#>true<#38446#>
    <#38447#>(vector?<#38447#> <#38448#>U)<#38448#> <#38449#>=<#38449#> <#38450#>false<#38450#> 
    
    if <#67098#><#38454#>U<#38454#><#67098#> is a value that isn't created with <#67099#><#38455#>vector<#38455#><#67099#>.
We can think of <#38457#>vector<#38457#>s as functions on a small, finite range of natural numbers. Their range is the full class of Scheme values. We can also think of them as tables that associate a small, finite range of natural numbers with Scheme values. Using vectors we can represent graphs like those in figures~#figgraph#38458> and~#figcyclicgraph#38459> with <#38460#>vector<#38460#>s if we use numbers as names. For example:

#tabular38462#

Using this translation, we can also produce a <#38466#>vector<#38466#>-based representation of the graph in figure~#figgraph#38467>:

<#38472#>(d<#38472#><#38473#>efine<#38473#> <#38474#>Graph-as-list<#38474#>
  <#38475#>'<#38475#><#38476#>(<#38476#><#38477#>(A<#38477#> <#38478#>(B<#38478#> <#38479#>E))<#38479#> 
    <#38480#>(B<#38480#> <#38481#>(E<#38481#> <#38482#>F))<#38482#> 
    <#38483#>(C<#38483#> <#38484#>(D))<#38484#> 
    <#38485#>(D<#38485#> <#38486#>())<#38486#> 
    <#38487#>(E<#38487#> <#38488#>(C<#38488#> <#38489#>F))<#38489#> 
    <#38490#>(F<#38490#> <#38491#>(D<#38491#> <#38492#>G))<#38492#> 
    <#38493#>(G<#38493#> <#38494#>())))<#38494#> 
<#38500#>(d<#38500#><#38501#>efine<#38501#> <#38502#>Graph-as-vector<#38502#>
  <#38503#>(vector<#38503#> <#38504#>(list<#38504#> <#38505#>1<#38505#> <#38506#>4)<#38506#> 
          <#38507#>(list<#38507#> <#38508#>4<#38508#> <#38509#>5)<#38509#> 
          <#38510#>(list<#38510#> <#38511#>3)<#38511#> 
          <#38512#>empty<#38512#> 
          <#38513#>(list<#38513#> <#38514#>2<#38514#> <#38515#>5)<#38515#> 
          <#38516#>(list<#38516#> <#38517#>3<#38517#> <#38518#>6)<#38518#> 
          <#38519#>empty))<#38519#> 
The definition on the left is the original list-based representation; the one on the right is a vector representation. The vector's <#67100#><#38523#>i<#38523#><#67100#>-th field contains the list of neighbors of the <#67101#><#38524#>i<#38524#><#67101#>-th node. The data definitions for <#67102#><#38525#>node<#38525#><#67102#> and <#67103#><#38526#>graph<#38526#><#67103#> change in the expected manner. Let's assume that N is the number of nodes in the given graph:
A <#67104#><#38528#>node<#38528#><#67104#> is an natural number between 0 and N-1.
A <#67105#><#38531#>graph<#38531#><#67105#> is a vector of <#67106#><#38532#>node<#38532#><#67106#>s: <#67107#><#38533#>(vectorof<#38533#><#38534#> <#38534#><#38535#>(listof<#38535#>\ <#38536#>node))<#38536#><#67107#>.
The notation <#67108#><#38538#>(vectorof<#38538#>\ <#38539#>X)<#38539#><#67108#> is similar to <#67109#><#38540#>(listof<#38540#><#38541#> <#38541#><#38542#>X)<#38542#><#67109#>. It denotes a vector that contains items from some undetermined class of data <#67110#><#38543#>X<#38543#><#67110#>. Now we can re-define <#67111#><#38544#>neighbors<#38544#><#67111#>:
<#71549#>;; <#67112#><#38549#>neighbors<#38549#> <#38550#>:<#38550#> <#38551#>node<#38551#> <#38552#>graph<#38552#> <#38553#><#38553#><#38554#>-;SPMgt;<#38554#><#38555#><#38555#> <#38556#>(listof<#38556#> <#38557#>node)<#38557#><#67112#><#71549#>
<#71550#>;; to lookup the <#67113#><#38558#>node<#38558#><#67113#> in <#67114#><#38559#>graph<#38559#><#67114#><#71550#> 
<#38560#>(d<#38560#><#38561#>efine<#38561#> <#38562#>(neighbors<#38562#> <#38563#>node<#38563#> <#38564#>graph)<#38564#> 
  <#38565#>(vector-ref<#38565#> <#38566#>graph<#38566#> <#38567#>node))<#38567#> 
As a result, looking up the neighbors of a node just became a constant-time operation, and we can truly ignore it when we study the abstract running time of <#67115#><#38571#>find-route<#38571#><#67115#>.
<#38574#>Exercise 29.3.1<#38574#> Test the new <#67116#><#38576#>neighbors<#38576#><#67116#> function. Use the strategy of section~#secequaltest#38577> to formulate the tests as boolean expressions.~ external Solution<#67117#><#67117#> <#38583#>Exercise 29.3.2<#38583#> Adapt the rest of the <#67118#><#38585#>find-route<#38585#><#67118#> program to the new vector representation. Adapt the tests from exercises~#exfindroute2#38586> through~#exfindroute4#38587> to check the new program. Measure how much time the two <#67119#><#38588#>find-route<#38588#><#67119#> programs consume to compute a route from node A to node E in the graph of figure~#figgraph#38589>. Recall that <#67120#><#38590#>(time<#38590#>\ <#38591#>expr)<#38591#><#67120#> measures how long it takes to evaluate <#67121#><#38592#>expr<#38592#><#67121#>. It is good practice to evaluate <#67122#><#38593#>expr<#38593#><#67122#>, say, 1000 times when we measure time. This produces more accurate measurements. external Solution<#67123#><#67123#> <#38599#>Exercise 29.3.3<#38599#> Translate the cyclic graph from figure~#figcyclicgraph#38601> into our vector representation of graphs.~ external Solution<#67124#><#67124#>
Before we can truly program with vectors, we must understand the data definition. The situation is comparable to that when we first encountered lists. We know that <#67125#><#38609#>vector<#38609#><#67125#>, like <#67126#><#38610#>cons<#38610#><#67126#>, is provided by Scheme, but we don't have a data definition that directs our program development efforts. So, let us take a look at vectors. Roughly speaking, <#67127#><#38611#>vector<#38611#><#67127#> is like <#67128#><#38612#>cons<#38612#><#67128#>. The <#67129#><#38613#>cons<#38613#><#67129#> primitive constructs lists, the <#67130#><#38614#>vector<#38614#><#67130#> primitive creates vectors. Since programming with lists usually means programming with the selectors <#67131#><#38615#>first<#38615#><#67131#> and <#67132#><#38616#>rest<#38616#><#67132#>, programming with vectors must mean programming with <#67133#><#38617#>vector-ref<#38617#><#67133#>. Unlike <#67134#><#38618#>first<#38618#><#67134#> and <#67135#><#38619#>rest<#38619#><#67135#>, however, <#67136#><#38620#>vector-ref<#38620#><#67136#> requires manipulating the vector and an index into a vector. This suggests that programming with vectors really means thinking about indices, which are natural numbers. Let's look at some simple examples to confirm this abstract judgement. Here is the first one:
<#71551#>;; <#67137#><#38625#>vector-sum-for-3<#38625#> <#38626#>:<#38626#> <#38627#>(vector<#38627#> <#38628#>number<#38628#> <#38629#>number<#38629#> <#38630#>number)<#38630#> <#38631#><#38631#><#38632#>-;SPMgt;<#38632#><#38633#><#38633#> <#38634#>number<#38634#><#67137#><#71551#>
<#38635#>(d<#38635#><#38636#>efine<#38636#> <#38637#>(vector-sum-for-3<#38637#> <#38638#>v)<#38638#> 
  <#38639#>(+<#38639#> <#38640#>(vector-ref<#38640#> <#38641#>v<#38641#> <#38642#>0)<#38642#> 
     <#38643#>(vector-ref<#38643#> <#38644#>v<#38644#> <#38645#>1)<#38645#> 
     <#38646#>(vector-ref<#38646#> <#38647#>v<#38647#> <#38648#>2)))<#38648#> 
The function <#67138#><#38652#>vector-sum-for-3<#38652#><#67138#> consumes vectors of three numbers and produces their sum. It uses <#67139#><#38653#>vector-ref<#38653#><#67139#> to extract the three numbers and adds them up. What varies in the three selector expressions is the index; the vector remains the same. Consider a second, more interesting example: <#67140#><#38654#>vector-sum<#38654#><#67140#>, a generalization of <#67141#><#38655#>vector-sum-for-3<#38655#><#67141#>. It consumes an arbitrarily large vector of numbers and produces the sum of the numbers:
<#71552#>;; <#67142#><#38660#>vector-sum<#38660#> <#38661#>:<#38661#> <#38662#>(vectorof<#38662#> <#38663#>number)<#38663#> <#38664#><#38664#><#38665#>-;SPMgt;<#38665#><#38666#><#38666#> <#38667#>number<#38667#><#67142#><#71552#>
<#71553#>;; to sum up the numbers in <#67143#><#38668#>v<#38668#><#67143#><#71553#> 
<#38669#>(define<#38669#> <#38670#>(vector-sum<#38670#> <#38671#>v)<#38671#> <#38672#>...)<#38672#> 
Here are some examples:
  <#38680#>(vector-sum<#38680#> <#38681#>(vector<#38681#> <#38682#>-1<#38682#> <#38683#>3/4<#38683#> <#38684#>1/4))<#38684#>
<#38685#>=<#38685#> <#38686#>0<#38686#> 
  <#38687#>(vector-sum<#38687#> <#38688#>(vector<#38688#> <#38689#>.1<#38689#> <#38690#>.1<#38690#> <#38691#>.1<#38691#> <#38692#>.1<#38692#> <#38693#>.1<#38693#> <#38694#>.1<#38694#> <#38695#>.1<#38695#> <#38696#>.1<#38696#> <#38697#>.1<#38697#> <#38698#>.1))<#38698#> 
<#38699#>=<#38699#> <#38700#>1<#38700#> 
  <#38701#>(vector-sum<#38701#> <#38702#>(vector))<#38702#> 
<#38703#>=<#38703#> <#38704#>0<#38704#> 
The last example suggests that we want a reasonable answer even if the vector is empty. As with <#67144#><#38708#>empty<#38708#><#67144#>, we use <#67145#><#38709#>0<#38709#><#67145#> as the answer in this case. The problem is that the one natural number associated with <#67146#><#38710#>v<#38710#><#67146#>, its length, is not an argument of <#67147#><#38711#>vector-sum<#38711#><#67147#>. The length of <#67148#><#38712#>v<#38712#><#67148#> is of course just an indication of how many items in <#67149#><#38713#>v<#38713#><#67149#> are to be processed, which in turn refers to legal indices of <#67150#><#38714#>v<#38714#><#67150#>. This reasoning forces us to develop an auxiliary function that consumes the vector and a natural number:
<#71554#>;; <#67151#><#38719#>vector-sum-aux<#38719#> <#38720#>:<#38720#> <#38721#>(vectorof<#38721#> <#38722#>number)<#38722#> <#38723#>N<#38723#> <#38724#><#38724#><#38725#>-;SPMgt;<#38725#><#38726#><#38726#> <#38727#>number<#38727#><#67151#><#71554#>
<#71555#>;; to sum up the numbers in <#67152#><#38728#>v<#38728#><#67152#> relative to <#67153#><#38729#>i<#38729#><#67153#> <#71555#> 
<#38730#>(define<#38730#> <#38731#>(vector-sum-aux<#38731#> <#38732#>v<#38732#> <#38733#>i)<#38733#> <#38734#>...)<#38734#> 
The natural choice for the initial value of <#67154#><#38738#>i<#38738#><#67154#> is the length of <#67155#><#38739#>v<#38739#><#67155#>, which suggests the following completion of <#67156#><#38740#>vector-sum<#38740#><#67156#>:
<#38745#>(d<#38745#><#38746#>efine<#38746#> <#38747#>(vector-sum<#38747#> <#38748#>v)<#38748#> 
  <#38749#>(vector-sum-aux<#38749#> <#38750#>v<#38750#> <#38751#>(vector-length<#38751#> <#38752#>v)))<#38752#> 
Based on this definition, we can also adapt the examples for <#67157#><#38756#>vector-sum<#38756#><#67157#> to <#67158#><#38757#>vector-sum-aux<#38757#><#67158#>:
  <#38762#>(vector-sum-aux<#38762#> <#38763#>(vector<#38763#> <#38764#>-1<#38764#> <#38765#>3/4<#38765#> <#38766#>1/4)<#38766#> <#38767#>3)<#38767#>
<#38768#>=<#38768#> <#38769#>0<#38769#> 
  <#38770#>(vector-sum-aux<#38770#> <#38771#>(vector<#38771#> <#38772#>.1<#38772#> <#38773#>.1<#38773#> <#38774#>.1<#38774#> <#38775#>.1<#38775#> <#38776#>.1<#38776#> <#38777#>.1<#38777#> <#38778#>.1<#38778#> <#38779#>.1<#38779#> <#38780#>.1<#38780#> <#38781#>.1)<#38781#> <#38782#>10)<#38782#> 
<#38783#>=<#38783#> <#38784#>1<#38784#> 
  <#38785#>(vector-sum-aux<#38785#> <#38786#>(vector)<#38786#> <#38787#>0)<#38787#> 
<#38788#>=<#38788#> <#38789#>0<#38789#> 
Unfortunately, this doesn't clarify the role of the second argument. To do that, we need to proceed to the next stage of the design process: the template development. When we develop templates for functions of two arguments, we must first decide which of the arguments must be processed, that is, which of the two will vary in the course of a computation. The <#67159#><#38793#>vector-sum-for-3<#38793#><#67159#> example suggests that it is the second argument in this case. Because this argument belongs to the class of natural numbers, we follow the design recipe for those:
<#38798#>(d<#38798#><#38799#>efine<#38799#> <#38800#>(vector-sum-aux<#38800#> <#38801#>v<#38801#> <#38802#>i)<#38802#> 
  <#38803#>(c<#38803#><#38804#>ond<#38804#> 
    <#38805#>[<#38805#><#38806#>(zero?<#38806#> <#38807#>i)<#38807#> <#38808#>...]<#38808#> 
    <#38809#>[<#38809#><#38810#>else<#38810#> <#38811#>...<#38811#> <#38812#>(vector-sum-aux<#38812#> <#38813#>v<#38813#> <#38814#>(sub1<#38814#> <#38815#>i))<#38815#> <#38816#>...]<#38816#><#38817#>))<#38817#> 
Although we considered <#67160#><#38821#>i<#38821#><#67160#> to be the length of the vector initially, the template suggests that we should consider it the number of items of <#67161#><#38822#>v<#38822#><#67161#> that <#67162#><#38823#>vector-sum-aux<#38823#><#67162#> must consider and thus as an index into <#67163#><#38824#>v<#38824#><#67163#>. The elaboration of <#67164#><#38825#>i<#38825#><#67164#>'s use naturally leads to a better purpose statement for <#67165#><#38826#>vector-sum-aux<#38826#><#67165#>:
<#71556#>;; <#67166#><#38831#>vector-sum-aux<#38831#> <#38832#>:<#38832#> <#38833#>(vectorof<#38833#> <#38834#>number)<#38834#> <#38835#>N<#38835#> <#38836#><#38836#><#38837#>-;SPMgt;<#38837#><#38838#><#38838#> <#38839#>number<#38839#><#67166#><#71556#>
<#71557#>;; to sum up the numbers in <#67167#><#38840#>v<#38840#><#67167#> with index in [<#67168#><#38841#>0<#38841#><#67168#>, <#67169#><#38842#>i<#38842#><#67169#>)<#71557#> 
<#38843#>(d<#38843#><#38844#>efine<#38844#> <#38845#>(vector-sum-aux<#38845#> <#38846#>v<#38846#> <#38847#>i)<#38847#> 
  <#38848#>(c<#38848#><#38849#>ond<#38849#> 
    <#38850#>[<#38850#><#38851#>(zero?<#38851#> <#38852#>i)<#38852#> <#38853#>...]<#38853#> 
    <#38854#>[<#38854#><#38855#>else<#38855#> <#38856#>...<#38856#> <#38857#>(vector-sum-aux<#38857#> <#38858#>v<#38858#> <#38859#>(sub1<#38859#> <#38860#>i))<#38860#> <#38861#>...]<#38861#><#38862#>))<#38862#> 
Excluding <#67170#><#38866#>i<#38866#><#67170#> is natural because it is initially <#67171#><#38867#>(vector-length<#38867#>\ <#38868#>v)<#38868#><#67171#> and thus not an index.
<#71558#>;; <#67172#><#38873#>vector-sum<#38873#> <#38874#>:<#38874#> <#38875#>(vectorof<#38875#> <#38876#>number)<#38876#> <#38877#><#38877#><#38878#>-;SPMgt;<#38878#><#38879#><#38879#> <#38880#>number<#38880#><#67172#><#71558#>
<#71559#>;; to compute the sum of the numbers in <#67173#><#38881#>v<#38881#><#67173#><#71559#> 
<#38882#>(d<#38882#><#38883#>efine<#38883#> <#38884#>(vector-sum<#38884#> <#38885#>v)<#38885#> 
  <#38886#>(vector-sum-aux<#38886#> <#38887#>(vector-length<#38887#> <#38888#>v)<#38888#> <#38889#>v))<#38889#> 
<#71560#>;; <#67174#><#38897#>vector-sum-aux<#38897#> <#38898#>:<#38898#> <#38899#>(vectorof<#38899#> <#38900#>number)<#38900#> <#38901#>N<#38901#> <#38902#><#38902#><#38903#>-;SPMgt;<#38903#><#38904#><#38904#> <#38905#>number<#38905#><#67174#><#71560#>
<#71561#>;; to sum the numbers in <#67175#><#38906#>v<#38906#><#67175#> with index in [<#67176#><#38907#>0<#38907#><#67176#>, <#67177#><#38908#>i<#38908#><#67177#>)<#71561#> 
<#38909#>(d<#38909#><#38910#>efine<#38910#> <#38911#>(vector-sum-aux<#38911#> <#38912#>v<#38912#> <#38913#>i)<#38913#> 
  <#38914#>(c<#38914#><#38915#>ond<#38915#> 
    <#38916#>[<#38916#><#38917#>(zero?<#38917#> <#38918#>i)<#38918#> <#38919#>0]<#38919#> 
    <#38920#>[<#38920#><#38921#>else<#38921#> <#38922#>(+<#38922#> <#38923#>(vector-ref<#38923#> <#38924#>v<#38924#> <#38925#>(sub1<#38925#> <#38926#>i))<#38926#> 
             <#38927#>(vector-sum-aux<#38927#> <#38928#>v<#38928#> <#38929#>(sub1<#38929#> <#38930#>i)))]<#38930#><#38931#>))<#38931#> 
<#38935#>Figure: Summing up the numbers in a vector (version 1)<#38935#>
<#71562#>;; <#67178#><#38941#>lr-vector-sum<#38941#> <#38942#>:<#38942#> <#38943#>(vectorof<#38943#> <#38944#>number)<#38944#> <#38945#><#38945#><#38946#>-;SPMgt;<#38946#><#38947#><#38947#> <#38948#>number<#38948#><#67178#><#71562#>
<#71563#>;; to sum up the numbers in <#67179#><#38949#>v<#38949#><#67179#><#71563#> 
<#38950#>(d<#38950#><#38951#>efine<#38951#> <#38952#>(lr-vector-sum<#38952#> <#38953#>v)<#38953#> 
  <#38954#>(vector-sum-aux<#38954#> <#38955#>v<#38955#> <#38956#>0))<#38956#> 
<#71564#>;; <#67180#><#38957#>vector-sum<#38957#> <#38958#>:<#38958#> <#38959#>(vectorof<#38959#> <#38960#>number)<#38960#> <#38961#><#38961#><#38962#>-;SPMgt;<#38962#><#38963#><#38963#> <#38964#>number<#38964#><#67180#><#71564#> 
<#71565#>;; to sum up the numbers in <#67181#><#38965#>v<#38965#><#67181#> with index in [<#67182#><#38966#>i<#38966#><#67182#>, <#67183#><#38967#>(vector-length<#38967#> <#38968#>v)<#38968#><#67183#>)<#71565#> 
<#38969#>(d<#38969#><#38970#>efine<#38970#> <#38971#>(vector-sum-aux<#38971#> <#38972#>v<#38972#> <#38973#>i)<#38973#> 
  <#38974#>(c<#38974#><#38975#>ond<#38975#> 
    <#38976#>[<#38976#><#38977#>(=<#38977#> <#38978#>i<#38978#> <#38979#>(vector-length<#38979#> <#38980#>v))<#38980#> <#38981#>0]<#38981#> 
    <#38982#>[<#38982#><#38983#>else<#38983#> <#38984#>(+<#38984#> <#38985#>(vector-ref<#38985#> <#38986#>v<#38986#> <#38987#>i)<#38987#> <#38988#>(vector-sum-aux<#38988#> <#38989#>v<#38989#> <#38990#>(add1<#38990#> <#38991#>i)))]<#38991#><#38992#>))<#38992#> 
<#38996#>Figure: Summing up the numbers in a vector (version 2)<#38996#>
To transform the template into a complete function definition, we consider each clause of the <#67184#><#38998#>cond<#38998#><#67184#>:
  1. If <#67185#><#39000#>i<#39000#><#67185#> is <#67186#><#39001#>0<#39001#><#67186#>, there are no further items to be considered because there are no vector fields between <#67187#><#39002#>0<#39002#><#67187#> and <#67188#><#39003#>i<#39003#><#67188#> with <#67189#><#39004#>i<#39004#><#67189#> excluded. Therefore the result is <#67190#><#39005#>0<#39005#><#67190#>.
  2. Otherwise, <#67191#><#39006#>(vector-sum-aux<#39006#>\ <#39007#>v<#39007#>\ <#39008#>(sub1<#39008#>\ <#39009#>i))<#39009#><#67191#> computes the sum of the numbers in <#67192#><#39010#>v<#39010#><#67192#> between <#67193#><#39011#>0<#39011#><#67193#> and <#67194#><#39012#>(sub1<#39012#>\ <#39013#>i)<#39013#><#67194#> [exclusive]. This leaves out the vector field with index <#67195#><#39014#>(sub1<#39014#><#39015#> <#39015#>\ <#39016#>i)<#39016#><#67195#>, which according to the purpose statement must be included. By adding <#67196#><#39017#>(vector-ref<#39017#>\ <#39018#>v<#39018#>\ <#39019#>(sub1<#39019#>\ <#39020#>i))<#39020#><#67196#>, we get the desired result:
    <#39025#>(+<#39025#> <#39026#>(vector-ref<#39026#> <#39027#>v<#39027#> <#39028#>(sub1<#39028#> <#39029#>i))<#39029#> <#39030#>(vector-sum-aux<#39030#> <#39031#>v<#39031#> <#39032#>(sub1<#39032#> <#39033#>i)))<#39033#>
    
See figure~#figvectorsum#39038> for the complete program. If we were to evaluate one of the examples for <#67197#><#39039#>vector-sum-aux<#39039#><#67197#> by hand, we would see that it extracts the numbers from the vector in a right to left order as <#67198#><#39040#>i<#39040#><#67198#> decreases to <#67199#><#39041#>0<#39041#><#67199#>. A natural question is whether we can invert this order. In other words: is there a function that extract the numbers in a left to right order? The answer is to develop a function that processes the class of natural numbers below <#67200#><#39042#>(vector-length<#39042#>\ <#39043#>v)<#39043#><#67200#> and to start at the first feasible index: <#67201#><#39044#>0<#39044#><#67201#>. Developing this function is just another instance of the design recipe for variants of natural numbers from section~#secnatnumalt#39045>. The new function definition is shown in figure~#figvectorsum2#39046>. The new auxiliary function now consumes <#67202#><#39047#>0<#39047#><#67202#> and counts up to <#67203#><#39048#>(vector-length<#39048#>\ <#39049#>v)<#39049#><#67203#>. A hand-evaluation of
<#39054#>(lr-vector-sum<#39054#> <#39055#>(vector<#39055#> <#39056#>0<#39056#> <#39057#>1<#39057#> <#39058#>2<#39058#> <#39059#>3))<#39059#>
shows that <#67204#><#39063#>vector-sum-aux<#39063#><#67204#> indeed extracts the items from <#67205#><#39064#>v<#39064#><#67205#> from left to right. The definition of <#67206#><#39065#>lr-vector-sum<#39065#><#67206#> shows why we need to study alternative definitions of classes of natural numbers. Sometimes it is necessary to count down to <#67207#><#39066#>0<#39066#><#67207#>. But at other times it is equally useful, and natural, to count from <#67208#><#39067#>0<#39067#><#67208#> up to some other number. The two functions also show how important it is to reason about intervals. The auxiliary vector-processing functions process intervals of the given vector. A good purpose statement specifies the exact interval that the function works on. Indeed, once we understand the exact interval specification, formulating the full function is relatively straightforward. We will see the importance of this point when we return to the study of vector-processing functions in the last section.
<#39070#>Exercise 29.3.4<#39070#> Evaluate <#67209#><#39072#>(vector-sum-aux<#39072#>\ <#39073#>(vector<#39073#>\ <#39074#>-1<#39074#>\ <#39075#>3/4<#39075#>\ <#39076#>1/4)<#39076#>\ <#39077#>3)<#39077#><#67209#> by hand. Show the major steps only. Check the evaluation with DrScheme's stepper. In what order does the function add up the numbers of the vector? Use a <#67210#><#39078#>local<#39078#>-expression<#67210#> to define a single function <#67211#><#39079#>vector-sum<#39079#><#67211#>. Then remove the vector argument from the inner function definition. Why can we do that?~ external Solution<#67212#><#67212#> <#39085#>Exercise 29.3.5<#39085#> Evaluate <#67213#><#39087#>(lr-vector-sum<#39087#>\ <#39088#>(vector<#39088#>\ <#39089#>-1<#39089#>\ <#39090#>3/4<#39090#>\ <#39091#>1/4))<#39091#><#67213#> by hand. Show the major steps only. Check the evaluation with DrScheme's stepper. In what order does the function add up the numbers of the vector? Use a <#67214#><#39092#>local<#39092#>-expression<#67214#> to define a single function <#67215#><#39093#>lr-vector-sum<#39093#><#67215#>. Then remove those arguments from the inner function definition that remain the same during an evaluation. Also introduce definitions for those expressions that always evaluate to the same value during the evaluation. Why is this useful?~ external Solution<#67216#><#67216#> <#39099#>Exercise 29.3.6<#39099#> The list-based analogue of <#67217#><#39101#>vector-sum<#39101#><#67217#> is <#67218#><#39102#>list-sum<#39102#><#67218#>:
<#71566#>;; <#67219#><#39107#>list-sum<#39107#> <#39108#>:<#39108#> <#39109#>(listof<#39109#> <#39110#>number)<#39110#> <#39111#><#39111#><#39112#>-;SPMgt;<#39112#><#39113#><#39113#> <#39114#>number<#39114#><#67219#> <#71566#>
<#71567#>;; to compute the sum of the numbers on <#67220#><#39115#>alon<#39115#><#67220#><#71567#> 
<#39116#>(d<#39116#><#39117#>efine<#39117#> <#39118#>(list-sum<#39118#> <#39119#>alon)<#39119#> 
  <#39120#>(list-sum-aux<#39120#> <#39121#>alon<#39121#> <#39122#>(length<#39122#> <#39123#>alon)))<#39123#> 
<#71568#>;; <#67221#><#39124#>list-sum-aux<#39124#> <#39125#>:<#39125#> <#39126#>N<#39126#> <#39127#>(listof<#39127#> <#39128#>number)<#39128#> <#39129#><#39129#><#39130#>-;SPMgt;<#39130#><#39131#><#39131#> <#39132#>number<#39132#><#67221#> <#71568#> 
<#71569#>;; to compute the sum of the first <#67222#><#39133#>L<#39133#><#67222#> numbers on <#67223#><#39134#>alon<#39134#><#67223#><#71569#> 
<#39135#>(d<#39135#><#39136#>efine<#39136#> <#39137#>(list-sum-aux<#39137#> <#39138#>L<#39138#> <#39139#>alon)<#39139#> 
  <#39140#>(c<#39140#><#39141#>ond<#39141#> 
    <#39142#>[<#39142#><#39143#>(zero?<#39143#> <#39144#>L)<#39144#> <#39145#>0]<#39145#> 
    <#39146#>[<#39146#><#39147#>else<#39147#> <#39148#>(+<#39148#> <#39149#>(list-ref<#39149#> <#39150#>alon<#39150#> <#39151#>(sub1<#39151#> <#39152#>L))<#39152#> <#39153#>(list-sum-aux<#39153#> <#39154#>(sub1<#39154#> <#39155#>L)<#39155#> <#39156#>alon))]<#39156#><#39157#>))<#39157#> 
Instead of using the structural definition of the list, the developer of this program used the size of the list---a natural number---as the guiding element in the design process. The resulting definition uses Scheme's <#67224#><#39161#>list-ref<#39161#><#67224#> function to access each item on the list. Looking up an item in a list with <#67225#><#39162#>list-ref<#39162#><#67225#> is an O(N) operation for lists of <#39163#>N<#39163#> items. Determine the abstract running time of <#67226#><#39164#>sum<#39164#><#67226#> (from section~#seclistsmore#39165>), <#67227#><#39166#>vector-sum-aux<#39166#><#67227#> and <#67228#><#39167#>list-sum-aux<#39167#><#67228#>. What does this suggest about program development?~ external Solution<#67229#><#67229#> <#39173#>Exercise 29.3.7<#39173#> Develop the function <#67230#><#39175#>norm<#39175#><#67230#>, which consumes a vector of numbers and produces the square root of the square of its sum. Another name for <#67231#><#39176#>norm<#39176#><#67231#> is <#67232#><#39177#>distance-to-0<#39177#><#67232#>, because the result is the distance of a vector to the origin, when we interpret the vector as a point.~ external Solution<#67233#><#67233#> <#39183#>Exercise 29.3.8<#39183#> Develop the function <#67234#><#39185#>vector-contains-doll?<#39185#><#67234#>. It consumes a vector of symbols and determines whether the vector contains the symbol <#67235#><#39186#>'<#39186#><#39187#>doll<#39187#><#67235#>. If so, it produces the index of <#67236#><#39188#>'<#39188#><#39189#>doll<#39189#><#67236#>'s field; otherwise, it produces <#67237#><#39190#>false<#39190#><#67237#>. Determine the abstract running time of <#67238#><#39191#>vector-contains-doll?<#39191#><#67238#> and compare with that of <#67239#><#39192#>contains-doll?<#39192#><#67239#>, which we discussed in the preceding subsection. Now discuss the following problem. Suppose we are to represent a collection of symbols. The only interesting problem concerning the collection is to determine whether it contains some given symbol. Which data representation is preferable for the collection: lists or vectors? Why?~ external Solution<#67240#><#67240#> <#39198#>Exercise 29.3.9<#39198#> Develop the function <#67241#><#39200#>binary-contains?<#39200#><#67241#>. It consumes a sorted vector of numbers and a key, which is also a number. The goal is to determine the index of the key, if it occurs in the vector, or <#67242#><#39201#>false<#39201#><#67242#>. Use the binary-search algorithm from section~#secbinarysearch#39202>. Determine the abstract running time of <#67243#><#39203#>binary-contains?<#39203#><#67243#> and compare with that of <#67244#><#39204#>contains?<#39204#><#67244#>, the function that searches for a key in a vector in the linear fashion of <#67245#><#39205#>vector-contains-doll?<#39205#><#67245#>. Suppose we are to represent a collection of numbers. The only interesting problem concerning the collection is to determine whether it contains some given number. Which data representation is preferable for the collection: lists or vectors? Why?~ external Solution<#67246#><#67246#> <#39211#>Exercise 29.3.10<#39211#> Develop the function <#67247#><#39213#>vector-count<#39213#><#67247#>. It consumes a vector <#67248#><#39214#>v<#39214#><#67248#> of symbols and a symbol <#67249#><#39215#>s<#39215#><#67249#>. Its result is the number of <#67250#><#39216#>s<#39216#><#67250#> that occur in <#67251#><#39217#>v<#39217#><#67251#>. Determine the abstract running time of <#67252#><#39218#>vector-count<#39218#><#67252#> and compare with that of <#67253#><#39219#>count<#39219#><#67253#>, which counts how many times <#67254#><#39220#>s<#39220#><#67254#> occurs in a list of symbols. Suppose we are to represent a collection of symbols. The only interesting problem concerning the collection is to determine how many times it contains some given symbol. Which data representation is preferable for the collection: lists or vectors? Why? What do exercises~#exvectorfind#39221>, #exvectorbinaryfind#39222>, and this exercise suggest?~ external Solution<#67255#><#67255#>
While accessing the items of a vector is one kind of programming problem, constructing vectors is an entirely different problem. When we know the number of items in a vector, we can construct it using <#67256#><#39230#>vector<#39230#><#67256#>. When we we wish to write programs, however, that work on a large class of vectors independent of their size, we need <#67257#><#39231#>build-vector<#39231#><#67257#>. Consider the following simple example. Suppose we represent the velocity of an object with a vector. For example, <#67258#><#39232#>(vector<#39232#>\ <#39233#>1<#39233#>\ <#39234#>2)<#39234#><#67258#> represents the veloicity of an object on a plane that moves <#67259#><#39235#>1<#39235#><#67259#> unit to the right and <#67260#><#39236#>2<#39236#><#67260#> down in each time unit. For comparison, <#67261#><#39237#>(vector<#39237#>\ <#39238#>-1<#39238#>\ <#39239#>2<#39239#><#39240#> <#39240#><#39241#>1)<#39241#><#67261#> is the veloicity of an object in space; it moves <#67262#><#39242#>-6<#39242#><#67262#> units in the x-direction in 6 time units, <#67263#><#39243#>12<#39243#><#67263#> units in the y-direction in 6 time units, and <#67264#><#39244#>6<#39244#><#67264#> units in the z-direction in 6 time units. We call <#67265#><#39245#>(vector<#39245#>\ <#39246#>-6<#39246#><#39247#> <#39247#><#39248#>12<#39248#>\ <#39249#>6)<#39249#><#67265#> the <#39250#>displacement<#39250#> of the object in 6 time units. Let's develop a function that computes the displacement for an object with some velocity <#67266#><#39251#>v<#39251#><#67266#> in <#67267#><#39252#>t<#39252#><#67267#> time units:
<#71570#>;; <#67268#><#39257#>displacement<#39257#> <#39258#>:<#39258#> <#39259#>(vectorof<#39259#> <#39260#>number)<#39260#> <#39261#>number<#39261#> <#39262#><#39262#><#39263#>-;SPMgt;<#39263#><#39264#><#39264#> <#39265#>(vectorof<#39265#> <#39266#>number)<#39266#><#67268#><#71570#>
<#71571#>;; to compute the displacement of <#67269#><#39267#>v<#39267#><#67269#> and <#67270#><#39268#>t<#39268#><#67270#><#71571#> 
<#39269#>(define<#39269#> <#39270#>(displacement<#39270#> <#39271#>v<#39271#> <#39272#>t)<#39272#> <#39273#>...)<#39273#> 
Computing the displacement is straightforward for some examples:
  <#39281#>(displacement<#39281#> <#39282#>(vector<#39282#> <#39283#>1<#39283#> <#39284#>2)<#39284#> <#39285#>3)<#39285#> 
<#39286#>=<#39286#> <#39287#>(vector<#39287#> <#39288#>3<#39288#> <#39289#>6)<#39289#> 
  <#39290#>(displacement<#39290#> <#39291#>(vector<#39291#> <#39292#>-1<#39292#> <#39293#>2<#39293#> <#39294#>1)<#39294#> <#39295#>6)<#39295#> 
<#39296#>=<#39296#> <#39297#>(vector<#39297#> <#39298#>-6<#39298#> <#39299#>12<#39299#> <#39300#>6)<#39300#> 
  <#39301#>(displacement<#39301#> <#39302#>(vector<#39302#> <#39303#>-1<#39303#> <#39304#>-2)<#39304#> <#39305#>2)<#39305#> 
<#39306#>=<#39306#> <#39307#>(vector<#39307#> <#39308#>-2<#39308#> <#39309#>-4)<#39309#> 
We just multiply each component of the object with the number, which yields a new vector. The examples' meaning for our programming problem is that <#67271#><#39313#>displacement<#39313#><#67271#> must construct a vector of the same how-many as <#67272#><#39314#>v<#39314#><#67272#> and must use the items in <#67273#><#39315#>v<#39315#><#67273#> to compute those of the new vectors. Here is how we build a vector of the same how-many as some given vector <#67274#><#39316#>v<#39316#><#67274#>:
<#39321#>(build-vector<#39321#> <#39322#>(vector-length<#39322#> <#39323#>v)<#39323#> <#39324#>...)<#39324#>
Now we need to replace ...\ with a function that computes the <#67275#><#39328#>0<#39328#><#67275#>-th, <#67276#><#39329#>1<#39329#><#67276#>-st, and so on items of the new vector:
<#71572#>;; <#67277#><#39334#>new-item<#39334#> <#39335#>:<#39335#> <#39336#>N<#39336#> <#39337#><#39337#><#39338#>-;SPMgt;<#39338#><#39339#><#39339#> <#39340#>number<#39340#><#67277#><#71572#>
<#71573#>;; to compute the contents of the new vector at the <#67278#><#39341#>i<#39341#><#67278#>-th position<#71573#> 
<#39342#>(define<#39342#> <#39343#>(new-item<#39343#> <#39344#>index)<#39344#> <#39345#>...)<#39345#> 
Following our discussion, we multiply <#67279#><#39349#>(vector-ref<#39349#>\ <#39350#>v<#39350#>\ <#39351#>i)<#39351#><#67279#> with <#67280#><#39352#>t<#39352#><#67280#> and that's all. Take a look at the complete definition:
<#71574#>;; <#67281#><#39357#>displacement<#39357#> <#39358#>:<#39358#> <#39359#>(vectorof<#39359#> <#39360#>number)<#39360#> <#39361#>number<#39361#> <#39362#><#39362#><#39363#>-;SPMgt;<#39363#><#39364#><#39364#> <#39365#>(vectorof<#39365#> <#39366#>number)<#39366#><#67281#><#71574#>
<#71575#>;; to compute the displacement of <#67282#><#39367#>v<#39367#><#67282#> and <#67283#><#39368#>t<#39368#><#67283#><#71575#> 
<#39369#>(d<#39369#><#39370#>efine<#39370#> <#39371#>(displacement<#39371#> <#39372#>v<#39372#> <#39373#>t)<#39373#> 
  <#39374#>(l<#39374#><#39375#>ocal<#39375#> <#39376#>((define<#39376#> <#39377#>(new-item<#39377#> <#39378#>i)<#39378#> <#39379#>(*<#39379#> <#39380#>(vector-ref<#39380#> <#39381#>v<#39381#> <#39382#>i)<#39382#> <#39383#>t)))<#39383#> 
    <#39384#>(build-vector<#39384#> <#39385#>(vector-length<#39385#> <#39386#>v)<#39386#> <#39387#>new-item)))<#39387#> 
The locally defined function is not recursive. We can thus replace it with a plain <#67284#><#39391#>lambda<#39391#>-expression<#67284#>:
<#71576#>;; <#67285#><#39396#>displacement<#39396#> <#39397#>:<#39397#> <#39398#>(vectorof<#39398#> <#39399#>number)<#39399#> <#39400#>number<#39400#> <#39401#><#39401#><#39402#>-;SPMgt;<#39402#><#39403#><#39403#> <#39404#>(vectorof<#39404#> <#39405#>number)<#39405#><#67285#><#71576#>
<#71577#>;; to compute the displacement of <#67286#><#39406#>v<#39406#><#67286#> and <#67287#><#39407#>t<#39407#><#67287#><#71577#> 
<#39408#>(d<#39408#><#39409#>efine<#39409#> <#39410#>(displacement<#39410#> <#39411#>v<#39411#> <#39412#>t)<#39412#> 
  <#39413#>(build-vector<#39413#> <#39414#>(vector-length<#39414#> <#39415#>v)<#39415#> <#39416#>(lambda<#39416#> <#39417#>(i)<#39417#> <#39418#>(*<#39418#> <#39419#>(vector-ref<#39419#> <#39420#>v<#39420#> <#39421#>i)<#39421#> <#39422#>t))))<#39422#> 
Mathematicians call this function <#39426#>scalar product<#39426#>. They have also studied many other operations on vectors, and in Scheme we can develop those in a natural manner.
<#39429#>Exercise 29.3.11<#39429#> Develop the function <#67288#><#39431#>id-vector<#39431#><#67288#>, which consumes a natural number and produces a vector of that many <#67289#><#39432#>1<#39432#><#67289#>'s.~ external Solution<#67290#><#67290#> <#39438#>Exercise 29.3.12<#39438#> Develop the functions <#67291#><#39440#>vector+<#39440#><#67291#> and <#67292#><#39441#>vector<#39441#>-<#67292#>, which compute the pointwise sum and differences of two vectors. That is, each consumes two vectors and produces a vector by manipulating corresponding programs. Assume the given vectors are of the same how-many. Also develop the functions <#67293#><#39442#>checked-vector+<#39442#><#67293#> and <#67294#><#39443#>checked-vector-<#39443#><#67294#>.~ external Solution<#67295#><#67295#> <#39449#>Exercise 29.3.13<#39449#> Develop the function <#67296#><#39451#>distance<#39451#><#67296#>, which consumes two vectors and computes their distance. Think of the distance of two vectors as the length of the line between them.~ external Solution<#67297#><#67297#> <#39457#>Exercise 29.3.14<#39457#> Develop a vector representation for chess boards of size #tex2html_wrap_inline73958# for n in <#67298#><#39459#>N<#39459#><#67298#>. Then develop the following two functions on chess boards:
<#71578#>;; <#67299#><#39464#>build-board<#39464#> <#39465#>:<#39465#> <#39466#>N<#39466#> <#39467#>(<#39467#><#39468#>N<#39468#> <#39469#>N<#39469#> <#39470#><#39470#><#39471#>-;SPMgt;<#39471#><#39472#><#39472#> <#39473#>boolean)<#39473#> <#39474#><#39474#><#39475#>-;SPMgt;<#39475#><#39476#><#39476#> <#39477#>board<#39477#><#67299#><#71578#>
<#71579#>;; to create a board of size <#67300#><#39478#>n<#39478#><#67300#> x <#67301#><#39479#>n<#39479#><#67301#>, <#71579#> 
<#71580#>;; fill each position with indices <#67302#><#39480#>i<#39480#><#67302#> and <#67303#><#39481#>j<#39481#><#67303#> with <#67304#><#39482#>(f<#39482#> <#39483#>i<#39483#> <#39484#>j)<#39484#><#67304#><#71580#> 
<#39485#>(define<#39485#> <#39486#>(build-board<#39486#> <#39487#>n<#39487#> <#39488#>f)<#39488#> <#39489#>...)<#39489#> 
<#71581#>;; <#67305#><#39490#>board-ref<#39490#> <#39491#>:<#39491#> <#39492#>board<#39492#> <#39493#>N<#39493#> <#39494#>N<#39494#> <#39495#><#39495#><#39496#>-;SPMgt;<#39496#><#39497#><#39497#> <#39498#>boolean<#39498#><#67305#><#71581#> 
<#71582#>;; to access a position with indices <#67306#><#39499#>i<#39499#><#67306#>, <#67307#><#39500#>j<#39500#><#67307#> on <#67308#><#39501#>a-board<#39501#><#67308#><#71582#> 
<#39502#>(define<#39502#> <#39503#>(board-ref<#39503#> <#39504#>a-board<#39504#> <#39505#>i<#39505#> <#39506#>j)<#39506#> <#39507#>...)<#39507#> 
Can we now run the program of section~#secqueens#39511> using vectors instead of lists? Inspect the solution of exercises~#exqueen2#39512> and~#exqueen#39513>.~ external Solution<#67309#><#67309#> <#39519#>Exercise 29.3.15<#39519#> A matrix is a chess board of numbers. Use the chess-board representation of exercise~#exvectorchess#39521> to represent the matrix

#displaymath73962#

Using <#67310#><#39525#>build-board<#39525#><#67310#>, develop the function <#67311#><#39526#>transpose<#39526#><#67311#>, which creates a mirror image of the matrix along its diagonal from the upper-left corner to the lower-right one. For example, the given matrix turns into

#displaymath73964#

More generally, the item at (i,j) becomes the item at (j,i).~ external Solution<#67312#><#67312#>