home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!ogicse!uwm.edu!ux1.cso.uiuc.edu!news.cso.uiuc.edu!mm-mac22.mse.uiuc.edu!gaylord
- From: gaylord@ux1.cso.uiuc.edu (Richard J. Gaylord)
- Newsgroups: sci.math.symbolic
- Subject: Rootterdam Competition in Mathematica Journal
- Message-ID: <BxtJGM.472@news.cso.uiuc.edu>
- Date: 16 Nov 92 17:05:08 GMT
- Article-I.D.: news.BxtJGM.472
- Sender: usenet@news.cso.uiuc.edu (Net Noise owner)
- Organization: University of Illinois
- Lines: 86
- X-Xxdate: Mon, 16 Nov 92 11:06:44 GMT
- X-Useragent: Nuntius v1.1.1d12
- X-Xxmessage-Id: <A72D314486049B16@mm-mac22.mse.uiuc.edu>
-
- in the latest issue of the Mathematica Journal, the results of the
- programming competition at the Boston and the Rotterdam Mathematica
- meetings were reported.
-
- I've already expressed in this group my (self) righteous indignation over
- the choice for most elegant program in Boston of a pattern-matched
- function over the clearly aesthetically superior as well as faster
- functional program so i'll only discuss the 'split' function program
- from Rotterdam. split takes two lists, the first of which is an arbitrary
- list and the second of which is a list of non-negative integers whose sum
- is the length of the first list.
-
- The function works like this:
-
- split[{a,b,c,d,e,f,g},{2,0,3,1,1}]
- {{a,b},{},{c,d,e},{f},{g}}
-
- clearly, the second list tells you how to 'split up' the first list.
-
- the winner of the contest for elegance was:
-
- splitElegant[lis_,parts_] :=
- Take[lis,#]& /@
- Rest[FoldList[#[[2]]+{1,#2}&,{0,0},parts]]
-
- the winner of the contest for efficiency was:
-
- splitFast[list_,parts_] :=
- Block[{accumulation = FoldList[Plus,0,parts]},
- Inner[Take[list,{#1,#2}]&,
- Drop[accumulation,-1]+1,
- Rest[accumulation],
- List]]
-
- It was reported in the article that splitFast is 50% faster than
- splitElegant. I tested this:
-
- parts = Table[Random[Integer,{0,5}],{500}];
-
- parts/.List->Plus
- 1255
-
- lis = Table[Random[Integer,{1,10}], {parts/.List->Plus}];
-
- Length[lis]
- 1255
-
- Timing[splitElegant[lis,parts];]
- {2.05 Second, Null}
-
- Timing[splitFast[lis,parts];]
- {1.35 Second, Null}
-
- ================
-
- the first point i want to raise is that splitElegant is really not that
- elegant if elegant also means it should be readable.
- [ how long it took you to figure out what the anonymous function #[[2]]
- +{1,#2}& does?]
-
- i have come up with an alternative program which slightly faster than
- splitFast and is more elegant than splitElegant {my dog darwin concurs
- with this judgement and he's incredibly picky about his code} :
-
-
- split[lis_, parts_] :=
- Map[Take[lis, #]&,
- Drop[Thread[List[# + 1, RotateLeft[#]]]& [FoldList[Plus,0,parts]], -1] ]
-
- Timing[split[lis,parts];]
- {1.28333 Second, Null}
-
-
- the nice thing about the split function given here is that it follows a
- prime directive of functional programming:
-
- "never disassemble a list and then reassemble the list".
-
-
- as an aside: in order to increase speed i used Thread[List[a,b]] rather
- than the somewhat slower Transpose[{a,b}] . mathematically oriented
- people may find that using Transpose increases the elegance of the
- program further.
-
- i don't suppose they're accepting any late entrie to theRotterdam
- Confereence contest?
-