patternrubyMinor
Project Euler code evaluation - digit fifth powers
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.
This works, and I am here for three reasons:
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 domap(&:to_i)andinject(:+). 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:
-
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.
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
endContext
StackExchange Code Review Q#55762, answer score: 5
Revisions (0)
No revisions yet.