Ask a Question related to Ruby, Design and Development.
-
Harry Ohlsen #1
Re: Possible use for a continuation? [Generating all factors of agiven number]
daz wrote:
Darn! I was hoping to finally get a chance to use one :-).> Continuations might be more-than-required since you
> suggest that when a condition arises, the game is up.
What I was really trying to achieve, though, was to have a generic iterator that invoked a block that was passed to it, passing each factor as it was calculated, but for that block to be able to determine that it didn't want any more values.> catch / throw may be what you need.
>
> N.B. I haven't done the job but just to show that
> throw can be issued from anywhere ...
>
> def gen_value_single(n, r)
> ret_ = []
> 0.upto(r) do |i|
> ret_ << n ** i
> throw :enough if ((false))
> end
> ret_
> end
>
> def gen_values(arr)
> all_done = false
> catch :enough do
> arr.each do |n, r|
> p gen_value_single(n, r)
> #
> ### accumulate stuff
> #
> throw :enough if ((false))
> end
> all_done = true
> end # post-catch
> return all_done
> end
>
> gen_values( [[2,3], [3,2], [5,2], [7,1]] )
>
>
> And, because I don't know your condition,
> I've entered false.
Alternatively, and I felt this would work more cleanly, I'd like a re-entrant generator that could simply be called multiple times, returning the next value each time. That way the caller doesn't need to communicate the fact that no more values are required, it simply wouldn't call the generator any more. This is where I thought a continuation might help.
What I ended up with was this ...
def Primes.each_factor(n, &block)
prime_factors = factors(n)
iterate_over_factors(1, prime_factors, &block)
end
def Primes.iterate_over_factors(start, factors, &block)
first = factors[0]
rest = factors[1 .. -1]
factor = first[0]
exponent = first[1]
x = start
(0 .. exponent).each do |i|
if rest.length == 0
if !block.call(x)
return false
end
else
if !iterate_over_factors(x, rest, &block)
break
end
end
x *= factor
end
end
which can be called like ...
isGenerator = true
Primes.each_factor(phi) do |factor|
exponent = phi / factor
if (i ** exponent).to_i == 1
isGenerator = false
end
isGenerator
end
The only problem with this is that you can't really "return" a value from a block (or, at least, I don't believe so), which makes the last line, which has to "return" true or false, so that the iterator knows whether to continue, isn't quite as obvious as I'd like.
As I say, to me it would be much nicer if I could do something like ...
factors = Primes.factors(phi)
while (f = factors.next())
exponent = phi / factor
if (i ** exponent).to_i == 1
return false
end
end
return true
because there's no need for the block to pass anything back to the generator (since the generator isn't actually passed the block).
Anyway, I have something that works. But, I'd still be interested if someone feels like showing me how to achieve the equivalent generator that's being used in the last code snippet.
Cheers,
Harry O.
Harry Ohlsen Guest
-
RAND() generating same number in rapid sequence
I am using RAND() in rapid sequence, possibly on different connections. I expected to get different numbers from RAND(). I didn't. I get the same... -
Equivalent focal lengths and crop factors...
Haven't read here for a while. Wondered when all this would surface here. Well, it has and it won't go away, so maybe some clarification is in... -
continuation operator
What is the best way to utilize most recent continuation operator \ ? I recently copied Mac director files to PC and they have different... -
Possible use for a continuation? [Generating all factors of a given number]
Harry Ohlsen <harryo@qiqsolutions.com> wrote: Overkill - this should do it: class MultiCounter def initialize(a, b = nil) @max = a @min =... -
PDF viewers capable of high zoom factors
I have a map of the British mainland as a .pdf file. In order to see useful local details on it, I want to be able to zoom in by about 50x. I have... -
Mauricio Fernández #2
Re: Possible use for a continuation? [Generating all factors of a given number]
On Wed, Jul 09, 2003 at 05:40:40PM +0900, Harry Ohlsen wrote:
[url]http://www.rubygarden.org/ruby?RubyFromPython[/url]> Anyway, I have something that works. But, I'd still be interested if
> someone feels like showing me how to achieve the equivalent generator
> that's being used in the last code snippet.
Scroll down to 'Generators'.
--
_ _
| |__ __ _| |_ ___ _ __ ___ __ _ _ __
| '_ \ / _` | __/ __| '_ ` _ \ / _` | '_ \
| |_) | (_| | |_\__ \ | | | | | (_| | | | |
|_.__/ \__,_|\__|___/_| |_| |_|\__,_|_| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com
No, that's wrong too. Now there's a race condition between the rm and
the mv. Hmm, I need more coffee.
-- Guy Maor on Debian Bug#25228
Mauricio Fernández Guest
-
Harry Ohlsen #3
Re: Possible use for a continuation? [Generating all factors of agiven number]
Brian Candler wrote:
That could be good! Thanks for the info.> IIRC, 1.8 has "next <expr>" and "break <expr>" which return a value.
Sorry, that was just a snippet of the overall code, to save people trying to understand all the details. The flag is there for other reasons. It just happens that it's value also tells me whether I can terminate the loop over the generated values.> In the above case, if 'isGenerator = false' terminates the loop, you could
> just write
>
> exponent = phi / factor
> (i ** exponent).to_i != 1 # continue condition
What I was getting at was that I didn't think it yelled out clearly that the last line in the block being just "isGenerator" was passing information back to the iterator, since this isn't something that I've often seen people do (although, that may just be a lack of data on my part).
Harry O.
Harry Ohlsen Guest



Reply With Quote

