I have been hearing a lot about Project Euler so I thought I solve one of the problems in C#. The problem as stated on the website is as follows:
If w
The code in DivisibleByThreeOrFive would be slightly faster if you would state it as follows:
return ((counter % 3 == 0) || (counter % 5 == 0));
And if you do not want to rely on the compiler to inline the function call, you could do this yourself by putting this code into the Main routine.
With LINQ (updated as suggested in comments)
static void Main(string[] args)
{
var total = Enumerable.Range(0,1000)
.Where(counter => (counter%3 == 0) || (counter%5 == 0))
.Sum();
Console.WriteLine(total);
Console.ReadKey();
}
I like technielogys idea, here's my idea of a modification
static int Euler1 ()
{
int sum = 0;
for (int i=3; i<1000; i+=3)
{
if (i % 5 == 0) continue;
sum+=i;
}
for (int i=5; i<1000; i+=5) sum+=i;
return sum;
}
Though also comes to mind is maybe a minor heuristic, does this make any improvement?
static int Euler1 ()
{
int sum = 0;
for (int i=3; i<1000; i+=3)
{
if (i % 5 == 0) continue;
sum+=i;
}
for (int i=5; i<250; i+=5)
{
sum+=i;
}
for (int i=250; i<500; i+=5)
{
sum+=i;
sum+=i*2;
sum+=(i*2)+5;
}
return sum;
}
You can do something like this:
Func<int,int> Euler = total=>
new List<int>() {3,5}
.Select(m => ((int) (total-1) / m) * m * (((int) (total-1) / m) + 1) / 2)
.Aggregate( (T, m) => T+=m);
You still have the double counting problem. I'll think about this a little more.
Edit:
Here is a working (if slightly inelegant) solution in LINQ:
var li = new List<int>() { 3, 5 };
Func<int, int, int> Summation = (total, m) =>
((int) (total-1) / m) * m * (((int) (total-1) / m) + 1) / 2;
Func<int,int> Euler = total=>
li
.Select(m => Summation(total, m))
.Aggregate((T, m) => T+=m)
- Summation(total, li.Aggregate((T, m) => T*=m));
Can any of you guys improve on this?
Explanation:
Remember the summation formula for a linear progression is n(n+1)/2. In the first case where you have multiples of 3,5 < 10, you want Sum(3+6+9,5). Setting total=10, you make a sequence of the integers 1 .. (int) (total-1)/3, and then sum the sequence and multiply by 3. You can easily see that we're just setting n=(int) (total-1)/3, then using the summation formula and multiplying by 3. A little algebra gives us the formula for the Summation functor.
I haven't written any Java in a while, but this should solve it in constant time with little overhead:
public class EulerProblem1
{
private static final int EULER1 = 233168;
// Equal to the sum of all natural numbers less than 1000
// which are multiples of 3 or 5, inclusive.
public static void main(String[] args)
{
System.out.println(EULER1);
}
}
EDIT: Here's a C implementation, if every instruction counts:
#define STDOUT 1
#define OUT_LENGTH 8
int main (int argc, char **argv)
{
const char out[OUT_LENGTH] = "233168\n";
write(STDOUT, out, OUT_LENGTH);
}
Notes:
write
. If true robustness is needed, a more sophisticated error handling strategy must be employed. Whether the added complexity is worth greater reliability depends on the needs of the user.out
would almost certainly be padded to 8 bytes anyway.out
variable could be avoided by placing the string inline in the write
call, any real compiler willoptimize away the declaration.write
syscall is used in preference to puts
or similar to avoid the additional overhead. Theoretically, you could invoke the system call directly, perhaps saving a few cycles, but this would raise significant portability issues. Your mileage may vary regarding whether this is an acceptable tradeoff.Here's a transliteration of my original F# solution into C#. Edited: It's basically mbeckish's solution as a loop rather than a function (and I remove the double count). I like mbeckish's better.
static int Euler1 ()
{
int sum = 0;
for (int i=3; i<1000; i+=3) sum+=i;
for (int i=5; i<1000; i+=5) sum+=i;
for (int i=15; i<1000; i+=15) sum-=i;
return sum;
}
Here's the original:
let euler1 d0 d1 n =
(seq {d0..d0..n} |> Seq.sum) +
(seq {d1..d1..n} |> Seq.sum) -
(seq {d0*d1..d0*d1..n} |> Seq.sum)
let result = euler1 3 5 (1000-1)