Implement NOT, AND and OR for booleans
def not(b)
if b
false
else
true
end
end
def and(a, b)
if a
if b
true
else
false
end
else
false
end
end
def or(a, b)
if a
true
else
if b
true
else
false
end
end
endImplement IS_LESS_OR_EQUAL and IS_EQUAL for natural numbers
def less_or_equal?(m, n) (m - n).zero? # 0 is the smallest number end def equal?(m, n) m <= n && n <= m end
Implement broken, cheating FACTORIAL for natural numbers
def factorial(n)
if n.zero?
1
else
n * factorial(n - 1)
end
endImplement DIV for natural numbers
def div(m, n)
if n <= m
div(m - n, n) + 1
else
0
end
endImplement MOD for natural numbers
def mod(m, n)
if n <= m
mod(m - n, n)
else
m
end
enddef range(m, n)
if m <= n
range(m + 1, n).unshift(m)
else
[]
end
enddef sum(l)
if l.empty?
0
else
l.first + sum(l[1..-1])
end
enddef product(l)
if l.empty?
1
else
l.first * product(l[1..-1])
end
endExtract INJECT from SUM and PRODUCT
def inject(l, x, &block)
if l.empty?
x
else
inject(l[1..-1], block.call(x, l.first), &block)
end
enddef concat(k, l)
if k.empty?
l
else
concat(k[1..-1], l).unshift(k.first)
end
enddef push(l, x) l.concat([].unshift(x)) end
def reverse(l)
if l.empty?
[]
else
reverse(l[1..-1]).push(l.first)
end
endExtract FOLD from CONCAT and REVERSE
def fold(l, x, &block)
if l.empty?
x
else
block.call(fold(l[1..-1], x, &block), l.first)
end
endImplement INCREMENT_ALL for lists
def increment_all(k)
fold(k, []) { |l, n| l.unshift(n + 1) }
endImplement DOUBLE_ALL for lists
def double_all(k)
fold(k, []) { |l, n| l.unshift(n * 2) }
endExtract MAP from INCREMENT_ALL and DOUBLE_ALL
def map(k, &block)
fold(k, []) { |l, x| l.unshift(block.call(x)) }
endImplement TO_DIGITS for natural numbers
def to_digits(n) (n <= 9 ? [] : to_digits(n / 10)).push(n % 10) end
def fizzbuzz(m)
(1..m).map { |n|
if (n % 15).zero?
'FizzBuzz'
elsif (n % 3).zero?
'Fizz'
elsif (n % 5).zero?
'Buzz'
else
n.to_s
end
}
endFix specs to work with Ruby 1.9.3+
The ability to refer to constants in an included module was actually a bug in Ruby 1.9.2, so the specs were failing on later versions where this bug has been fixed. The solution is to define the example blocks inside the module itself, since that's the only place where the unqualified constants should be visible. rspec/rspec-core#506 http://bugs.ruby-lang.org/issues/5657 https://twitter.com/dchelimsky/status/185335729738616833