class UlamSequence

Attributes

max[R]
sieve[R]
size[R]

Public Class Methods

new(size) click to toggle source
# File lib/ulam_sequence.rb, line 8
def initialize(size)
  @size = size.to_i
  @max = @size**2
  @sieve = PrimeSieve.new(@max)
end

Public Instance Methods

each() { |x, y, n, prime?(n)| ... } click to toggle source
# File lib/ulam_sequence.rb, line 14
def each
  return to_enum { size } unless block_given?

  points = Enumerator.new do |yielder|
    walk_cycle = [
      lambda { |x, y| [x + 1, y] }, # east
      lambda { |x, y| [x, y - 1] }, # north
      lambda { |x, y| [x - 1, y] }, # west
      lambda { |x, y| [x, y + 1] }, # south
    ].cycle

    x, y = origin
    i = 1
    advance_point = walk_cycle.next

    loop do
      ((i + 1) / 2).times do
        yielder << [x, y]
        x, y = advance_point.call(x, y)
      end

      advance_point = walk_cycle.next
      i += 1
    end
  end

  1.upto(max) do |n|
    x, y = points.next
    yield [x, y, n, sieve.prime?(n)]
  end
end
origin() click to toggle source
# File lib/ulam_sequence.rb, line 46
def origin
  [
    (size - 1) / 2,
    size / 2,
  ]
end