Possible use for a continuation? [Generating all factors of agiven number]

Ask a Question related to Ruby, Design and Development.

  1. #1

    Default Re: Possible use for a continuation? [Generating all factors of agiven number]

    daz wrote:
    > Continuations might be more-than-required since you
    > suggest that when a condition arises, the game is up.
    Darn! I was hoping to finally get a chance to use one :-).
    > 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.
    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.

    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

  2. Similar Questions and Discussions

    1. 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...
    2. 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...
    3. 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...
    4. 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 =...
    5. 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...
  3. #2

    Default 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:
    > 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.
    [url]http://www.rubygarden.org/ruby?RubyFromPython[/url]

    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

  4. #3

    Default Re: Possible use for a continuation? [Generating all factors of agiven number]

    Brian Candler wrote:
    > IIRC, 1.8 has "next <expr>" and "break <expr>" which return a value.
    That could be good! Thanks for the info.
    > In the above case, if 'isGenerator = false' terminates the loop, you could
    > just write
    >
    > exponent = phi / factor
    > (i ** exponent).to_i != 1 # continue condition
    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.

    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

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139