On Mon, 12 Mar 2001, Benjamin J. Tilly wrote: > >===== Original Message From Mathieu Bouchard <matju / sympatico.ca> ===== > >On Mon, 12 Mar 2001, Benjamin J. Tilly wrote: > >> >(oh, btw. Ben's version takes over 3 times longer. i'm now testing with > >> >n=10**30 and using >/dev/null) > >> We have a winner. If you want all of the Hamming numbers less > >> than a fixed bound, this appears fastest. > > > >I believe there are faster ways than that, but I don't want to go that > >far... > > Well fastest of the submitted solutions. :-) > > >> Theoretically the sort is k*log(k) where k is the number of > >> elements. Practically if you raise n large enough for that to > >> matter, you will run out of memory on the machine. :-) > > > >the hamming function, where h(1)=1, is very close to > > > >proc{|k| 0.185*6.9893**(k**(1/3.0)) } > > > >which can be used as a reliable approximation for large values of k > >(add 2% for safety) > > Ah, I didn't know that. Well with that fact you should be > able to indeed do well. > I was about to post that Ben was the winner since matju's solution didn't adhere to my initial posting (the n first hamming numbers and not the hamming numbers less than a fixed bound) but the above formula should turn things around. Thanks for all nice solutions, this was fun. My solution is slower than yours but shorter when you've got LazyArray's (It's simple to define them if you build on MetaRuby; they're basically as the ProcAsArray example but allowing a length of Infinity): def hamming_sequence(gens) hs = LazyArray.new([1]) {|i, me| # Having an explicit state is ugly; there's probably a nicer solution unless me.state["inner"] me.state["inner"] = merge(gens.map{|gen| hs.map {|v| gen*v}}) end me.state["inner"][i-1] } end # The n first hamming_sequence([2,3,5])[0...1000] This solution is basically the same as the perl one pointed to by Ben. Expressing it in Ruby makes things a fair amount cleaner though... Regards, Robert