Project Euler 19, 20, 21, 22, 23, 24, 25 (Ruby)
The next pack of Project Euler solutions.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
# https://projecteuler.net/index.php?section=problems&id=19 # count, which sundays are the first of the month from 1901..2000 class << SundayCounter = Module.new # same as module SundayCounter; class << self START_YEAR = 1900 END_YEAR = 2000 def leap_year?(y) y % 400 == 0 or ( y % 4 == 0 and y % 100 != 0 ) end def month_length_of(m) [31, @february, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][m] end def set_february(year) @february = 28 + ( leap_year?(year) ? 1 : 0 ) end def count sundays = 0 day = 0 month = 0 count_activated = false year = START_YEAR set_february( year ) while year <= END_YEAR sundays += 1 if day == 6 && count_activated day = (day + 7) % month_length_of(month) if day < 7 # new month reached month = (month + 1) % 12 if month.zero? # new year reached year += 1 set_february( year ) count_activated = true # don't count the first year end end end sundays end end puts SundayCounter.count
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
# https://projecteuler.net/index.php?section=problems&id=20 # find the sum of the digits in the number 100 puts (1..100). # get all numbers from 1 to 100 inject(:*). # multiply them to_s.chars. # get characters inject(0){ |sum, cur| # transform to_i and sum them up sum + cur.to_i } # There are so many more ways to get the factorial ;) # (1..100).inject(:*) # (1..100).inject(0){|acc, cur| acc * cur} # (1..100).inject(&:*) # [*1..100].reduce(:*) # 1.upto(100).reduce(:*) # 100 * 100.times.inject(:*) # eval [*1..100]*'*' # f=proc{|x| x<1?1:f[x-1]}; f[100] # f=->(x){if x<1 then 1 else f[x-1] end}; f.call 100 # [recursive method] # [while loop] # ...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
# https://projecteuler.net/index.php?section=problems&id=21 # evaluate the sum of all the "amicable" numbers under 10000 require 'mathn' class Integer def dsum return 1 if self < 2 pd = prime_division.flat_map{ |n, p| [n]*p } # get all prime divisors ([1] + (1...pd.size).flat_map{ |e| # get all possible prime divisor combinations pd.combination(e).map{ |f| f.reduce(:*) } }).uniq.reduce(:+) # sum up end end res = 10_000.times.inject{ |sum, cur| other = cur.dsum (cur != other && other.dsum == cur) ? sum + cur : sum } puts res
1 2 3 4 5 6 7 8 9 10 11
# https://projecteuler.net/index.php?section=problems&id=22 # sum of the 'scores' of all words of the file get_score = proc{ |word, position| (position + 1) * # position begins with 0 word[1..-2]. # do not use "" bytes.map{|e|e-64}. # - "A".ord + 1 inject(:+) # sum } puts File.read( 'names.txt' ).split(',').sort.map.with_index( &get_score ).inject(:+)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
# https://projecteuler.net/index.php?section=problems&id=23 # all numbers under 28123 that cannot be written as "abundant" number require 'mathn' require 'set' MAX = 28123 class Integer def dsum # calculate divisor sum return 1 if self < 2 pd = prime_division.flat_map{ |n,p| [n]*p } # get all prime divisors Set[ 1, *(1...pd.size).flat_map{ |e| # get all possible prime divisor combinations pd.combination(e).map{ |f| f.reduce(:*) } }].reduce(:+) # sum up end end can_be_written = Set.new cannot_be_written = (1..MAX).to_set abundants = (1..MAX).select{ |n| n.dsum > n } abundants[0..MAX/2].each.with_index{ |x,i| abundants[i..-1].each{ |y| break if MAX < a = x + y can_be_written << a } } puts (cannot_be_written - can_be_written).reduce(:+)
1 2 3 4 5
# https://projecteuler.net/index.php?section=problems&id=24 # what is the millionth lexicographic permutation of the digits 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9? # this is the "I don't care about performance an let Ruby manage it"-approach puts [*0..9].permutation.to_a[ 1_000_000 - 1 ].join # yeah! they are sorted automatically
1 2 3 4 5 6 7 8 9 10 11 12
# https://projecteuler.net/index.php?section=problems&id=25 # fibonacci again ;) MAX = 10**999 # the next number has 1000 digits fib = [1,1] # the first two digits are given i = 0 while fib[-1] < MAX fib << fib[i] + fib[i+=1] end puts fib.size
Level 1 (25 solutions) reached ;)