Services & Resources / Wolfram Forums
-----
 /
MathGroup Archive
1996
*January
*February
*March
*April
*May
*June
*July
*August
*September
*October
*November
*December
*Archive Index
*Ask about this page
*Print this page
*Give us feedback
*Sign up for the Wolfram Insider

MathGroup Archive 1996

[Date Index] [Thread Index] [Author Index]

Search the Archive

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


  • Prev by Date: Re: FindMinimum Termination Criteria?
  • Next by Date: Need program: simplify Boolean functions
  • Previous by thread: Re: functional code
  • Next by thread: Re: functional code