euler 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +24 -0
- data/README.mkdn +5 -0
- data/lib/euler.rb +191 -0
- metadata +56 -0
data/LICENSE
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
Copyright (c) 2008, Mike "Oompa" Skalnik ("THE AUTHOR")
|
2
|
+
All rights reserved. mike.skalnik@gmail.com
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
6
|
+
* Redistributions of source code must retain the above copyright
|
7
|
+
notice, this list of conditions and the following disclaimer.
|
8
|
+
* Redistributions in binary form must reproduce the above copyright
|
9
|
+
notice, this list of conditions and the following disclaimer in the
|
10
|
+
documentation and/or other materials provided with the distribution.
|
11
|
+
* Neither the name of the author nor the
|
12
|
+
names of its contributors may be used to endorse or promote products
|
13
|
+
derived from this software without specific prior written permission.
|
14
|
+
|
15
|
+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY
|
16
|
+
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
17
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
18
|
+
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
19
|
+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
20
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
21
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
22
|
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
23
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
24
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.mkdn
ADDED
data/lib/euler.rb
ADDED
@@ -0,0 +1,191 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
libeuler is a simple library you can simply +require+ in your code.
|
3
|
+
It's goal is to help reduce the repetativeness of some Project
|
4
|
+
Euler problems.
|
5
|
+
|
6
|
+
Author:: Mike Skalnik(mailto:mike.skalnik@gmail.com)
|
7
|
+
Copyright:: 2008, Mike Skalnik; All Rights Reserved
|
8
|
+
License:: See LICENSE file
|
9
|
+
=end
|
10
|
+
module Euler
|
11
|
+
extend self
|
12
|
+
attr_reader :primes, :sieve, :fibonaccis
|
13
|
+
# Several methods for the Integer class.
|
14
|
+
module IntegerMethods
|
15
|
+
# Returns +self+!
|
16
|
+
# 5.factorial # => 120
|
17
|
+
def factorial
|
18
|
+
return 0 if self < 1
|
19
|
+
(2..self).inject(1) { |value, n| value * n }
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns an array of prime factors of +self+
|
23
|
+
# 10.prime_factors # => [2, 5]
|
24
|
+
# 20.prime_factors # => [2, 2, 5]
|
25
|
+
def prime_factors
|
26
|
+
return [self] if self.prime?
|
27
|
+
current, to_factor, factors, max = 2, self, [], 0
|
28
|
+
# current is the value currently being tested
|
29
|
+
# to_factor is the value being factored (slowly moves to a prime value)
|
30
|
+
# factors is the array of prime factors
|
31
|
+
# max is the maximum value of any factor set after the next loop
|
32
|
+
while to_factor % current == 0
|
33
|
+
factors << 2
|
34
|
+
to_factor /= current
|
35
|
+
end
|
36
|
+
current += 1
|
37
|
+
max = Math.sqrt(to_factor).to_i + 1
|
38
|
+
while to_factor <= max
|
39
|
+
if to_factor % current == 0
|
40
|
+
factors << current
|
41
|
+
to_factor /= current
|
42
|
+
else
|
43
|
+
i += 2
|
44
|
+
end
|
45
|
+
end
|
46
|
+
factors << to_factor if to_factor > 1
|
47
|
+
return factors
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns +true+ or +false+ depending on the primality of
|
51
|
+
# +self+
|
52
|
+
# 2.prime? # => true
|
53
|
+
# 4.prime? # => false
|
54
|
+
def prime?
|
55
|
+
if self == 1 then return false
|
56
|
+
elsif self < 4 then return true
|
57
|
+
elsif self % 2 == 0 then return false
|
58
|
+
elsif self < 9 then return true
|
59
|
+
elsif self % 3 == 0 then return false
|
60
|
+
else
|
61
|
+
5.step(Math.sqrt(self).to_i, 2) do |x|
|
62
|
+
return false if self % x == 0
|
63
|
+
end
|
64
|
+
end
|
65
|
+
return true
|
66
|
+
end
|
67
|
+
|
68
|
+
# Compares +self+ and +x+ and returns +true+
|
69
|
+
# if the values are permutations, and +false+
|
70
|
+
# otherwise.
|
71
|
+
# 123.is_permutation?(312) # => true
|
72
|
+
# 312.is_permutation?(281) # => false
|
73
|
+
def is_permutation?(x)
|
74
|
+
return true if self == x # A number is a permutation of itself
|
75
|
+
primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
|
76
|
+
s, s_total, x_total = self, 1, 1
|
77
|
+
|
78
|
+
while s > 0
|
79
|
+
s_total *= primes[s % 10]
|
80
|
+
s /= 10
|
81
|
+
end
|
82
|
+
|
83
|
+
while x > 0
|
84
|
+
x_total *= primes[x % 10]
|
85
|
+
x /= 10
|
86
|
+
end
|
87
|
+
|
88
|
+
return s_total == x_total
|
89
|
+
end
|
90
|
+
|
91
|
+
# Checks to see if +self+ is a pandigital with the range
|
92
|
+
# of x
|
93
|
+
# 0192837465.is_pandigital?(0..9) # => true
|
94
|
+
# 0192837465.is_pandigital?(1..9) # => false
|
95
|
+
def is_pandigital?(x)
|
96
|
+
str = self.to_s
|
97
|
+
x.each do |i|
|
98
|
+
return false unless str.include? i.to_s
|
99
|
+
end
|
100
|
+
return true
|
101
|
+
end
|
102
|
+
|
103
|
+
# Checks to see if +self+ is contained in the fibonacci
|
104
|
+
# sequence.
|
105
|
+
# 1.is_fibonacci? # => true
|
106
|
+
# 4.is_fibonacci? # => true
|
107
|
+
def is_fibonacci?
|
108
|
+
a, b = Math.sqrt((5*(self**2))+4), Math.sqrt((5*(self**2))-4)
|
109
|
+
return true if a.to_i == a or b.to_i == b
|
110
|
+
return false
|
111
|
+
end
|
112
|
+
|
113
|
+
# Returns how many digits +self+ contains.
|
114
|
+
# 10.length # => 2
|
115
|
+
# 4563.length # => 4
|
116
|
+
def length
|
117
|
+
n, count = self, 1
|
118
|
+
while n > 9
|
119
|
+
n /= 10
|
120
|
+
count += 1
|
121
|
+
end
|
122
|
+
return count
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# A basic prime sieve. Sets Euler.sieve to an array of
|
127
|
+
# boolean values that indicate if that index if prime
|
128
|
+
# or not.
|
129
|
+
# Euler.generate_sieve(50)
|
130
|
+
# Euler::sieve[2] # => true
|
131
|
+
# Euler::sieve[4] # => false
|
132
|
+
def generate_sieve(max)
|
133
|
+
@sieve = Array.new(max, false)
|
134
|
+
@sieve[2] = true
|
135
|
+
3.step(max, 2) { |x| @sieve[x] = true}
|
136
|
+
3.step(Math.sqrt(max).to_i, 2) { |i|
|
137
|
+
if @sieve[i]
|
138
|
+
(i**2).step(max, 2*i) { |x| @sieve[x] = false}
|
139
|
+
end
|
140
|
+
}
|
141
|
+
end
|
142
|
+
|
143
|
+
# A more advanced prime sieve. Generates an n amount of
|
144
|
+
# prime values.
|
145
|
+
# Euler.get_primes(50)
|
146
|
+
# Euler::primes[0] # => 2
|
147
|
+
# Euler::primes[2] # => 5
|
148
|
+
def get_primes(n)
|
149
|
+
counter, current_value, @primes = 0, 2, []
|
150
|
+
while counter < n
|
151
|
+
if current_value.prime?
|
152
|
+
@primes << current_value
|
153
|
+
counter += 1
|
154
|
+
end
|
155
|
+
current_value += 1
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# Sets Euler::fibonaccis to an array of integers which are the
|
160
|
+
# Fibonacci sequence of length +n+
|
161
|
+
# Euler.get_fibonaccis(50)
|
162
|
+
# Euler::fibonaccis[0] # => 1
|
163
|
+
# Euler::fibonaccis[4] # => 5
|
164
|
+
def get_fibonaccis(n)
|
165
|
+
@fibonaccis, phi = [], (1+Math.sqrt(5))/2
|
166
|
+
sqrt_5 = Math.sqrt(5)
|
167
|
+
0.upto(n) do |x|
|
168
|
+
@fibonaccis << (phi**(x+1)/sqrt_5).round
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
# Determines if the three values given are a pythagorean triplet
|
173
|
+
# Euler.is_pythagorean_triplet?(3, 4, 5) # => true
|
174
|
+
# Euler.is_pythagorean_triplet?(1, 2, 3) # => false
|
175
|
+
def is_pythagorean_triplet?(a, b, c)
|
176
|
+
a**2 + b**2 == c**2
|
177
|
+
end
|
178
|
+
|
179
|
+
# Given two values of a pythagorean triplet, and nil for the missing
|
180
|
+
# value, it returns the missing value.
|
181
|
+
# Euler.find_missing_pyth_value(nil, 4, 5) # => 3
|
182
|
+
def find_missing_pyth_value(a, b, c)
|
183
|
+
return Math.sqrt(c**2 - b**2) if a.nil?
|
184
|
+
return Math.sqrt(c**2 - a**2) if b.nil?
|
185
|
+
return Math.sqrt(a**2 + b**2) if c.nil?
|
186
|
+
end
|
187
|
+
|
188
|
+
end
|
189
|
+
|
190
|
+
# Just adds Euler::IntegerMethods to the Integer class.
|
191
|
+
Integer.send :include, Euler::IntegerMethods
|
metadata
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: euler
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mike Skalnik
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-08-25 00:00:00 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: A gem that provides a small library to help in the solving of Project Euler problems.
|
17
|
+
email: mike.skalnik@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.mkdn
|
24
|
+
- LICENSE
|
25
|
+
files:
|
26
|
+
- LICENSE
|
27
|
+
- README.mkdn
|
28
|
+
- lib/euler.rb
|
29
|
+
has_rdoc: true
|
30
|
+
homepage: http://theoompa.com
|
31
|
+
post_install_message:
|
32
|
+
rdoc_options: []
|
33
|
+
|
34
|
+
require_paths:
|
35
|
+
- lib
|
36
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: "0"
|
41
|
+
version:
|
42
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
version:
|
48
|
+
requirements: []
|
49
|
+
|
50
|
+
rubyforge_project:
|
51
|
+
rubygems_version: 1.2.0
|
52
|
+
signing_key:
|
53
|
+
specification_version: 2
|
54
|
+
summary: A gem that provides a small library to help in the solving of Project Euler problems.
|
55
|
+
test_files: []
|
56
|
+
|