From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,7e81a70d49e1dad0 X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news3.google.com!newshub.sdsu.edu!elnk-nf2-pas!newsfeed.earthlink.net!stamper.news.pas.earthlink.net!stamper.news.atl.earthlink.net!newsread2.news.atl.earthlink.net.POSTED!14bb18d8!not-for-mail Sender: mheaney@MHEANEYX200 Newsgroups: comp.lang.ada Subject: Re: Adding functions to generic package References: <429891d3$1@news.broadpark.no> <4298b608$1@news.broadpark.no> From: Matthew Heaney Message-ID: User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Date: Sun, 29 May 2005 00:56:55 GMT NNTP-Posting-Host: 24.149.57.125 X-Complaints-To: abuse@earthlink.net X-Trace: newsread2.news.atl.earthlink.net 1117328215 24.149.57.125 (Sat, 28 May 2005 17:56:55 PDT) NNTP-Posting-Date: Sat, 28 May 2005 17:56:55 PDT Organization: EarthLink Inc. -- http://www.EarthLink.net Xref: g2news1.google.com comp.lang.ada:11199 Date: 2005-05-29T00:56:55+00:00 List-Id: Preben Randhol writes: > On 2005-05-28, Matthew Heaney wrote: > > What do Randomize and Move do? If you have a tentative implementation, > > then post it (or just mail it to me) and we can figure what is the best > > option for you. > > It should be called Randomize_Container and be equivelent to the > Reverse_Container procedure except that it makes the order of the > elements random. I guess this doesn't seem to make sense for a List, > but I need it for a program that is asking questions from a list. > What Move does it to move element number 2 to number 4. How is that different from Splice? > If you have a list perhaps the user wants to rearrange the order and > drags one element to another place in the list (I'm not talking > GUI-wise). Then I noticed it is a bit cumbersome not to have a move > routine. That's what Splice does. > The procedures are give below: > > ----------------------- > > procedure Move > (Container : in out Container_Type; > From : Natural; > To : Natural) I see that the positions are integer indexes. That means you'll have to search for the iterator designating those nodes. But once you have iterator objects, just pass them to Splice. > if To = Length (Container) then > Append (Container, Element (From_Iterator)); > elsif To > From then > Insert (Container, Succ (To_Iterator), > Element (From_Iterator)); > elsif To < From then > Insert (Container, To_Iterator, > Element (From_Iterator)); > end if; > > Delete (Container, From_Iterator); > end if; Use Splice for this. > end Move; > > ----------------------- > > procedure Randomise_Container > (Container : in out Container_Type; > Loops : Natural) > is > subtype Container_Range is Integer range 1 .. Length (Container); > > package Random_Container is new > Ada.Numerics.Discrete_Random (Container_Range); > use Random_Container; > > Seed : Generator; > Number : Natural; > begin > > Reset (Seed); > for I in 1 .. loops loop > Reset (Seed); > Reset (Seed); > for Current in Container_Range loop > Number := Random (Seed); > Move (Container, From => Current, To => Number); > end loop; > end loop; > > end Randomise_Container; This is going to be way too expensive, since Move is implemented in terms of integer indexes. You definitely want to implement Randomize in terms of iterators, not indexes. I would implement the loop something like: procedure Randomize (C : in out CT) is ... I : IT := First (C); J : IT; N : Natural := Length (C); procedure Get_Random_Iterator is ...; -- see below begin while I /= Last (C) loop -- or: while N > 1 loop Get_Random_Iterator; -- get value of J Splice (C, Before => I, Iterator => J); I := Succ (J); end loop; end Randomize; Get_Random_Iterator returns an iterator (J) in the range [I, Back): procedure Get_Random_Iterator is M : constant Natural := Random (G) mod N; begin J := I; for Index in 1 .. M loop Succ (J); end loop; N := N - 1; end Get_Random_Iterator; The expression Random (G) is a call to the Generator function Random, from an instantiation of Discrete_Random on type Integer. This should perform much better than the algorithm you posted. -Matt