main
1require 'spec_helper'
2require 'prime'
3=begin
4The sequence of triangle numbers is generated by adding the natural numbers. So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. The first ten terms would be:
5
61, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...
7
8Let us list the factors of the first seven triangle numbers:
9
10 1: 1
11 3: 1,3
12 6: 1,2,3,6
1310: 1,2,5,10
1415: 1,3,5,15
1521: 1,3,7,21
1628: 1,2,4,7,14,28
17We can see that 28 is the first triangle number to have over five divisors.
18
19What is the value of the first triangle number to have over five hundred divisors?
20
21help:
22* http://www.wikihow.com/Determine-the-Number-of-Divisors-of-an-Integer
23* https://www.khanacademy.org/math/pre-algebra/factors-multiples/prime_factorization/v/prime-factorization
24=end
25
26class TriangleNumbers
27 include Enumerable
28
29 def each(&block)
30 n = 1
31 loop do
32 block.call(sum_of(n))
33 n += 1
34 end
35 end
36
37 private
38
39 def sum_of(n)
40 n.downto(0).inject(0) { |total, m| total += m }
41 end
42
43end
44
45describe 'problem 12' do
46 describe TriangleNumbers do
47 it 'produces the first 7 triangle numbers' do
48 expect(subject.take(7)).to eql([1, 3, 6, 10, 15, 21, 28])
49 end
50
51 it 'produces the first 10 triangle numbers' do
52 expect(subject.take(10)).to eql([1, 3, 6, 10, 15, 21, 28, 36, 45, 55])
53 end
54 end
55
56 class Divisors
57 def divisors_for(n)
58 1.upto(n).find_all do |x|
59 (n % x).zero?
60 end
61 end
62
63 def number_of_divisors_for(n)
64 prime_factors = n.prime_division
65 powers_plus_one = prime_factors.map do |(prime, exponent)|
66 exponent + 1
67 end
68 powers_plus_one.inject(1) { |total, power| total *= power }
69 end
70 end
71
72 describe Divisors do
73 it 'returns each factor for a number' do
74 {
75 1 => [1],
76 2 => [1, 2],
77 3 => [1,3],
78 4 => [1,2,4],
79 5 => [1, 5],
80 6 => [1,2,3,6],
81 7 => [1, 7],
82 8 => [1, 2, 4, 8],
83 9 => [1, 3, 9],
84 10 => [1,2,5,10],
85 11 => [1, 11],
86 12 => [1, 2, 3, 4, 6, 12],
87 13 => [1, 13],
88 14 => [1, 2, 7, 14],
89 15 => [1,3,5,15],
90 16 => [1, 2, 4, 8, 16],
91 21 => [1,3,7,21],
92 24 => [1, 2, 3, 4, 6, 8, 12, 24],
93 28 => [1, 2, 4, 7, 14, 28],
94 }.each do |key, values|
95 expect(subject.divisors_for(key)).to eql(values)
96 end
97 end
98
99 it 'brute forces the answer' do
100 subject = TriangleNumbers.new
101 divisors = Divisors.new
102 result = subject.find do |n|
103 divisors.number_of_divisors_for(n) >= 500
104 end
105 expect(result).to eql(76576500)
106 end
107 end
108end