Take the last element of the lazy enumerator

I have a function like this:

(0..Float::INFINITY).lazy.take_while {|n|(n**2+ 1*n+41).prime?}.force[-1]

I use this as an optimization exercise. This works fine, but has an O (n) memory order, as it will create the whole array and then take the last element.

I try to get this without building the entire list, hence the lazy enumerator. I can't think of anything other than using a loop while.

(0..Float::INFINITY).lazy.take_while {|n|(n**2+ 1*n+41).prime?}.last.force

Is there a way to do this in space order O (1), and not O (n) with enumerations?

EDIT: lazy is not needed here for this example to work, but I thought it would be more useful to reduce the spatial complexity of the function?

+4
source share
2

:

(0..1.0/0).find {|n| !(n**2+n+41).prime?} - 1

1.0/0 Float::INFINITY. , . , .

:

def do_it
  e = (0..1.0/0).to_enum
  loop do
    n = e.peek
    return e.inspect unless (n**2+n+41).prime?
    e.next
  end
end

do_it 
+2

.

(0..Float::INFINITY).lazy.take_while {|n|(n**2+ 1*n+41).prime?}.inject{|acc,n| n }

, lazy inject .

, , , ruby ​​ . , "" .

ObjectSpace.enum_for(:each_object, Array).each_with_object([]) {|e, acc|
  acc << e if e.size == 40 and e.first == 0
}

:

[[0, 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]]

lazy .

+1

All Articles