Reputation: 3475
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. It is the Project Euler Problem 30
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?
Upvotes: 2
Views: 869
Reputation: 11
class Program
{
static void Main(string[] args)
{
ulong sum, gh = 0;
for (ulong i = 2; i <= 355000; i++)
{
string s = Convert.ToString(i);
sum = 0;
int ddd = s.Length;
for (int j = 0; j < ddd; j++)
{
//sum +=(int)Math.Pow(Convert.ToInt32(s[j]), 4);
ulong g = Convert.ToUInt64(Convert.ToString(s[j]));
sum = sum + (ulong)Math.Pow(g, 5);
}
// Console.WriteLine(sum);
if (sum == i)
{
gh += i;
}
}
Console.WriteLine(gh);
Console.ReadKey();
}
}
Upvotes: 1
Reputation: 564671
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.
Upvotes: 4
Reputation: 185663
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.
Upvotes: 0