Ruby's object-oriented style enforces writing 1..100 before x. Think not of x in 1..100. Think of 1..100 giving x.
There is no elegant way to comprise a list from multiple variables. Pythagorean triplets need three variables, with 1..n giving x, then x..n giving y, then y..n giving z. A less than elegant way is to nest three blocks.
=== Ruby 1.9.2 ===
* The outer <tt>(1..n).flat_map { ... }</tt> concatenates the middle arrays for all x.
=== Ruby 1.8.6 ===
{{works with|Ruby|1.8.6 or later}}
<lang ruby>n = 20
unless Enumerable.method_defined? :flat_map
module Enumerable
def flat_map
inject([]) { |a, x| a.concat yield(x) }
end
end
end
unless Array.method_defined? :keep_if
class Array
def keep_if
delete_if { |x| not yield(x) }
end
end
end
# select Pythagorean triplets
r = ((1..n).flat_map { |x|
(x..n).flat_map { |y|
(y..n).flat_map { |z|
[[x, y, z]].keep_if { x * x + y * y == z * z }}}})
p r # print the array _r_</lang>
This is the exact same code, except that it now defines Enumerable#flat_map and Array#keep_if when those methods are missing. It now works with older versions of Ruby, like 1.8.6.
Illustrating a way to avoid all loops (but no list comprehensions) :
|