Re: functional code

*To*: mathgroup at smc.vnet.net*Subject*: [mg4805] Re: functional code*From*: rhall2 at umbc.edu (hall robert)*Date*: Mon, 16 Sep 1996 23:51:26 -0400*Organization*: University of Maryland, Baltimore County*Sender*: owner-wri-mathgroup at wolfram.com

richard gaylord, who's book on programming I'm currently reading, wrote: >i received the following query from someone and thought i'd post the >problem and a solution i've come up with: >query: >Here is my non-functional solution to this problem: >Given a list of numbers row={18,19,1,11,25,12,22,14} >Select the numbers from the list by taking the largest number >from the ends of the list until the list is empty. > >row={18,19,1,11,25,12,22,14}; >p=Length[row]; >result={}; >Do[If[First[row]>=Last[row], >AppendTo[result, First[row]];row=Rest[row], >AppendTo[result,Last[row]];row=Drop[row,-1]], >{p}]; > >result > >{18,19,14,22,12,25,11,1} > >If there a way to do this functionally? > >response: yes, of course it can be done functionally. > >In[30]:= >Nest[ >Function[y, >({Join[y[[1]],{#}] , DeleteCases[y[[2]], #]})&[Max[First[y[[2]]], >Last[y[[2]]]]]], {{}, row}, Length[row]][[1]] > >Out[30]= >{18, 19, 14, 22, 12, 25, 11, 1} Actually, once you have the original block of code, it's easier to turn it into a function by wrapping a module around it. In[18]:= takeLargestFromEnds[row_] := Module[ {result, list = row}, result={}; Do[ If[ First[list]>=Last[list], AppendTo[result, First[list]]; list = Rest[list], AppendTo[result, Last[list]]; list = Drop[list, -1] ], {Length[row]} ]; result ] In[28]:= takeLargestFromEnds[row] Out[28]= {18, 19, 14, 22, 12, 25, 11, 1} There are three major differences between this and Richard's solution: 1. This is not a one-liner; Richard's is. 2. This uses iteration; Richard's solution uses recursion. 3. This algorithm isn't fooled by repeated numbers: Richard's is. Here's a one-liner that uses recursion and isn't fooled by repeated numbers. In[27]:= Apply[ (#1 - #2)&, Partition[ (Plus @@ #)& /@ NestList[ If[First[#] >= Last[#], Rest[#], Drop[#, -1]]&, row, Length[row] ], 2, 1 ], 1 ] Out[27]= {18, 19, 14, 22, 12, 25, 11, 1} Substitute an 18 for the 22 in 'row' and it works fine. -- Bob Hall | "Know thyself? Absurd direction! rhall2 at gl.umbc.edu | Bubbles bear no introspection." -Khushhal Khan Khatak ==== [MESSAGE SEPARATOR] ====