Generator/Exponential: Difference between revisions
(→{{header|Tcl}}: Tart up) |
(→{{header|Python}}: Newly created..) |
||
Line 5: | Line 5: | ||
'''Task:''' Write a generator (or generators), in the most natural way in your language, that produces the numbers that are squares (<math>n^2</math>) but not cubes (<math>m^3</math>) and use that to print the first 21st to 30th members of that sequence. |
'''Task:''' Write a generator (or generators), in the most natural way in your language, that produces the numbers that are squares (<math>n^2</math>) but not cubes (<math>m^3</math>) and use that to print the first 21st to 30th members of that sequence. |
||
=={{header|Python}}== |
|||
In Python, any function that contains a yield statement becomes a generator. The standard libraries itertools module provides the following functions used in the solution: [http://docs.python.org/library/itertools.html#itertools.count count], that will count up from zero; and [http://docs.python.org/library/itertools.html#itertools.islice islice], which will take a slice from an iterator/generator. |
|||
<lang python>from itertools import islice, count |
|||
def powers(m): |
|||
for n in count(): |
|||
yield n ** m |
|||
def filtered(s1, s2): |
|||
n1, n2 = s1.__next__, s2.__next__ |
|||
v, f = n1(), n2() |
|||
while True: |
|||
if v > f: |
|||
f = n2() |
|||
continue |
|||
elif v < f: |
|||
yield v |
|||
v = n1() |
|||
squares, cubes = powers(2), powers(3) |
|||
f = filtered(squares, cubes) |
|||
print(list(islice(f, 20, 30)))</lang> |
|||
'''Sample output''' |
|||
<pre>[529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089]</pre> |
|||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
Revision as of 18:14, 22 November 2010
A generator is an executable entity (like a function or procedure) that contains code that yields a sequence of values, one at a time, so that each time you call the generator, the next value in the sequence is provided. Generators are often built on top of coroutines or objects so that the internal state of the object is handled “naturally”. Generators are often used in situations where a sequence is potentially infinite, and where it is possible to construct the next value of the sequence with only minimal state.
See also:
Task: Write a generator (or generators), in the most natural way in your language, that produces the numbers that are squares () but not cubes () and use that to print the first 21st to 30th members of that sequence.
Python
In Python, any function that contains a yield statement becomes a generator. The standard libraries itertools module provides the following functions used in the solution: count, that will count up from zero; and islice, which will take a slice from an iterator/generator.
<lang python>from itertools import islice, count
def powers(m):
for n in count(): yield n ** m
def filtered(s1, s2):
n1, n2 = s1.__next__, s2.__next__ v, f = n1(), n2() while True: if v > f: f = n2() continue elif v < f: yield v v = n1()
squares, cubes = powers(2), powers(3) f = filtered(squares, cubes) print(list(islice(f, 20, 30)))</lang>
Sample output
[529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089]
Tcl
Tcl implements generators in terms of coroutines. If these generators were terminating, they would finish by doing return -code break
so as to terminate the calling loop context that is doing the extraction of the values from the generator.
<lang tcl>package require Tcl 8.6
proc powers m {
yield for {set n 0} true {incr n} {
yield [expr {$n ** $m}]
}
} coroutine squares powers 2 coroutine cubes powers 3 coroutine filtered apply {{s1 s2} {
yield set f [$s2] set v [$s1] while true {
if {$v > $f} { set f [$s2] continue } elseif {$v < $f} { yield $v } set v [$s1]
}
}} squares cubes
- Drop 20
for {set i 0} {$i<20} {incr i} {filtered}
- Take/print 10
for {} {$i<30} {incr i} {
puts [filtered]
}</lang> Output:
529 576 625 676 784 841 900 961 1024 1089