Generator/Exponential: Difference between revisions
Content added Content deleted
m (drop plural) |
(→{{header|Tcl}}: Add Ruby.) |
||
Line 180: | Line 180: | ||
'''Sample output''' |
'''Sample output''' |
||
<pre>[529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089]</pre> |
<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}}== |
=={{header|Tcl}}== |