• Source
    1. # -*- coding: utf-8 -*-
    2. # q1010_answer_1.rb
    3.  
    4. # 工夫した点・苦労した点・感想等(ご自由にお書きください):
    5. # ・メインとなる iter_a は each メソッドでループを回し、iter_b は Enumerator 化して next(および peek)メソッドを利用するようにしました。
    6. # ・next メソッドが返す値と、返した後で内部で保持している値(=その後に peek メソッドが返す値)が異なるので、呼ぶ順番に苦労しました。
    7.  
    8. # iter_a に存在し、iter_b に出てこない要素(整数)を列挙するメソッド
    9. def enum_diff iter_a, iter_b
    10. return to_enum :enum_diff, iter_a, iter_b unless block_given?
    11. enum_b = iter_b.to_enum
    12. enum_b_terminated = false
    13. iter_a.each do |a|
    14. if enum_b_terminated
    15. yield a
    16. else
    17. begin
    18. b = enum_b.peek
    19. while b < a
    20. enum_b.next
    21. b = enum_b.peek
    22. end
    23. yield a if a < b
    24. rescue StopIteration
    25. yield a
    26. enum_b_terminated = true
    27. end
    28. end
    29. end
    30. end
    31.  
    32. # ※これ以降は変更しないこと。
    33. if $0 == __FILE__
    34. require 'test/unit'
    35. require 'prime'
    36.  
    37. def primes
    38. Prime.to_enum
    39. end
    40.  
    41. def nats
    42. (1...Float::INFINITY)
    43. end
    44.  
    45. def fib
    46. return to_enum :fib unless block_given?
    47. a, b = 0, 1
    48. loop do
    49. yield b
    50. a, b = b, a + b
    51. end
    52. end
    53.  
    54. class AnswerQ2Test < Test::Unit::TestCase
    55. def test_fib
    56. expected = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
    57. result = enum_diff(fib, []).take(10)
    58. assert_equal(expected, result)
    59. end
    60.  
    61. def test_nats_without_fib
    62. expected = [4, 6, 7, 9, 10, 11, 12, 14, 15, 16]
    63. result = enum_diff(nats, fib).take(10)
    64. assert_equal(expected, result)
    65. end
    66.  
    67. def test_fib_without_primes
    68. expected = [1, 1, 8, 21, 34, 55, 144, 377, 610, 987, 2584, 4181, 6765, 10946, 17711, 46368]
    69. result = enum_diff(fib, primes).take_while{|n| n < 50000}
    70. assert_equal(expected, result)
    71. end
    72.  
    73. def test_fib_reflect
    74. # 3以上20以下の整数を乱択
    75. k = rand(18) + 3
    76. expected = fib.take(k)
    77. result = enum_diff(fib, enum_diff(nats, fib)).take(k)
    78. assert_equal(expected, result)
    79. end
    80. end
    81. end