Generator/Exponential: Difference between revisions

Content added Content deleted
m (drop plural)
Line 180:
'''Sample output'''
<pre>[529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089]</pre>
 
=={{header|Ruby}}==
This task is easier if we cheat and use only one generator!
 
The typical iterator is a Ruby method that has a block parameter, and loops the block for each element. For example, <tt>[11, 22, 33].each { |i| puts "Got #{i}" }</tt> would iterate an Array to print Got 11, Got 22, Got 33. Starting with Ruby 1.8.7, one can use <tt>Object#enum_for</tt> to convert an iterator method to an <tt>Enumerator</tt> object. The <tt>Enumerator#next</tt> method is a generator that runs the iterator method on a separate coroutine.
 
{{works with|Ruby|1.8.7}}
 
<lang ruby>def powers(m)
return enum_for(:powers, m) unless block_given?
 
n = 0
loop { yield n ** m; n += 1 }
end
 
def squares_without_cubes
return enum_for(:squares_without_cubes) unless block_given?
 
cubes = powers(3)
c = cubes.next
powers(2) do |s|
yield s unless c == s
(c = cubes.next) until c > s
end
end
 
# Here .take(30) returns an Array of size 30.
# Something like .take(30_000).drop(20_000) would waste much memory.
p squares_without_cubes.take(30).drop(20)</lang>
 
Output: <tt>[529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089]</tt>
 
There are three iterators: <tt>powers(2)</tt> does squares, <tt>powers(3)</tt> does cubes, and <tt>squares_without_cubes</tt> does its name. These are all infinite loops. The example uses <tt>powers(3)</tt> as a generator. The example also converts <tt>squares_without_cubes</tt> to an <tt>Enumerator</tt> object but never uses this Object as a generator; instead <tt>Enumerable#take</tt> breaks the infinite loop after 30 iterations.
 
=={{header|Tcl}}==