# tardate/sources

### Subversion checkout URL

You can clone with HTTPS or Subversion.

Fetching contributors…

Cannot retrieve contributors at this time

332 lines (294 sloc) 7.663 kb
 # my collection of routines built up while solving problems # at projecteuler.net # By Paul Gallagher gallagher.paul@gmail.com # http://tardate.blogspot.com # free to share and use anyhow, anywhere... # class Integer # @see project euler #15,20,34 def factorial (2..self).inject(1) { |prod, n| prod * n } end # sum of digits in the number, expressed as a decimal # @see project euler #16, 20 def sum_digits self.to_s.split('').inject(0) { |memo, c| memo + c.to_i } end # num of digits in the number, expressed as a decimal # @see project euler #25 def num_digits self.to_s.length end # returns an array of all the base10 digit rotations of the number # @see project euler #35 def rotations self.to_s.rotations.collect { |s| s.to_i } end # tests if all the base10 digits in the number are odd # @see project euler #35 def all_digits_odd? self.to_s.split('').inject(0) { |memo, s| memo + ( s.to_i%2==0 ? 1 : 0 ) } == 0 end # @see project euler #4, 36, 91 def palindrome?(base = 10) case base when 2 sprintf("%0b",self).palindrome? else self.to_s.palindrome? end end # http://en.wikipedia.org/wiki/Prime_factor # @see project euler #12 def prime_factors primes = Array.new d = 2 n = self while n > 1 if n%d==0 primes << d n/=d else d+=1 end end primes end # http://en.wikipedia.org/wiki/Divisor_function # @see project euler #12 def divisor_count primes = self.prime_factors primes.uniq.inject(1) { |memo, p| memo * ( ( primes.find_all {|i| i == p} ).length + 1) } end # # @see project euler #12, 21, 23 def divisors d = Array.new (1..self-1).each { |n| d << n if self % n == 0 } d end # @see project euler # def prime? divisors.length == 1 # this is a brute force check end # prime series up to this limit, using Sieve of Eratosthenes method # http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes # @see project euler #7, 10, 35 def prime_series t = self limit = Math.sqrt(t) a = (2..t).to_a n = 2 while (n < limit) do x = n*2 begin a[x-2]=2 x+=n end until (x > t ) begin n+=1 end until ( a[n-2] != 2 ) end a.uniq! end # @see project euler #23 def perfect? self == divisors.sum end # @see project euler #23 def deficient? self > divisors.sum end # @see project euler #23 def abundant? self < divisors.sum end # http://en.wikipedia.org/wiki/Collatz_conjecture # @see project euler #14 def collatz_series a = Array.new a << n = self while n > 1 if n % 2 == 0 n /= 2 else n = 3*n + 1 end a << n end a end # express integer as an english phrase # @see project euler #17 def speak case when self <20 ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" ][self] when self > 19 && self < 100 a = ["twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"][self / 10 - 2] r = self % 10 if r == 0 a else a + "-" + r.speak end when self > 99 && self < 1000 a = (self / 100).speak + " hundred" r = self % 100 if r == 0 a else a + " and " + r.speak end when self > 999 && self < 10000 a = (self / 1000).speak + " thousand" r = self % 1000 if r == 0 a else a + ( r <100 ? " and " : " " ) + r.speak end else self end end # generates triangle number for this integer # @see project euler #42 def triangle self * ( self + 1 ) / 2 end # calculates integer partitions for given number using array of elements # http://en.wikipedia.org/wiki/Integer_partition # @see project euler #31 def integer_partitions(pArray, p=0) if p==pArray.length-1 1 else self >= 0 ? (self - pArray[p]).integer_partitions(pArray ,p) + self.integer_partitions(pArray,p+1) : 0 end end end class Array # sum elements in the array def sum self.inject(0) { |sum, n| sum + n } end # sum of squares for elements in the array # @see project euler #6 def sum_of_squares self.inject(0) { |sos, n| sos + n**2 } end # @see project euler #17 def square_of_sum ( self.inject(0) { |sum, n| sum + n } ) ** 2 end # index of the smallest item in the array def index_of_smallest value, index = self.first, 0 self.each_with_index {| obj, i | value, index = obj, i if obj 0 num3 = num1 - num2 num1 = [num2,num3].max num2 = [num2,num3].min end t_val = num1 end t_val end # http://utilitymill.com/edit/GCF_and_LCM_Calculator # @see project euler #5 def LCM a=self.remove_factors t_val = a[0] for cnt in 0...a.length-1 num1 = t_val num2 = a[cnt+1] tmp = [num1,num2].GCF t_val = tmp * num1/tmp * num2/tmp end t_val end # brute force method: # http://www.cut-the-knot.org/Curriculum/Arithmetic/LCM.shtml # @see project euler #5 def lcm2 a=self.remove_factors c=a.dup while c.uniq.length>1 index = c.index_of_smallest c[index]+=a[index] end c.first end # returns the kth Lexicographical permutation of the elements in the array # http://en.wikipedia.org/wiki/Permutation#Lexicographical_order_generation # @see project euler #24 def lexicographic_permutation(k) k -= 1 s = self.dup n = s.length n_less_1_factorial = (n - 1).factorial # compute (n - 1)! (1..n-1).each do |j| tempj = (k / n_less_1_factorial) % (n + 1 - j) s[j-1..j+tempj-1]=s[j+tempj-1,1]+s[j-1..j+tempj-2] unless tempj==0 n_less_1_factorial = n_less_1_factorial / (n- j) end s end # returns ordered array of all the lexicographic permutations of the elements in the array # http://en.wikipedia.org/wiki/Permutation#Lexicographical_order_generation # @see project euler #24 def lexicographic_permutations a=Array.new (1..self.length.factorial).each { |i| a << self.lexicographic_permutation(i) } a end end class String # sum of digits in the number # @see project euler #16, 20 def sum_digits self.split('').inject(0) { |memo, c| memo + c.to_i } end # product of digits in the number # @see project euler #8 def product_digits self.split('').inject(1) { |memo, c| memo * c.to_i } end # # @see project euler #4, 36, 91 def palindrome? self==self.reverse end # returns an array of all the character rotations of the string # @see project euler #35 def rotations s = self rots = Array[s] (1..s.length-1).each do |i| s=s[1..s.length-1]+s[0,1] rots << s end rots end end
Something went wrong with that request. Please try again.