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