Skip to main content
added 554 characters in body
Source Link
Adam
  • 5.1k
  • 1
  • 29
  • 45

You can have both performance and readability using the newly-introduced (.NET 4.0) method BigInteger.GreatestCommonDivisor (a reference to System.Numerics is required).

With the BigInteger stuct, you gain an additional advantage: your code will work for arbitrarily large numbers (assuming sufficient memory).

var result = ClosedInterval(1, 20).LeastCommonMultiple();

What we are looking for is the least common multiple of all natural numbers in the interval [1, 20], so we'll need a method to generate them (closed means including both bounds and the numbers between):

static IEnumerable<BigInteger> ClosedInterval(BigInteger first, BigInteger last)
{
    for (var i = first; i <= last; i++)
    {
        yield return i;
    }
}

From Wikipedia, we know how to calculate the least common multiple of two numbers:

static BigInteger LeastCommonMultiple(BigInteger a, BigInteger b)
{
    return (a * b) / BigInteger.GreatestCommonDivisor(a, b);
}

For an arbitrary number of least common multiples, we simply aggregate them using LINQ and package the logic in an extension method:

static BigInteger LeastCommonMultiple(this IEnumerable<BigInteger> divisors)
{
    return divisors.Aggregate(LeastCommonMultiple);
}

The implementation calculates the correct result (232792560) in less than ten milliseconds.

In less than half a second, you can find out the answer for an input of [1, 20000]; The solution is over eight thousand digits long and therefore somewhat outside the scope of this answer.


What's really awesome:

  • There is an implicit cast from int to BigInteger, so you can pass integer literals as arguments to ClosedInterval

  • The arithmetic operators are overloaded, so you can use the same syntax for dividing, multiplying, etc. as you would with the integral numeric types

  • BigInteger is extremely optimized for speed (the only thing to wary of is that it is a struct, and therefore exhibits different memory behaviour than reference types do).

  • It turns out that the aggregation is highly parallelizable! Just using PLINQ like this:

     static BigInteger LeastCommonMultiple(this IEnumerable<BigInteger> divisors)
     {
         return divisors.AsParallel().Aggregate(LeastCommonMultiple);
     }
    

leads to a performance improvement proportional to the number of cores in your machine. In my case, finding the least common multiple of all natural numbers between one and two hundred thousand completed in around six seconds (the sequential version took over 45).

You can have both performance and readability using the newly-introduced (.NET 4.0) method BigInteger.GreatestCommonDivisor (a reference to System.Numerics is required).

With the BigInteger stuct, you gain an additional advantage: your code will work for arbitrarily large numbers (assuming sufficient memory).

var result = ClosedInterval(1, 20).LeastCommonMultiple();

What we are looking for is the least common multiple of all natural numbers in the interval [1, 20], so we'll need a method to generate them (closed means including both bounds and the numbers between):

static IEnumerable<BigInteger> ClosedInterval(BigInteger first, BigInteger last)
{
    for (var i = first; i <= last; i++)
    {
        yield return i;
    }
}

From Wikipedia, we know how to calculate the least common multiple of two numbers:

static BigInteger LeastCommonMultiple(BigInteger a, BigInteger b)
{
    return (a * b) / BigInteger.GreatestCommonDivisor(a, b);
}

For an arbitrary number of least common multiples, we simply aggregate them using LINQ and package the logic in an extension method:

static BigInteger LeastCommonMultiple(this IEnumerable<BigInteger> divisors)
{
    return divisors.Aggregate(LeastCommonMultiple);
}

The implementation calculates the correct result (232792560) in less than ten milliseconds.

In less than half a second, you can find out the answer for an input of [1, 20000]; The solution is over eight thousand digits long and therefore somewhat outside the scope of this answer.


What's really awesome:

  • There is an implicit cast from int to BigInteger, so you can pass integer literals as arguments to ClosedInterval

  • The arithmetic operators are overloaded, so you can use the same syntax for dividing, multiplying, etc. as you would with the integral numeric types

  • BigInteger is extremely optimized for speed (the only thing to wary of is that it is a struct, and therefore exhibits different memory behaviour than reference types do).

You can have both performance and readability using the newly-introduced (.NET 4.0) method BigInteger.GreatestCommonDivisor (a reference to System.Numerics is required).

With the BigInteger stuct, you gain an additional advantage: your code will work for arbitrarily large numbers (assuming sufficient memory).

var result = ClosedInterval(1, 20).LeastCommonMultiple();

What we are looking for is the least common multiple of all natural numbers in the interval [1, 20], so we'll need a method to generate them (closed means including both bounds and the numbers between):

static IEnumerable<BigInteger> ClosedInterval(BigInteger first, BigInteger last)
{
    for (var i = first; i <= last; i++)
    {
        yield return i;
    }
}

From Wikipedia, we know how to calculate the least common multiple of two numbers:

static BigInteger LeastCommonMultiple(BigInteger a, BigInteger b)
{
    return (a * b) / BigInteger.GreatestCommonDivisor(a, b);
}

For an arbitrary number of least common multiples, we simply aggregate them using LINQ and package the logic in an extension method:

static BigInteger LeastCommonMultiple(this IEnumerable<BigInteger> divisors)
{
    return divisors.Aggregate(LeastCommonMultiple);
}

The implementation calculates the correct result (232792560) in less than ten milliseconds.

In less than half a second, you can find out the answer for an input of [1, 20000]; The solution is over eight thousand digits long and therefore somewhat outside the scope of this answer.


What's really awesome:

  • There is an implicit cast from int to BigInteger, so you can pass integer literals as arguments to ClosedInterval

  • The arithmetic operators are overloaded, so you can use the same syntax for dividing, multiplying, etc. as you would with the integral numeric types

  • BigInteger is extremely optimized for speed (the only thing to wary of is that it is a struct, and therefore exhibits different memory behaviour than reference types do).

  • It turns out that the aggregation is highly parallelizable! Just using PLINQ like this:

     static BigInteger LeastCommonMultiple(this IEnumerable<BigInteger> divisors)
     {
         return divisors.AsParallel().Aggregate(LeastCommonMultiple);
     }
    

leads to a performance improvement proportional to the number of cores in your machine. In my case, finding the least common multiple of all natural numbers between one and two hundred thousand completed in around six seconds (the sequential version took over 45).

sorry, performance figures were off a bit.
Source Link
Adam
  • 5.1k
  • 1
  • 29
  • 45

You can have both performance and readability using the newly-introduced (.NET 4.0) method BigInteger.GreatestCommonDivisor (a reference to System.Numerics is required).

With the BigInteger stuct, you gain an additional advantage: your code will work for arbitrarily large numbers (assuming sufficient memory).

var result = ClosedInterval(1, 20).LeastCommonMultiple();

What we are looking for is the least common multiple of all natural numbers in the interval [1, 20], so we'll need a method to generate them (closed means including both bounds and the numbers between):

static IEnumerable<BigInteger> ClosedInterval(BigInteger first, BigInteger last)
{
    for (var i = first; i <= last; i++)
    {
        yield return i;
    }
}

From Wikipedia, we know how to calculate the least common multiple of two numbers:

static BigInteger LeastCommonMultiple(BigInteger a, BigInteger b)
{
    return (a * b) / BigInteger.GreatestCommonDivisor(a, b);
}

For an arbitrary number of least common multiples, we simply aggregate them using LINQ and package the logic in an extension method:

static BigInteger LeastCommonMultiple(this IEnumerable<BigInteger> divisors)
{
    return divisors.Aggregate(LeastCommonMultiple);
}

The implementation calculates the correct result (232792560) in less than one tenth of a millisecondten milliseconds on my machine.

In less than half a second, you can find out the answer for an input of [1, 20000]; The solution is over eight thousand digits long and therefore somewhat outside the scope of this answer.


What's really awesome:

  • There is an implicit cast from int to BigInteger, so you can pass integer literals as arguments to ClosedInterval

  • The arithmetic operators are overloaded, so you can use the same syntax for dividing, multiplying, etc. as you would with the integral numeric types

  • BigInteger is extremely optimized for speed (the only thing to wary of is that it is a struct, and therefore exhibits different memory behaviour than reference types do).

You can have both performance and readability using the newly-introduced (.NET 4.0) method BigInteger.GreatestCommonDivisor (a reference to System.Numerics is required).

With the BigInteger stuct, you gain an additional advantage: your code will work for arbitrarily large numbers (assuming sufficient memory).

var result = ClosedInterval(1, 20).LeastCommonMultiple();

What we are looking for is the least common multiple of all natural numbers in the interval [1, 20], so we'll need a method to generate them (closed means including both bounds and the numbers between):

static IEnumerable<BigInteger> ClosedInterval(BigInteger first, BigInteger last)
{
    for (var i = first; i <= last; i++)
    {
        yield return i;
    }
}

From Wikipedia, we know how to calculate the least common multiple of two numbers:

static BigInteger LeastCommonMultiple(BigInteger a, BigInteger b)
{
    return (a * b) / BigInteger.GreatestCommonDivisor(a, b);
}

For an arbitrary number of least common multiples, we simply aggregate them using LINQ and package the logic in an extension method:

static BigInteger LeastCommonMultiple(this IEnumerable<BigInteger> divisors)
{
    return divisors.Aggregate(LeastCommonMultiple);
}

The implementation calculates the correct result (232792560) in less than one tenth of a millisecond on my machine.

In less than half a second, you can find out the answer for an input of [1, 20000]; The solution is over eight thousand digits long and therefore somewhat outside the scope of this answer.


What's really awesome:

  • There is an implicit cast from int to BigInteger, so you can pass integer literals as arguments to ClosedInterval

  • The arithmetic operators are overloaded, so you can use the same syntax for dividing, multiplying, etc. as you would with the integral numeric types

  • BigInteger is extremely optimized for speed (the only thing to wary of is that it is a struct, and therefore exhibits different memory behaviour than reference types do).

You can have both performance and readability using the newly-introduced (.NET 4.0) method BigInteger.GreatestCommonDivisor (a reference to System.Numerics is required).

With the BigInteger stuct, you gain an additional advantage: your code will work for arbitrarily large numbers (assuming sufficient memory).

var result = ClosedInterval(1, 20).LeastCommonMultiple();

What we are looking for is the least common multiple of all natural numbers in the interval [1, 20], so we'll need a method to generate them (closed means including both bounds and the numbers between):

static IEnumerable<BigInteger> ClosedInterval(BigInteger first, BigInteger last)
{
    for (var i = first; i <= last; i++)
    {
        yield return i;
    }
}

From Wikipedia, we know how to calculate the least common multiple of two numbers:

static BigInteger LeastCommonMultiple(BigInteger a, BigInteger b)
{
    return (a * b) / BigInteger.GreatestCommonDivisor(a, b);
}

For an arbitrary number of least common multiples, we simply aggregate them using LINQ and package the logic in an extension method:

static BigInteger LeastCommonMultiple(this IEnumerable<BigInteger> divisors)
{
    return divisors.Aggregate(LeastCommonMultiple);
}

The implementation calculates the correct result (232792560) in less than ten milliseconds.

In less than half a second, you can find out the answer for an input of [1, 20000]; The solution is over eight thousand digits long and therefore somewhat outside the scope of this answer.


What's really awesome:

  • There is an implicit cast from int to BigInteger, so you can pass integer literals as arguments to ClosedInterval

  • The arithmetic operators are overloaded, so you can use the same syntax for dividing, multiplying, etc. as you would with the integral numeric types

  • BigInteger is extremely optimized for speed (the only thing to wary of is that it is a struct, and therefore exhibits different memory behaviour than reference types do).

added 473 characters in body
Source Link
Adam
  • 5.1k
  • 1
  • 29
  • 45

You can have both performance and readability using the newly-introduced (.NET 4.0) method BigInteger.GreatestCommonDivisor (a reference to System.Numerics is required).

With the BigInteger stuct, you gain an additional advantage: your code will work for arbitrarily large numbers (assuming sufficient memory).

var result = ClosedInterval(1, 20).LeastCommonMultiple();

What we are looking for is the least common multiple of all natural numbers in the interval [1, 20], so we'll need a method to generate them (closed means including both bounds and the numbers between):

static IEnumerable<BigInteger> ClosedInterval(BigInteger first, BigInteger last)
{
    for (var i = first; i <= last; i++)
    {
        yield return i;
    }
}

From Wikipedia, we know how to calculate the least common multiple of two numbers:

static BigInteger LeastCommonMultiple(BigInteger a, BigInteger b)
{
    return (a * b) / BigInteger.GreatestCommonDivisor(a, b);
}

For an arbitrary number of least common multiples, we simply aggregate them using LINQ and package the logic in an extension method:

static BigInteger LeastCommonMultiple(this IEnumerable<BigInteger> divisors)
{
    return divisors.Aggregate(LeastCommonMultiple);
}

The implementation calculates the correct result (232792560) in less than one tenth of a millisecond on my machine.

In less than half a second, you can find out the answer for an input of [0[1, 20000]; The solution is over eight thousand digits long and therefore somewhat outside the scope of this answer.


What's really awesome:

  • There is an implicit cast from int to BigInteger, so you can pass integer literals as arguments to ClosedInterval

  • The arithmetic operators are overloaded, so you can use the same syntax for dividing, multiplying, etc. as you would with the integral numeric types

  • BigInteger is extremely optimized for speed (the only thing to wary of is that it is a struct, and therefore exhibits different memory behaviour than reference types do).

You can have both performance and readability using the newly-introduced (.NET 4.0) method BigInteger.GreatestCommonDivisor (a reference to System.Numerics is required).

With the BigInteger stuct, you gain an additional advantage: your code will work for arbitrarily large numbers (assuming sufficient memory).

var result = ClosedInterval(1, 20).LeastCommonMultiple();

What we are looking for is the least common multiple of all natural numbers in the interval [1, 20], so we'll need a method to generate them (closed means including both bounds and the numbers between):

static IEnumerable<BigInteger> ClosedInterval(BigInteger first, BigInteger last)
{
    for (var i = first; i <= last; i++)
    {
        yield return i;
    }
}

From Wikipedia, we know how to calculate the least common multiple of two numbers:

static BigInteger LeastCommonMultiple(BigInteger a, BigInteger b)
{
    return (a * b) / BigInteger.GreatestCommonDivisor(a, b);
}

For an arbitrary number of least common multiples, we simply aggregate them using LINQ and package the logic in an extension method:

static BigInteger LeastCommonMultiple(this IEnumerable<BigInteger> divisors)
{
    return divisors.Aggregate(LeastCommonMultiple);
}

The implementation calculates the correct result (232792560) in less than one tenth of a millisecond on my machine.

In less than half a second, you can find out the answer for an input of [0, 20000]; The solution is over eight thousand digits long and therefore somewhat outside the scope of this answer.

You can have both performance and readability using the newly-introduced (.NET 4.0) method BigInteger.GreatestCommonDivisor (a reference to System.Numerics is required).

With the BigInteger stuct, you gain an additional advantage: your code will work for arbitrarily large numbers (assuming sufficient memory).

var result = ClosedInterval(1, 20).LeastCommonMultiple();

What we are looking for is the least common multiple of all natural numbers in the interval [1, 20], so we'll need a method to generate them (closed means including both bounds and the numbers between):

static IEnumerable<BigInteger> ClosedInterval(BigInteger first, BigInteger last)
{
    for (var i = first; i <= last; i++)
    {
        yield return i;
    }
}

From Wikipedia, we know how to calculate the least common multiple of two numbers:

static BigInteger LeastCommonMultiple(BigInteger a, BigInteger b)
{
    return (a * b) / BigInteger.GreatestCommonDivisor(a, b);
}

For an arbitrary number of least common multiples, we simply aggregate them using LINQ and package the logic in an extension method:

static BigInteger LeastCommonMultiple(this IEnumerable<BigInteger> divisors)
{
    return divisors.Aggregate(LeastCommonMultiple);
}

The implementation calculates the correct result (232792560) in less than one tenth of a millisecond on my machine.

In less than half a second, you can find out the answer for an input of [1, 20000]; The solution is over eight thousand digits long and therefore somewhat outside the scope of this answer.


What's really awesome:

  • There is an implicit cast from int to BigInteger, so you can pass integer literals as arguments to ClosedInterval

  • The arithmetic operators are overloaded, so you can use the same syntax for dividing, multiplying, etc. as you would with the integral numeric types

  • BigInteger is extremely optimized for speed (the only thing to wary of is that it is a struct, and therefore exhibits different memory behaviour than reference types do).

Source Link
Adam
  • 5.1k
  • 1
  • 29
  • 45
Loading