HiveBrain v1.2.0
Get Started
← Back to all entries
patternrubyMinor

Project Euler code evaluation - digit fifth powers

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
evaluationfifthprojecteulercodedigitpowers

Problem

This is for Project Euler #30:


Surprisingly there are only three numbers that can be written as the
sum of fourth powers of their digits:


\$1634 = 1^4 + 6^4 + 3^4 + 4^4\$

\$8208 = 8^4 + 2^4 + 0^4 + 8^4\$

\$9474 = 9^4 + 4^4 + 7^4 + 4^4\$


As \$1 = 1^4\$ is not a sum it is not included. The sum of these numbers
is \$1634 + 8208 + 9474 = 19316\$.


Find the sum of all the numbers that can be written as the sum of
fifth powers of their digits.

list = []
2.upto(1_000_000) do |num|
 list << num if num.to_s.split("").map(&:to_i).map { |num| num ** 5 }.inject(:+) == num
end

puts list.inject(:+)


This works, and I am here for three reasons:

  • I use map twice, and this smells but I don't know an easier/better way.



  • How does the & work? Notice I do map(&:to_i) and inject(:+). I have seen examples of this but don't know why they are different and what is going on.



  • Any suggestions on code improvements?

Solution

Here is a little simpler way to write your code:

list = (2..1_000_000).select do |num|
  num.to_s.chars.map {|digit| digit.to_i ** 5}.inject(:+) == num
end


-
Using map twice is not big issue here, you operate on small collection and memory is not an issue (for really big collections you would probably want to use lazy, it's slower but somehow smarter).

-
The ampersand converts a symbol to a proc.

Inject without ampersand works pretty much the same, see documentation for details:


If you specify a symbol instead, then each element in the collection will be passed to the named method of memo

Given memo = 0 and element 12 ruby does: 0 passed-symbol 12.

-
I'm not sure improvements are worth it, you can't really make it shorter or easier to read and performance or design is not necessary an issue here.

Code Snippets

list = (2..1_000_000).select do |num|
  num.to_s.chars.map {|digit| digit.to_i ** 5}.inject(:+) == num
end

Context

StackExchange Code Review Q#55762, answer score: 5

Revisions (0)

No revisions yet.