Posts Tagged ‘.net4’

Project Euler Problem #214: First Attempt.

September 2nd, 2010

Problem 214 says:

Let φ be Euler’s totient function, i.e. for a natural number n, φ(n) is the number of k, 1 ≤ k ≤ n, for which gcd(k,n) = 1.

By iterating φ, each positive integer generates a decreasing chain of numbers ending in 1.
E.g. if we start with 5 the sequence 5,4,2,1 is generated.
Here is a listing of all chains with length 4:
5,4,2,1
7,6,2,1
8,4,2,1
9,6,2,1
10,4,2,1
12,4,2,1
14,6,2,1
18,6,2,1

Only two of these chains start with a prime, their sum is 12.

What is the sum of all primes less than 40000000 which generate a chain of length 25?

My first approach is to build a list of primes less than 40000000, and keeps a hashtable of all the totients that the program solves for, as well as a hashtable for storing all of the previous chains the program has come across. It works but it takes an age to give the answer, even when using .net 4′s task parallel library. So I’ll be reworking this and posting a better version.

Until then, here is the code. (C# requires .net 4)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace Problem214
{
	class MainClass
	{
        public static long[] primes = GetPrimesUpTo(40000000);
		public static Hashtable knownTotients = new Hashtable();
        public static Hashtable KnownChains = new Hashtable();
        private static object lockObject = new object();
        private static object lockObject2 = new object();

		public static void Main (string[] args)
		{
			long sum = 0L;
            Console.WriteLine("starting search");
            Parallel.ForEach(primes, p =>
            {
                //Console.WriteLine(p);
                if (Chain25((int)p))
                {
                    lock (lockObject)
                    {
                        sum = sum + p;
                        Console.WriteLine("Current Sum :: "+sum.ToString());
                    }
                }
            });
            Console.WriteLine(sum);
			Console.ReadLine();
		}
		static bool Chain25 (int num)
		{
			if (ChainLen(num) == 25)
				return true;
			else
				return false;
		}
		static int ChainLen (int num)
		{
			int c = chain(num,1);
            KnownChains.Add(num, c);
			return c;
		}
		static int chain(int num, int len)
		{
            if (KnownChains.Contains(num))
                return len + (int)KnownChains[num];
			if (len >= 25) return 60000;
            int phin = eulerTotientWrap(num);
			if (phin != 1) return chain(phin,len+1);
			else return len++;
		}
		static bool[] GetPrimeSieve(long upTo)
		{
		    long sieveSize = upTo + 1;
		    bool[] sieve = new bool[sieveSize];
		    Array.Clear(sieve, 0, (int)sieveSize);
		    sieve[0] = true;
		    sieve[1] = true;
		    long p, max = (long)Math.Sqrt(sieveSize) + 1;
		    for (long i = 2; i <= max; i++)
		    {
		        if (sieve[i]) continue;
		        p = i + i;
		        while (p < sieveSize) { sieve[p] = true; p += i; }
		    }
		    return sieve;
		}
		static long[] GetPrimesUpTo(long upTo)
		{
		    if (upTo < 2) return null;
		    bool[] sieve = GetPrimeSieve(upTo);
		    long[] primes = new long[upTo + 1];

		    long index = 0;
		    for (long i = 2; i <= upTo; i++) if (!sieve[i]) primes[index++] = i;

		    Array.Resize(ref primes, (int)index);
		    return primes;
		}
		static int GetLastIndex(int n)
		{
			for (int i = 0; i< primes.Length;i++)
			{
				if (primes[i] >= n)
					return i+1;
			}
			return primes.Length;
		}
        static int eulerTotientWrap(int n)
        {
            if (knownTotients.Contains(n))
                return (int)knownTotients[n];
            int t = eulerTotient(n);
            lock (lockObject2)
            {
                if (!knownTotients.Contains(n))
                    knownTotients.Add(n, t);
            }
            return t;

        }
		static int eulerTotient(int n)
		{
		    int numPrimes = GetLastIndex(n);

		    int totient = n;
		    int currentNum = n, temp, p, prevP = 0;
		    for (int i = 0; i < numPrimes; i++)
		    {
		        p = (int)primes[i];
		        if (p > currentNum) break;
		        temp = currentNum / p;
		        if (temp * p == currentNum)
		        {
		            currentNum = temp;
		            i--;
		            if (prevP != p) { prevP = p; totient -= (totient / p); }
		        }
		    }
		    return totient;
		}
	}
}

Tags: , , ,
Posted in Project Euler | Comments (0)

Project Euler Problem #57

May 6th, 2010

Problem #57 says:

It is possible to show that the square root of two can be expressed as an infinite continued fraction.

√ 2 = 1 + 1/(2 + 1/(2 + 1/(2 + … ))) = 1.414213…

By expanding this for the first four iterations, we get:

1 + 1/2 = 3/2 = 1.5
1 + 1/(2 + 1/2) = 7/5 = 1.4
1 + 1/(2 + 1/(2 + 1/2)) = 17/12 = 1.41666…
1 + 1/(2 + 1/(2 + 1/(2 + 1/2))) = 41/29 = 1.41379…

The next three expansions are 99/70, 239/169, and 577/408, but the eighth expansion, 1393/985, is the first example where the number of digits in the numerator exceeds the number of digits in the denominator.

In the first one-thousand expansions, how many fractions contain a numerator with more digits than denominator?


The fastest way to attack this one is to treat it as a sequence and find the pattern required to expand it. for the numerator to take the previous denominator and multiple it by two then add the previous numerator to it, for the denominator you just add the previous numerator and denominator together. This gets really big really fast so we’ll use the biginteger class in .net 4. then we just check the string length of the numerator and denominator and see which is larger. wash rinse and repeat.

Solution in f# and requires .net 4.0 Runs in (5* (10^-6)) seconds or 65 ticks on my netbook.

open System
open System.Diagnostics

let sw = new Stopwatch()
sw.Start()

let num n d = (2I*d)+n
let den n d = n+d

let rec Answer n d c count =
    if c > 1000 then
        count
    else
        if n.ToString().Length > d.ToString().Length then
            Answer (num n d) (den n d) (c+1) (count+1)
        else
            Answer (num n d) (den n d) (c+1) count

sw.Stop()
Console.WriteLine(Answer 3I 2I 0 0)
Console.WriteLine(sw.Elapsed.Ticks)
Console.ReadLine() |> ignore   

Tags: , ,
Posted in Project Euler | Comments (0)

Project Euler Problem #99!

May 1st, 2010

Problem #99 says:

Comparing two numbers written in index form like 2^(11) and 3^(7) is not difficult,
as any calculator would confirm that 2^(11) = 2048 < 3^(7) = 2187.

However, confirming that 632382^(518061) > 519432^(525806) would be much more difficult,
as both numbers contain over three million digits.

Using base_exp.txt (right click and ‘Save Link/Target As…’), a 22K text file containing one
thousand lines with a base/exponent pair on each line, determine which line number has the greatest numerical value.


This is a problem that seems kinda complicated at first. Each of the base exponent sets creates a number that easily dwarfs anything a computer can currently handle. The solution is to do something else that still lets us compare them to one another. So instead of expanding the exponent base pair what we do is multiply the exponent by the natural log of the base and use that value. Using this method reading the file in is almost harder than solving the task.

Solution in F# requires .net 4, runs in under one second.


open System
open System.IO
open System.Diagnostics

let sw = new Stopwatch()
sw.Start()

let test b e =
    e * Math.Log(b)    

let CheckSets =
    let f = new StreamReader("base_exp.txt")
    let mutable lines = []
    let mutable line = f.ReadLine()
    while line <> null do
        lines <- lines @ [line]
        line <- f.ReadLine()
    lines

let mutable mv = 0.0
let mutable ml = 0
let mutable ln = 0

let FindAnswer =
    for s in CheckSets do
        ln <- ln + 1
        let ss = s.Split(",".ToCharArray())
        let b = float ss.[0]
        let e = float ss.[1]
        if (test b e) > mv then
            mv <- (test b e)
            ml <- ln
FindAnswer
Console.WriteLine(ml)
sw.Stop()
Console.WriteLine(sw.Elapsed)
Console.ReadLine() |> ignore

Tags: , , ,
Posted in Project Euler | Comments (0)

Random Snippets.

May 1st, 2010


Here are some random snippets of f# code I had lying around. mostly simple stuff for basic stats calculations. Not the most complex stuff but maybe its useful to somebody trying to learn f#.

// Learn more about F# at http://fsharp.net
open System
open System.Net

//basic arithmetic mean
let Mean (x:List<float>) =
    let sum = x |> Seq.sum
    let items = x |>Seq.length
    sum / (float items)

//basic variance method
let Variance x =
    let m = Mean x
    let deviation =
        x
        |> Seq.map (fun x -> Math.Pow((x-m), 2.))
        |> Seq.toList
    Mean deviation

//Calculates standard deviation using above variance method
let StandardDeviation x =
    Math.Sqrt(Variance x)

//recursively calculates the factorial of x
//will overflow long before running into recursion limits
//at larger values it will wrap back around to 0
let rec Factorial x =
    if x = 0I then
        1I
    else
        x * Factorial(x-1I)

//calculates combinations
let Combinations n r =
    (Factorial n)/ ((Factorial r)*(Factorial (n-r)))

//calculates permutations
let Permutations n r =
    (Factorial n)/ (Factorial (n-r))

//uses Euclids formula for the greatest common divisor
let rec GCD a b =
    if b = 0UL then
        a
    else
        GCD b (a%b)

//returns an array representing the binary version of x
let toBinary (x:uint64) =
    let rec con (x:uint64) r =
        if x = 0UL then
            r
        else
            con (x/2UL) ([x%2UL] @ r)
    con x []

// gets ticker price using yahoo
let GetTickerPrice (ticker:string) =
    let url =
        "http://download.finance.yahoo.com/d/quotes.csv?s="+
        ticker+
        "&f=sl1d1t1c1ohgv&e=.csv"
    let wc = new WebClient()
    let info = wc.DownloadString(url).Split([|','|])
    float info.[1] // info.[1] is the current price will return 0.0 on invalid ticker

Tags: ,
Posted in Software | Comments (0)

Project Euler Problem #73!

April 26th, 2010

Problem #73 says:

Consider the fraction, n/d, where n and d are positive integers. If n

If we list the set of reduced proper fractions for d ≤ 8 in ascending order of size, we get:

1/8, 1/7, 1/6, 1/5, 1/4, 2/7, 1/3, 3/8, 2/5, 3/7, 1/2, 4/7, 3/5, 5/8, 2/3, 5/7, 3/4, 4/5, 5/6, 6/7, 7/8

It can be seen that there are 3 fractions between 1/3 and 1/2.

How many fractions lie between 1/3 and 1/2 in the sorted set of reduced proper fractions for d ≤ 12,000?

First off brute forcing this problem isn’t hard, and you can do it in well under a minute. However there is an elegant solution so readily available that it would be a shame not to go with it. The elegant method involves calculating a Farey Sequence (http://en.wikipedia.org/wiki/Farey_sequence) then counting the results. Alternatively we can just count how many results we would have without calculating the actual results.

Solution in f# and runs in ~.32 seconds. Requires .net 4 and fsharp.

#light
module ProjectEuler

open System
open System.Diagnostics

let watch = new Stopwatch()
watch.Start()

let rec FareySeq denom1 denom2 max =
    if (denom1+denom2) > max then
        0.0
    else
        1.0 + (FareySeq denom1 (denom1+denom2) max)+(FareySeq (denom1+denom2)denom2 max)

Console.WriteLine(FareySeq 3 2 12000)
watch.Stop()
Console.WriteLine(watch.Elapsed)
Console.Beep() |> ignore
Console.ReadKey() |> ignore

Tags: , ,
Posted in Project Euler | Comments (0)