Friday, February 7, 2014

Friend Key

I forgot that this was a thing until now: in case following this blog isn't enough knowledge of my Euler, you can follow me using my Project Euler friend key, which is:

74984898511083_5d87aba52ef23ddb87141cc890ae65d4

Also, my current level / # of problems solved is always updated at:

http://projecteuler.net/profile/PELC.png

Problem 75 - getting to level 3 in Vala

After not using Vala for problem 74 due to the attractiveness of Genie, I used Vala for problem 75. I never did solve this problem before (reason why probably because I worked in a functional programming language my first time through Euler, and this problem begs for a big array or dictionary). However, it wasn't terribly hard, I just made a lot of dumb mistakes along the way (the last of which which needed to be fixed was "oh yeah, 1 is an odd number." This problem also should be noted for probably teaching close to 8000 people about Euclid's Formula for generating Pythagorean Triples. My solution runs in .1s in my machine, which I am pretty satisfied with, especially as I search over a larger than necessary space. Also, this is problem 75, and thus the 75th problem I have solved: this moved my Project Euler account to Level 3, a feat accomplished by only 3.45% of users.
int gcd(int a, int b) {
    if (b == 0) {
        return a;
    } else {
        return gcd(b, a%b);
    }
}

bool coprime(int a, int b) {
    return gcd(a, b) == 1;
}

bool odd(int x) {
    return x%2 == 1;
}

/** Returns the perimeter of the primitive pythagorean triple
    generated by m and n, assuming m, n coprime and m - n odd */
int euclid(int m, int n) {
    return 2*m*m + 2*m*n;
}

void main () {

    int[] L = new int[1500001];
    for (int i = 0; i <= 1500000; ++i) {
        L[i] = 0;
    }
    
    int ans = 0;
    int m = 1;
    int n = 1;
    int p = 0;
    while (n <= 1000) {
        m = n + 1;
        while (m <= 1000) {
            if (odd(m - n) && coprime(m, n)) {
                p = euclid(m, n);
                int k = 1;
                while (p*k <= 1500000) {
                  //  stdout.printf("%d\n", p*k);
                    if (L[p*k] == 0) {
                        ++ans;
                        L[p*k]++;
                    } else if (L[p*k] == 1) {
                        --ans;
                        L[p*k]++;
                    }
                    ++k;
                }
            }
            ++m;
        }
        ++n;
    }
    stdout.printf ("%d\n", ans);
}