In my attempt to learn Ruby out in the open, here’s my solution for Project Euler Problem 43

This is yet another problem where I blatantly avoided all real math. (Maybe that’s why it takes 37 seconds to execute…) I found this problem interesting, pun intended. Not much going on here, but I am starting to dig the shorthand that can be used for simple mapping and reduction. For example, interestings.map(&:to_i).reduce(&:+). I’m also trying to respect the one-line rule when deciding to whether to bookend my blocks with mere braces or do’s and end’s.

As always, any feedback is welcome.

# Euler 43
# http://projecteuler.net/index.php?section=problems&id=43
# The number, 1406357289, is a 0 to 9 pandigital number
# because it is made up of each of the digits 0 to 9 in
# some order, but it also has a rather interesting
# sub-string divisibility property.
#
# Let d1 be the 1st digit, d2 be the 2nd digit, and so on.
# In this way, we note the following:
#
# d2d3d4=406 is divisible by 2
# d3d4d5=063 is divisible by 3
# d4d5d6=635 is divisible by 5
# d5d6d7=357 is divisible by 7
# d6d7d8=572 is divisible by 11
# d7d8d9=728 is divisible by 13
# d8d9d10=289 is divisible by 17
#
# Find the sum of all 0 to 9 pandigital numbers with this property.
timer_start = Time.now

def interesting?(n,p)
  1.upto(7) { |i|
    return false if (n.to_s.slice(i...i+3).to_i % p[i] != 0)
  }
  true
end

#puts interesting?(1406357289, [0,2,3,5,7,11,13,17])

interestings = [0,1,2,3,4,5,6,7,8,9] \
  .permutation(10) \
  .map { |x| x.join } \
  .select { |x| interesting?(x, [0,2,3,5,7,11,13,17])}

#puts interestings
puts interestings.map(&:to_i).reduce(&:+)

puts "Elapsed Time: #{(Time.now - timer_start)*1000} milliseconds"

2 Comments to “Project Euler 43: Ruby”

  1. valbaca says:

    I too am using Project Euler to learn Ruby and must admit that your code has helped me with the ones I just can’t get.

    I really liked your interesting? function and how it uses the Don’t Repeat Yourself methodology. My first attempt at this part had a VERY ugly line (which would look just fine in C).

    I was able to cut down a little of your code. No speed improvements though.

    class String
      def interesting?
        p = [0,2,3,5,7,11,13,17]
        1.upto(7){|i| return false if (self.slice(i...i+3).to_i % p[i] != 0)}
        true
      end
    end
    puts Array(0..9).permutation(10).map(&:join).select(&:interesting?).map(&:to_i).reduce(&:+)
    

    If I ever get ahead of you on the problems I’ll post them on my site. In the meantime I’ll be visiting.

  2. Ben Griswold says:

    @valbaca, Thanks for sharing your solution. Glad I’ve been able to help you out a bit but from the looks of it you’ll be posting your Ruby solutions online soon since you’re only 10 problems away from surpassing me. Keep it up — I’m looking forward to continued learning from you too. Take care and thanks for the comment.

Leave a Reply

You can wrap your code with [ruby][/ruby] or [python][/python] blocks for syntax highlighting and you can use these traditional tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>