# -*- coding: utf-8 -*-
# 工夫した点・苦労した点・感想等(ご自由にお書きください):
# ・
# ・
# 必要に応じてここに require 文を挿入してもOKです(標準添付ライブラリに限る)。
# 例:require 'set'
# 無限リスト(ストリーム)に対応した直積(Cartesian product)を生成して列挙するメソッド
def infinite_product *iters
return to_enum :infinite_product, *iters unless block_given?
# ここを適切に実装しなおしてテストが通るようにしてください。
# ただし、以下の条件を満たすこと:
# ・後述の別メソッド infinite_product_process を利用すること。
# ・yield 式を必ず利用すること。
iters[0].each do |el|
yield [el]
end
# 桜先生からのワンポイントアドバイス:
# ・今まで学んだことを最大限に活かしてね♪
# ・Good Luck!
end
def infinite_product_process *args
# メソッドの引数は変更しても可↑。ただし「ブロック引数 (&block)」は利用不可。
# メソッドの引数を変更した場合は、下記の ↓ to_enum の引数も適切に変更すること。
return to_enum :infinite_product_process, *args unless block_given?
# ここを適切に実装してテストが通るようにしてください。
# ただし、以下の条件を満たすこと:
# ・yield 式を必ず利用すること。
# 桜先生からのワンポイントアドバイス:
# ・この infinite_product_process メソッドの使い方がポイント。
# 何を受け取って、何を返すか(何を yield の引数に引き渡すのか)。
# あと、何回呼び出すのか、どこから呼び出すのか、とかもね。
# ・あとは、えーと…ぐ、Good Luck!
end
# ※これ以降は変更しないこと。
if $0 == __FILE__
require 'test/unit'
require 'prime'
# 素数を列挙する Enumerator を返すメソッド
def primes
Prime.to_enum
end
# 整数(>0)を列挙する Enumerable(≠Enumerator) を返すメソッド
def nats
(1..1.0/0)
end
# フィボナッチ数列を列挙するメソッド
def fib
return to_enum :fib unless block_given?
a, b = 0, 1
loop do
yield b
a, b = b, a + b
end
end
# infinite_product メソッドのテストクラス
class AnswerQ3Test < Test::Unit::TestCase
# fib のみのテスト
def test_fib_only
expected = [[1], [1], [2], [3], [5], [8], [13], [21], [34], [55]]
result = infinite_product(fib).take(10)
assert_equal(expected, result)
end
# nats と fib の infinite_product のテスト
def test_product_nats_fib
expected = [
[1, 1],
[1, 1], [2, 1],
[1, 2], [2, 1], [3, 1],
[1, 3], [2, 2], [3, 1], [4, 1],
[1, 5], [2, 3], [3, 2], [4, 1], [5, 1],
[1, 8], [2, 5], [3, 3], [4, 2], [5, 1], [6, 1]
]
result = infinite_product(nats, fib).take(21)
assert_equal(expected, result)
end
# primes と nats と fib の infinite_product のテスト
def test_product_primes_nats_fib
expected = [
[2, 1, 1],
[2, 1, 1], [2, 2, 1],
[3, 1, 1],
[2, 1, 2], [2, 2, 1], [2, 3, 1],
[3, 1, 1], [3, 2, 1],
[5, 1, 1],
[2, 1, 3], [2, 2, 2], [2, 3, 1], [2, 4, 1],
[3, 1, 2], [3, 2, 1], [3, 3, 1],
[5, 1, 1], [5, 2, 1],
[7, 1, 1],
[2, 1, 5], [2, 2, 3], [2, 3, 2], [2, 4, 1], [2, 5, 1],
[3, 1, 3], [3, 2, 2], [3, 3, 1], [3, 4, 1],
[5, 1, 2], [5, 2, 1], [5, 3, 1],
[7, 1, 1], [7, 2, 1],
[11, 1, 1]
]
result = infinite_product(primes, nats, fib).take(35)
assert_equal(expected, result)
end
# nats と [1, 2, 3] の infinite_product のテスト
def test_product_nats_1_3
expected = [
[1, 1],
[1, 2], [2, 1],
[1, 3], [2, 2], [3, 1],
[2, 3], [3, 2], [4, 1],
[3, 3], [4, 2], [5, 1],
[4, 3], [5, 2], [6, 1]
]
result = infinite_product(nats, 1..3).take(15)
assert_equal(expected, result)
end
# [1, 2, 3] と nats の infinite_product のテスト
def test_product_1_3_nats
expected = [
[1, 1],
[1, 2], [2, 1],
[1, 3], [2, 2], [3, 1],
[1, 4], [2, 3], [3, 2],
[1, 5], [2, 4], [3, 3],
[1, 6], [2, 5], [3, 4]
]
result = infinite_product(1..3, nats).take(15)
assert_equal(expected, result)
end
end
end