Feeds:
Posts
Comments

Posts Tagged ‘Project Euler’


There’s no neat and nice way of clearing the irb console as it seems.

There is a way however.

Put the following in a file called utilities.rb.

module Utilities
  def cls
    system 'cls'
  end
end

Then put the following lines into the project where you want to clear the irb console.

require_relative 'utilities.rb'

include Utilities

and use the cls function thus

Utilities.cls

Note: This only works on Windows machines.

Read Full Post »


Decided to combine these two as 29 was very simple (unless you don’t want to use BigInteger in .net 4).

Here’s the code for 29:

var terms = new HashSet<double>();
           
for (double a = 2; a <= 100; a++)
{
    for (double b = 2; b <= 100; b++)
    {
        terms.Add(Math.Pow(a, b));
    }
}

Basically I just find all the values and put them into a list, then I use the distinct function to get each value only once and then I count that number.
It does get a bit trickier if you don’t want to or can’t use BigInteger though.

EDIT: BigInteger is not needed as Math.pow can’t return any value bigger than double.MaxValue anyway. Thanks Mikael. Now it’s even faster and there’s no need for .net 4.
EDIT2: Using a hashset also eliminates the need for the distinct iteration over the collection. To get the number of distinct values, just use the count property on terms.

Problem 30 was a little harder but not much. Problem here is to know when to start but some thought solved that problem aswell.

At some point the sum of the digits will be overtaken by the value itself, this is the time to stop.
If we start looking at the maxvalue that four digits can produce when taking the fifth power of them. The maximum of each digit is 9^5 and 4 digits equals 236196. That is 6 digits so 4 digits is not correct.
Lets look at 5 digits then, 5 * 9^5 = 295245, still 6 digits and we’re still not there.
6 digits = 354294, now we’re getting close. 6 digits from the power of five = 6 digits in the value.
7 digits = 413343. Here the value overtakes the maximum from the digits to the power of five.

I was quite happy with my solution which looks like this:

int sum = 0;

foreach (var num in GetNumber())
{
    if (num == GetFifthPowerSum(num))
    {
        sum += num;
    }

    if (num == upperBound ) 
    {
        break;
    }
}
private int GetFifthPowerSum(int num)
{
    if ((num % 10 == 0) && (num.ToString().Length <= 1))
    {
        return 0;
    }

    int thisDigit = num % 10;
    int rest = num / 10;

    return (int)Math.Pow(thisDigit, 5) + GetFifthPowerSum(rest);
}

private static IEnumerable<int> GetNumber()
{
    int number = 1;

    while (number < int.MaxValue)
        yield return ++number;
}

That should be pretty self explanatory but I’ll go through it anyway.
If the value of the fifth power sum is equal to the number itself then sum those numbers.
If number is equal to 7 * 9^5 then stop looping.

GetFifthPowerSum is a recursive function that sums each digit to the fifth power in the number.
GetDecimal returns the number starting at 2 up to Int.MaxValue.

Read Full Post »


This one wasn’t all that hard so I’ll just give some friendly pointers to what the important points are:

The formula looked like this: n^2 + a * n + b, |a| < 1000, |b| < 1000

As the formula always starts with n = 0 the first value is always b. This gives that for an unbroken prime sequence b has to be prime. A prime must be positive and thus all negative b values can be ignored.

Another thing to make sure that the program won't run for hours on end is to create a list of all prime numbers up to an amount of b-1 (in this case 998) as the longest prime sequence is no longer than b-1 and check each value coming from the formula against this list of primes. Here is the evidence (I am not the one formulating this but can't remember who to give credit):

"If n=kb, n2+an+b=(kb)2+kab+b≡0 mod b. Hence if n is between two consecutive multiples of b, for exmaple, 3b and 4b, then it WILL be composite when n=4b. Therefore the longest chain of consecutive composities is (k+1)b-kb-1=b-1."

And the n at which to stop calculating is when the sequence of primes is broken.

There are most likely more optimizations that can be made but I am satisfied with ~14 seconds of execution time and won't put any more time into it.

Read Full Post »


This one was some real work for me.

I went long and pondered how to get the required number of decimals needed. The Decimal-class only held a maximum of 18 decimals and there is no larger type to use. There is no class corresponding to BigInteger for decimals either in .NET or C#. There is a BigDecimals class for J# but I didn’t want to use that as I decided that using .NET libraries for C# is fine but other libraries is not and especially not third-party products.

This had a much simpler solution than I could have thought.
I’ll give an example using 1/7 that my friend used to explain to me:

1/7 = 0.142857… % 10 = 0
10/7 = 1.42857… % 10 = 1
100/7 = 14.2857… % 10 = 4
1000/7 = 142.857… % 10 = 2

Stupidly easy.
So I made a class that gives me one decimal each time I iterate which looks like this:


private static IEnumerable GetDecimalsReversed(int numerator, int denominator, int numberOfDecimals)
{
    int exponent = numberOfDecimals;

    while (exponent > 0)
    {
        yield return int.Parse((((BigInteger.Pow(10, --exponent) * 1) / denominator) % (BigInteger)10).ToString());
    }
}

and is used like this:


foreach int fractionDecimal in GetDecimalsReversed(1, divideBy, divideBy * 2));

A small note here is that this class gives me the decimals starting from numberOfDecimals and walks toward the decimal point, the reason for this will be explained, I will also explain why I use divideBy * 2 as numberOfDecimals.

Now, the next problem I encountered was how to find the loop. There could be decimals in the start that isn’t a part of the loop. After some searching around I found out that the length of the recurring cycle a/b will always be shorter than b. Now I decided to get rid of the problem with the possible irrelevant decimals directly after the decimal point and instead start from behind, here’s the reason for getting the decimals reversed and also for numberOfDecimals being divideBy * 2.

My friend helped me find the algorithm for the loop. I’ll give a brief explanation (using the way my program calculates):

1/7 = 0.14285714285714

4 != 1
57 != 14
285 != 714
1428 != 5714
57142 != 85714
285714 == 285714

When I find a sequence that matches I know that I have the recurrance cycle. One problem here is that possibly there could be a sequence that ends with the same two numbers (e.g. 0.112233112233) where this will be wrong. This never happened in problem 26 so I decided not to guard against it.

For opmimization I caclulate only prime numbers as per mathematical evidence, those have the longest recurring cycles.

Read Full Post »


I got led to Project Euler by a good friend of mine about a year ago. He mentioned it and I thought it was a bit of a chore to solve the problems so I didn’t get on the band wagon.

We got to discuss it again a few months ago when I had started my new job and I was much more “into” the idea now. The new job had motivated me to do some programming and I had already started reading a lot of programming books and articles, besides I had started C# and was eager to try it out.

Some time before I had my second child I started problem 22 (http://projecteuler.net/index.php?section=problems&id=22) which at first seemed very simple. I thought out a solution and implemented it and it was the wrong answer.

I had a suspicion about sort being the problem as all the other code was trivial. I thought it had to do with sort being an unstable sort but couldn’t see how that could affect anything.

I spoke to my friend and he scratched his head for about an hour before he saw what was wrong.
When sorting the list of names everything was correct up to v. Turns out that when using the Sort-function on a list it is affected by which language setting you are using. In my case Swedish was used and apparantly V and W are treated the same, thus I got a sequence such as this:

Vanessa
Wendolyn
William
Vyllian

The fix for this was putting the following row in the code:

Thread.CurrentThread.CurrentCulture = new CultureInfo "en-GB";

Read Full Post »