main
 1require "spec_helper"
 2
 3describe "problem nine" do
 4  # A Pythagorean triplet is a set of three natural numbers, a < b < c, for which, a^2 + b^2 = c^2
 5  # For example, 3^2 + 4^2 = 9 + 16 = 25 = 5^2.
 6
 7  # There exists exactly one Pythagorean triplet for which a + b + c = 1000.
 8  # Find the product abc.
 9
10  # a < b < c
11  # c^2 = a^2 + b^2
12  class PythagoreanTriplet
13    include Enumerable
14    attr_reader :max
15
16    def initialize(max = 1_000)
17      @max = max
18    end
19
20    def each(&block)
21      triplets.each(&block)
22    end
23
24    private
25
26    def triplets
27      Enumerator.new do |yielder|
28        (2..max).each do |m|
29          (1...m).each do |n|
30            # https://en.wikipedia.org/wiki/Pythagorean_triple#Proof_of_Euclid.27s_formula
31            a, b, c = m*m - n*n, 2*m*n, m*m + n*n
32            yielder.yield([a, b, c])
33          end
34        end
35      end
36    end
37  end
38
39  subject { PythagoreanTriplet.new }
40
41  it "returns the triplet for 25" do
42    expect(subject.first).to eql([3, 4, 5])
43
44    result = subject.find do |triplet|
45      (triplet.last * triplet.last) == 25
46    end
47    expect(result).to eql([3, 4, 5])
48    expect(subject).to include([3, 4, 5])
49    expect(subject).to include([5, 12, 13])
50  end
51
52  it "returns the triplet for 1000" do
53    result = subject.find do |triplet|
54      (triplet[0] + triplet[1] + triplet[2]) == 1_000
55    end
56    expect(result).to eql([375, 200, 425])
57    puts 375*200*425
58  end
59end