restructuring solutions for spec usage

master
Evan Hemsley 2018-02-24 19:32:39 -08:00
parent eb21d847e1
commit 251fb30d67
22 changed files with 294 additions and 111 deletions

View File

@ -3,11 +3,14 @@
require "big" require "big"
module Euler module Euler
alias NumType = Int32 | Int64 | UInt32 | UInt64 | BigInt extend self
def self.trial_division(n : NumType) alias NumType = Int32 | Int64 | UInt32 | UInt64
factors = [] of NumType
check = ->(p: NumType) { macro trial_division_method(given_type)
def trial_division(n : {{given_type}})
factors = [] of {{given_type}}
check = ->(p: {{given_type}}) {
q, r = n.divmod(p) q, r = n.divmod(p)
while r.zero? while r.zero?
factors << p factors << p
@ -28,9 +31,11 @@ module Euler
factors << n if n > 1 factors << n if n > 1
factors factors
end end
end
def self.prime_factorization(n : NumType) macro prime_factorization_method(given_type)
result = {} of NumType => NumType def prime_factorization(n : {{given_type}})
result = {} of {{given_type}} => Int32
factors = self.trial_division(n) factors = self.trial_division(n)
factors.each do |f| factors.each do |f|
@ -44,16 +49,33 @@ module Euler
result result
end end
def self.palindrome?(x)
x.to_s.reverse == x.to_s
end end
def self.to_digit_list(n : NumType) macro to_digit_list_method(given_type)
def to_digit_list(n : {{given_type}})
n.to_s.chars.map { |d| d.to_i } n.to_s.chars.map { |d| d.to_i }
end end
end
def self.to_big_ints(num_list : Array(NumType)) macro to_big_ints_method(given_type)
def to_big_ints(num_list : Array({{given_type}}))
num_list.map { |n| BigInt.new(n) } num_list.map { |n| BigInt.new(n) }
end end
end end
trial_division_method(NumType)
trial_division_method(BigInt)
prime_factorization_method(NumType)
prime_factorization_method(BigInt)
to_digit_list_method(NumType)
to_digit_list_method(BigInt)
to_big_ints_method(NumType)
to_big_ints_method(BigInt)
def palindrome?(x)
x.to_s.reverse == x.to_s
end
end

View File

@ -1 +1,9 @@
puts (1..999).select { |n| (n % 3 == 0) || (n % 5 == 0) }.sum module Euler
module Problem001
extend self
def solution
(1..999).select { |n| (n % 3 == 0) || (n % 5 == 0) }.sum
end
end
end

View File

@ -1,3 +1,7 @@
module Euler
module Problem002
extend self
def fibonacci_nums_up_to(n) def fibonacci_nums_up_to(n)
result = [1] of Int32 result = [1] of Int32
@ -15,4 +19,8 @@ def fibonacci_nums_up_to(n)
result result
end end
puts fibonacci_nums_up_to(4000000).select{ |n| n.even? }.sum def solution
fibonacci_nums_up_to(4000000).select{ |n| n.even? }.sum
end
end
end

View File

@ -1,3 +1,11 @@
require "./euler" require "./euler"
puts Euler.trial_division(600851475143).max module Euler
module Problem003
extend self
def solution
Euler.trial_division(600851475143).max
end
end
end

View File

@ -1,7 +1,15 @@
require "./euler" require "./euler"
module Euler
module Problem004
extend self
def products_of_three_digit_nums def products_of_three_digit_nums
(100..999).to_a.combinations(2).map { |p| p.product } (100..999).to_a.combinations(2).map { |p| p.product }
end end
puts products_of_three_digit_nums.select { |x| Euler.palindrome?(x) }.max def solution
products_of_three_digit_nums.select { |x| Euler.palindrome?(x) }.max
end
end
end

View File

@ -1,5 +1,9 @@
require "./euler" require "./euler"
module Euler
module Problem005
extend self
def integer_factorization_divisible_by_all_up_to(n) def integer_factorization_divisible_by_all_up_to(n)
result = {} of Euler::NumType => Euler::NumType result = {} of Euler::NumType => Euler::NumType
(2..n).map do |i| (2..n).map do |i|
@ -16,4 +20,8 @@ def factors_to_int(factorization : Hash(Euler::NumType, Euler::NumType))
factorization.map { |prime, exponent| prime ** exponent }.product factorization.map { |prime, exponent| prime ** exponent }.product
end end
puts factors_to_int(integer_factorization_divisible_by_all_up_to(20)) def solution
factors_to_int(integer_factorization_divisible_by_all_up_to(20))
end
end
end

View File

@ -1 +1,9 @@
puts (1..100).sum ** 2 - (1..100).map { |n| n * n }.sum module Euler
module Problem006
extend self
def solution
(1..100).sum ** 2 - (1..100).map { |n| n * n }.sum
end
end
end

View File

@ -1,3 +1,11 @@
require "./euler" require "./prime"
puts Euler.eratosthenes_sieve(1000000)[10000] module Euler
module Problem007
extend self
def solution
Euler::Prime.new.skip(10000).next
end
end
end

View File

@ -1,10 +1,15 @@
require "./euler" require "./euler"
module Euler
module Problem008
extend self
def largest_consecutive_product(n, adjacent) def largest_consecutive_product(n, adjacent)
Euler.to_big_ints(Euler.to_digit_list(n)).each_cons(adjacent).map { |x| x.product }.max Euler.to_big_ints(Euler.to_digit_list(n)).each_cons(adjacent).map { |x| x.product }.max
end end
puts largest_consecutive_product( def solution
largest_consecutive_product(
BigInt.new("73167176531330624919225119674426574742355349194934 BigInt.new("73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843 96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511 85861560789112949495459501737958331952853208805511
@ -25,3 +30,6 @@ BigInt.new("73167176531330624919225119674426574742355349194934
84580156166097919133875499200524063689912560717606 84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725 05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450"), 13) 71636269561882670428252483600823257530420752963450"), 13)
end
end
end

View File

@ -1,5 +1,9 @@
require "./euler" require "./euler"
module Euler
module Problem009
extend self
def generate_pythagorean_triples(upper_bound) def generate_pythagorean_triples(upper_bound)
([] of Array(Euler::NumType)).tap do |triples| ([] of Array(Euler::NumType)).tap do |triples|
(2..upper_bound).each do |a| (2..upper_bound).each do |a|
@ -11,4 +15,8 @@ def generate_pythagorean_triples(upper_bound)
end end
end end
puts generate_pythagorean_triples(500).find([-1]) { |x| x.sum == 1000 }.product def solution
generate_pythagorean_triples(500).find([-1]) { |x| x.sum == 1000 }.product
end
end
end

View File

@ -1,4 +1,12 @@
require "./prime" require "./prime"
module Euler
module Problem010
extend self
def solution
prime = Euler::Prime.new prime = Euler::Prime.new
puts prime.take_while { |x| x < 2000000 }.sum prime.take_while { |x| x < 2000000 }.sum
end
end
end

View File

@ -2,7 +2,8 @@ require "./euler"
module Euler module Euler
class Prime class Prime
include Iterator(NumType) # needs to include BigInt ...
include Iterator(NumType | BigInt)
def initialize() def initialize()
@sieve_size = 16 @sieve_size = 16

View File

@ -0,0 +1,8 @@
require "spec"
require "../euler001"
describe Euler::Problem001 do
it "should return 233168" do
Euler::Problem001.solution.should eq 233168
end
end

View File

@ -0,0 +1,8 @@
require "spec"
require "../euler002"
describe Euler::Problem002 do
it "should return 4613732" do
Euler::Problem002.solution.should eq 4613732
end
end

View File

@ -0,0 +1,8 @@
require "spec"
require "../euler003"
describe Euler::Problem003 do
it "should return 6857" do
Euler::Problem003.solution.should eq 6857
end
end

View File

@ -0,0 +1,8 @@
require "spec"
require "../euler004"
describe Euler::Problem004 do
it "should return 906609" do
Euler::Problem004.solution.should eq 906609
end
end

View File

@ -0,0 +1,8 @@
require "spec"
require "../euler005"
describe Euler::Problem005 do
it "should return 232792560" do
Euler::Problem005.solution.should eq 232792560
end
end

View File

@ -0,0 +1,8 @@
require "spec"
require "../euler006"
describe Euler::Problem006 do
it "should return 25164150" do
Euler::Problem006.solution.should eq 25164150
end
end

View File

@ -0,0 +1,8 @@
require "spec"
require "../euler007"
describe Euler::Problem007 do
it "should return 104743" do
Euler::Problem007.solution.should eq 104743
end
end

View File

@ -0,0 +1,8 @@
require "spec"
require "../euler008"
describe Euler::Problem008 do
it "should return 23514624000" do
Euler::Problem008.solution.should eq 23514624000
end
end

View File

@ -0,0 +1,8 @@
require "spec"
require "../euler009"
describe Euler::Problem009 do
it "should return 31875000" do
Euler::Problem009.solution.should eq 31875000
end
end

View File

@ -0,0 +1,8 @@
require "spec"
require "../euler010"
describe Euler::Problem010 do
it "should return 142913828922" do
Euler::Problem010.solution.should eq 142913828922
end
end