views:

233

answers:

2

Hi

I have this following IEnumerable LINQ query:

var query = from p in Enumerable.Range(2, 1000000)
let sumofPowers = from ch in p.ToString()
         let sumOfPowers = Math.Pow(Convert.ToDouble(ch.ToString()), 5)
                  select sumOfPowers
where p == sumofPowers.Sum()
select p;

It finds the sum of all the numbers that can be written as the sum of fifth powers of their digits. (Google Project Euler Problem 30 for a more thorough explanation).

It works fine as it is. I know it is nitpick, but the range annoys me. I have basically guessed that it has found the correct result at 1,000,000, so I let it stop there. In this scenario, the number was sufficient.

But it is just a hardcoded "random" number... If you look at the code, you find that as soon as where p == sumofPowers.Sum() is true, you don't really need to run through the loop anymore.

I know yield can do it in under other situations and break works in normal loops - so is there anything you can do in this situation?

A: 

LINQ is not the solution to all problems. Your problem only has a range that is defined by its solution, so from the "query" perspective there IS no range, making this unsuited for known set operations like LINQ and the standard IEnumerable extension methods. You would do better (and produce more readable code) using a yield statement.

Adam Robinson
+3  A: 

You can use the First() operator to break out.

Since LINQ does deferred calculation, this will go until you reach the point where p == sumofPowers.Sum(), and then return the first element. Just wrap the entire query in (...).First(); to return the first value.

Also, while you're at it, there is no need to convert to a string then to a double - you can convert directly from int -> double, and avoid the string conversions.

Reed Copsey
I am not sure what you mean by the last part.Math.Pow(Convert.ToDouble(ch.ToString()), 5)Won't work asMath.Pow((double) ch, 5)
CasperT
Try: from ch in p let sumOfPowers = Math.Pow(Convert.ToDouble(ch), 5)
Reed Copsey