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] ====