Each number specifies the distance between two dots. What we need is the following picture, where each dot is annotated with the distance to the left-most dot:
<#71593#>;; <#67349#><#39600#>relative-2-absolute<#39600#> <#39601#>:<#39601#> <#39602#>(listof<#39602#> <#39603#>number)<#39603#> <#39604#><#39604#><#39605#>-;SPMgt;<#39605#><#39606#><#39606#> <#39607#>(listof<#39607#> <#39608#>number)<#39608#><#67349#><#71593#> <#39609#>;; to convert a list of relative distances to a list of absolute distances<#39609#> <#39610#>;; the first item on the list represents the distance to the origin<#39610#> <#39611#>(d<#39611#><#39612#>efine<#39612#> <#39613#>(relative-2-absolute<#39613#> <#39614#>alon)<#39614#> <#39615#>(c<#39615#><#39616#>ond<#39616#> <#39617#>[<#39617#><#39618#>(empty?<#39618#> <#39619#>alon)<#39619#> <#39620#>empty]<#39620#> <#39621#>[<#39621#><#39622#>else<#39622#> <#39623#>(cons<#39623#> <#39624#>(first<#39624#> <#39625#>alon)<#39625#> <#39626#>(add-to-each<#39626#> <#39627#>(first<#39627#> <#39628#>alon)<#39628#> <#39629#>(relative-2-absolute<#39629#> <#39630#>(rest<#39630#> <#39631#>alon))))]<#39631#><#39632#>))<#39632#> <#71594#>;; <#67350#><#39633#>add-to-each<#39633#> <#39634#>:<#39634#> <#39635#>number<#39635#> <#39636#>(listof<#39636#> <#39637#>number)<#39637#> <#39638#><#39638#><#39639#>-;SPMgt;<#39639#><#39640#><#39640#> <#39641#>(listof<#39641#> <#39642#>number)<#39642#><#67350#><#71594#> <#71595#>;; to add <#67351#><#39643#>n<#39643#><#67351#> to each number on <#67352#><#39644#>alon<#39644#><#67352#><#71595#> <#39645#>(d<#39645#><#39646#>efine<#39646#> <#39647#>(add-to-each<#39647#> <#39648#>n<#39648#> <#39649#>alon)<#39649#> <#39650#>(c<#39650#><#39651#>ond<#39651#> <#39652#>[<#39652#><#39653#>(empty?<#39653#> <#39654#>alon)<#39654#> <#39655#>empty]<#39655#> <#39656#>[<#39656#><#39657#>else<#39657#> <#39658#>(cons<#39658#> <#39659#>(+<#39659#> <#39660#>(first<#39660#> <#39661#>alon)<#39661#> <#39662#>n)<#39662#> <#39663#>(add-to-each<#39663#> <#39664#>n<#39664#> <#39665#>(rest<#39665#> <#39666#>alon)))]<#39666#><#39667#>))<#39667#><#39671#>Figure: Converting relative distances to absolute distances<#39671#>
<#39689#>(define<#39689#> <#39690#>x<#39690#> <#39691#>(relative-2-absolute<#39691#> <#39692#>(list<#39692#> <#39693#>0<#39693#> <#39694#>...<#39694#> <#39695#>N)))<#39695#>As we increase <#67358#><#39699#>N<#39699#><#67358#>, the time needed grows even faster:
Instead of doubling as we go from <#39708#>100<#39708#> to <#39709#>200<#39709#> items, the time
quadruples. This is also the approximate relationship for going from <#39710#>200<#39710#>
to <#39711#>400<#39711#>, <#39712#>300<#39712#> to <#39713#>600<#39713#>, and so on.
<#39716#>Exercise 30.1.1<#39716#>
Solution<#67363#><#67363#>
<#39726#>Exercise 30.1.2<#39726#>
<#39734#>(relative-2-absolute<#39734#> <#39735#>(list<#39735#> <#39736#>0<#39736#> <#39737#>...<#39737#> <#39738#>N))<#39738#>by hand. Start by replacing <#67365#><#39742#>N<#39742#><#67365#> with 1, 2, and 3. How many natural recursions of <#67366#><#39743#>relative-2-absolute<#39743#><#67366#> and <#67367#><#39744#>add-to-each<#39744#><#67367#> are required each time?~
<#39756#>(d<#39756#><#39757#>efine<#39757#> <#39758#>(rel-2-abs<#39758#> <#39759#>alon)<#39759#> <#39760#>(c<#39760#><#39761#>ond<#39761#> <#39762#>[<#39762#><#39763#>(empty?<#39763#> <#39764#>alon)<#39764#> <#39765#>...]<#39765#> <#39766#>[<#39766#><#39767#>else<#39767#> <#39768#>...<#39768#> <#39769#>(first<#39769#> <#39770#>alon)<#39770#> <#39771#>...<#39771#> <#39772#>(rel-2-abs<#39772#> <#39773#>(rest<#39773#> <#39774#>alon))<#39774#> <#39775#>...]<#39775#><#39776#>))<#39776#>Now imagine an ``evaluation'' of <#67369#><#39780#>(rel-2-abs<#39780#>\ <#39781#>(list<#39781#>\ <#39782#>3<#39782#>\ <#39783#>2<#39783#>\ <#39784#>7))<#39784#><#67369#>:
<#39789#>(rel-2-abs<#39789#> <#39790#>(list<#39790#> <#39791#>3<#39791#> <#39792#>2<#39792#> <#39793#>7))<#39793#> <#39794#>=<#39794#> <#39795#>(c<#39795#><#39796#>ons<#39796#> <#39797#>...<#39797#> <#39798#>3<#39798#> <#39799#>...<#39799#> <#39800#>(convert<#39800#> <#39801#>(list<#39801#> <#39802#>2<#39802#> <#39803#>7)))<#39803#> <#39804#>=<#39804#> <#39805#>(c<#39805#><#39806#>ons<#39806#> <#39807#>...<#39807#> <#39808#>3<#39808#> <#39809#>...<#39809#> <#39810#>(c<#39810#><#39811#>ons<#39811#> <#39812#>...<#39812#> <#39813#>2<#39813#> <#39814#>...<#39814#> <#39815#>(convert<#39815#> <#39816#>(list<#39816#> <#39817#>7))))<#39817#> <#39818#>=<#39818#> <#39819#>(c<#39819#><#39820#>ons<#39820#> <#39821#>...<#39821#> <#39822#>3<#39822#> <#39823#>...<#39823#> <#39824#>(c<#39824#><#39825#>ons<#39825#> <#39826#>...<#39826#> <#39827#>2<#39827#> <#39828#>...<#39828#> <#39829#>(c<#39829#><#39830#>ons<#39830#> <#39831#>...<#39831#> <#39832#>7<#39832#> <#39833#>...<#39833#> <#39834#>(convert<#39834#> <#39835#>empty))))<#39835#>The first item of the result list should obviously be <#67370#><#39839#>3<#39839#><#67370#>, and it is easy to construct this list. But, the second one should be <#67371#><#39840#>(+<#39840#>\ <#39841#>3<#39841#><#39842#> <#39842#><#39843#>2)<#39843#><#67371#>, yet the second instance of <#67372#><#39844#>rel-2-abs<#39844#><#67372#> has no way of ``knowing'' that the first item of the <#39845#>original<#39845#> list is <#67373#><#39846#>3<#39846#><#67373#>. The ``knowledge'' is lost. Put differently, the problem is that recursive functions are independent of their context. A function processes the list <#67374#><#39847#>L<#39847#><#67374#> in <#67375#><#39848#>(cons<#39848#>\ <#39849#>N<#39849#><#39850#> <#39850#><#39851#>L)<#39851#><#67375#> in the exact same manner as <#67376#><#39852#>L<#39852#><#67376#> in <#67377#><#39853#>(cons<#39853#>\ <#39854#>K<#39854#>\ <#39855#>L)<#39855#><#67377#>. Indeed, it would also process <#67378#><#39856#>L<#39856#><#67378#> in that manner if it were given <#67379#><#39857#>L<#39857#><#67379#> by itself. While this property makes structurally recursive functions easy to design, it also means that solutions are, on occasion, more complicated than necessary, and this complication may affect the performance of the function. To make up for the loss of ``knowledge'', we equip the function with an additional parameter: <#67380#><#39858#>accu-dist<#39858#><#67380#>. The new parameter represents the accumulated distance, which is the tally that we keep when we convert a list of relative distances to a list of absolute distances. Its initial value must be <#67381#><#39859#>0<#39859#><#67381#>. As the function processes the numbers on the list, it must add them to the tally. Here is the revised definition:
<#39864#>(d<#39864#><#39865#>efine<#39865#> <#39866#>(rel-2-abs<#39866#> <#39867#>alon<#39867#> <#39868#>accu-dist)<#39868#> <#39869#>(c<#39869#><#39870#>ond<#39870#> <#39871#>[<#39871#><#39872#>(empty?<#39872#> <#39873#>alon)<#39873#> <#39874#>empty]<#39874#> <#39875#>[<#39875#><#39876#>else<#39876#> <#39877#>(cons<#39877#> <#39878#>(+<#39878#> <#39879#>(first<#39879#> <#39880#>alon)<#39880#> <#39881#>accu-dist)<#39881#> <#39882#>(rel-2-abs<#39882#> <#39883#>(rest<#39883#> <#39884#>alon)<#39884#> <#39885#>(+<#39885#> <#39886#>(first<#39886#> <#39887#>alon)<#39887#> <#39888#>accu-dist)))]<#39888#><#39889#>))<#39889#>The recursive application consumes the rest of the list and the new absolute distance of the current point to the origin. Although this means that two arguments are changing simultaneously, the change in the second one strictly depends on the first argument. The function is still a plain list-processing procedure. Evaluating our running example with <#67382#><#39893#>rel-2-abs<#39893#><#67382#> shows how much the use of an accumulator simplifies the conversion process:
<#39898#>=<#39898#> <#39899#>(rel-2-abs<#39899#> <#39900#>(list<#39900#> <#39901#>3<#39901#> <#39902#>2<#39902#> <#39903#>7)<#39903#> <#39904#>0)<#39904#> <#39905#>=<#39905#> <#39906#>(cons<#39906#> <#39907#>3<#39907#> <#39908#>(rel-2-abs<#39908#> <#39909#>(list<#39909#> <#39910#>2<#39910#> <#39911#>7)<#39911#> <#39912#>3))<#39912#> <#39913#>=<#39913#> <#39914#>(cons<#39914#> <#39915#>3<#39915#> <#39916#>(cons<#39916#> <#39917#>5<#39917#> <#39918#>(rel-2-abs<#39918#> <#39919#>(list<#39919#> <#39920#>7)<#39920#> <#39921#>5)))<#39921#> <#39922#>=<#39922#> <#39923#>(cons<#39923#> <#39924#>3<#39924#> <#39925#>(cons<#39925#> <#39926#>5<#39926#> <#39927#>(cons<#39927#> <#39928#>12<#39928#> <#39929#>(rel-2-abs<#39929#> <#39930#>empty<#39930#> <#39931#>12))))<#39931#> <#39932#>=<#39932#> <#39933#>(cons<#39933#> <#39934#>3<#39934#> <#39935#>(cons<#39935#> <#39936#>5<#39936#> <#39937#>(cons<#39937#> <#39938#>12<#39938#> <#39939#>empty)))<#39939#>Each item in the list is processed once. When <#67383#><#39943#>rel-2-abs<#39943#><#67383#> reaches the end of the argument list, the result is completely determined and no further work is needed. In general, the function performs on the order of <#39944#>N<#39944#> natural recursion steps for a list with <#39945#>N<#39945#> items. One minor problem with the new definition is that the function consumes two arguments and is thus not equivalent to <#67384#><#39946#>relative-2-absolute<#39946#><#67384#>, a function of one argument. Worse, someone might accidentally misuse <#67385#><#39947#>rel-2-abs<#39947#><#67385#> by applying it to a list of numbers and a number that isn't <#67386#><#39948#>0<#39948#><#67386#>. We can solve both problems with a function definition that contains <#67387#><#39949#>rel-2-abs<#39949#><#67387#> in a <#67388#><#39950#>local<#39950#><#67388#> definition: see figure~#figrelabshuman#39951>
<#71598#>;; <#67391#><#39958#>relative-2-absolute2<#39958#> <#39959#>:<#39959#> <#39960#>(listof<#39960#> <#39961#>number)<#39961#> <#39962#><#39962#><#39963#>-;SPMgt;<#39963#><#39964#><#39964#> <#39965#>(listof<#39965#> <#39966#>number)<#39966#><#67391#><#71598#> <#39967#>;; to convert a list of relative distances to a list of absolute distances<#39967#> <#39968#>;; the first item on the list represents the distance to the origin<#39968#> <#39969#>(d<#39969#><#39970#>efine<#39970#> <#39971#>(relative-2-absolute2<#39971#> <#39972#>alon)<#39972#> <#39973#>(l<#39973#><#39974#>ocal<#39974#> <#39975#>((d<#39975#><#39976#>efine<#39976#> <#39977#>(rel-2-abs<#39977#> <#39978#>alon<#39978#> <#39979#>accu-dist)<#39979#> <#39980#>(c<#39980#><#39981#>ond<#39981#> <#39982#>[<#39982#><#39983#>(empty?<#39983#> <#39984#>alon)<#39984#> <#39985#>empty]<#39985#> <#39986#>[<#39986#><#39987#>else<#39987#> <#39988#>(cons<#39988#> <#39989#>(+<#39989#> <#39990#>(first<#39990#> <#39991#>alon)<#39991#> <#39992#>accu-dist)<#39992#> <#39993#>(rel-2-abs<#39993#> <#39994#>(rest<#39994#> <#39995#>alon)<#39995#> <#39996#>(+<#39996#> <#39997#>(first<#39997#> <#39998#>alon)<#39998#> <#39999#>accu-dist)))]<#39999#><#40000#>)))<#40000#> <#40001#>(rel-2-abs<#40001#> <#40002#>alon<#40002#> <#40003#>0)))<#40003#><#40007#>Figure: Converting relative distances with an accumulator<#40007#>