Skip to content

Commit

Permalink
Solve p3 in C# (Java port to follow)
Browse files Browse the repository at this point in the history
  • Loading branch information
LivInTheLookingGlass committed Aug 29, 2024
1 parent 2f5ad7b commit d518847
Show file tree
Hide file tree
Showing 9 changed files with 248 additions and 2 deletions.
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ Olivia's Project Euler Solutions
| | C++14+ in: |msvc| [1]_ | | |CodeQL| |br| |
| | |br| Browser [3]_ | | |Cp-lint| |
+------------+----------------------------+--------+-------------------+
| C# | .NET 2+ | 18 | |C#i| |br| |
| C# | .NET 2+ | 19 | |C#i| |br| |
| | | | |Cs-Cov| |br| |
| | | | |CodeQL| |br| |
| | | | |C#-lint| |
Expand Down
33 changes: 33 additions & 0 deletions csharp/Euler.Test/test.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public static IEnumerable<object[]> Data()
yield return new object[] { typeof(p0000), false, 0 };
yield return new object[] { typeof(p0001), false, Utilities.GetAnswer(1) };
yield return new object[] { typeof(p0002), false, Utilities.GetAnswer(2) };
yield return new object[] { typeof(p0003), false, Utilities.GetAnswer(3) };
yield return new object[] { typeof(p0004), false, Utilities.GetAnswer(4) };
yield return new object[] { typeof(p0006), false, Utilities.GetAnswer(6) };
yield return new object[] { typeof(p0008), false, Utilities.GetAnswer(8) };
Expand Down Expand Up @@ -58,6 +59,38 @@ public void EulerTest_Mathematics_Factorial()
}
}

[Fact]
public void EulerTest_Prime_Primes()
{
List<long> results = new() {
2, 3, 5, 7, 11, 13, 17, 19, 23, 29
};
var comparison = Prime.Primes().GetEnumerator();
for (byte i = 0; i < results.Count; i += 1)
{
long expected = results[i];
comparison.MoveNext();
Assert.Equal(expected, comparison.Current);
}
}

[Fact]
public void EulerTest_Prime_PrimeFactors()
{
List<long> candidates = new() {
2, 3, 5, 7, 11, 13, 17, 19, 23, 29
};
foreach (long x in candidates)
{
foreach (long y in candidates)
{
List<long> result = new(Prime.PrimeFactors(x * y));
Assert.Contains(x, result);
Assert.Contains(y, result);
}
}
}

[Fact]
public async Task EulerTest_Mathematics_NChooseR()
{
Expand Down
141 changes: 141 additions & 0 deletions csharp/Euler/include/prime.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
using System;

namespace Euler
{
public static class Prime
{
private static long lastCached = 0;
private static List<long> cache = new();

public static IEnumerable<long> Primes(long? stop = null)
{
if (stop is null)
{
foreach (var p in cache)
{
yield return p;
}
}
else
{
foreach (var p in cache)
{
if (p < stop)
yield return p;
else
break;
}
}
if (stop is not null && lastCached > stop)
yield break;
foreach (var p in ModifiedEratosthenes())
{
if (p <= lastCached)
continue;
if (stop is not null && p > stop)
break;
cache.Add(p);
lastCached = p;
yield return p;
}
}

private static IEnumerable<long> ModifiedEratosthenes()
{
yield return 2;
yield return 3;
yield return 5;
yield return 7;
Dictionary<long, long> sieve = new();
var recurse = ModifiedEratosthenes().GetEnumerator();
recurse.MoveNext();
recurse.MoveNext();
long prime = recurse.Current;
if (prime != 3)
throw new Exception();
long primeSquared = prime * prime;
long step = 2;
for (long candidate = 9; ; candidate += 2)
{
if (sieve.ContainsKey(candidate))
{
step = sieve[candidate];
sieve.Remove(candidate);
}
else if (candidate < primeSquared)
{
yield return candidate;
continue;
}
else
{
step = prime * 2;
recurse.MoveNext();
prime = recurse.Current;
primeSquared = prime * prime;
}
long tc = candidate;
do
{
tc += step;
} while (sieve.ContainsKey(tc));
sieve.Add(tc, step);
}
}

public static IEnumerable<long> PrimeFactors(long n)
{
if (n < 0)
{
yield return -1;
n = -n;
}
if (n == 0)
{
yield return 0;
}
else
{
long root = (long)Math.Ceiling(Math.Sqrt(n));
foreach (long factor in Primes())
{
long modulo = n % factor;
if (modulo == 0)
{
do
{
yield return factor;
n /= factor;
modulo = n % factor;
} while (modulo == 0);
root = (long)Math.Ceiling(Math.Sqrt(n));
}
if (n <= 1)
break;
if (factor > root)
{
yield return n;
break;
}
}
}
}

public static long isComposite(long n)
{
var factors = PrimeFactors(n).GetEnumerator();
factors.MoveNext();
long first = factors.current;

Check failure on line 128 in csharp/Euler/include/prime.cs

View workflow job for this annotation

GitHub Actions / csharp (2, ubuntu-latest)

'IEnumerator<long>' does not contain a definition for 'current' and no accessible extension method 'current' accepting a first argument of type 'IEnumerator<long>' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 128 in csharp/Euler/include/prime.cs

View workflow job for this annotation

GitHub Actions / csharp (3, ubuntu-latest)

'IEnumerator<long>' does not contain a definition for 'current' and no accessible extension method 'current' accepting a first argument of type 'IEnumerator<long>' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 128 in csharp/Euler/include/prime.cs

View workflow job for this annotation

GitHub Actions / csharp (5, ubuntu-latest)

'IEnumerator<long>' does not contain a definition for 'current' and no accessible extension method 'current' accepting a first argument of type 'IEnumerator<long>' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 128 in csharp/Euler/include/prime.cs

View workflow job for this annotation

GitHub Actions / csharp (6, ubuntu-latest)

'IEnumerator<long>' does not contain a definition for 'current' and no accessible extension method 'current' accepting a first argument of type 'IEnumerator<long>' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 128 in csharp/Euler/include/prime.cs

View workflow job for this annotation

GitHub Actions / csharp (7, ubuntu-latest)

'IEnumerator<long>' does not contain a definition for 'current' and no accessible extension method 'current' accepting a first argument of type 'IEnumerator<long>' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 128 in csharp/Euler/include/prime.cs

View workflow job for this annotation

GitHub Actions / csharp (8, ubuntu-latest)

'IEnumerator<long>' does not contain a definition for 'current' and no accessible extension method 'current' accepting a first argument of type 'IEnumerator<long>' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 128 in csharp/Euler/include/prime.cs

View workflow job for this annotation

GitHub Actions / csharp (9, ubuntu-latest)

'IEnumerator<long>' does not contain a definition for 'current' and no accessible extension method 'current' accepting a first argument of type 'IEnumerator<long>' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 128 in csharp/Euler/include/prime.cs

View workflow job for this annotation

GitHub Actions / csharp (6, macos-latest)

'IEnumerator<long>' does not contain a definition for 'current' and no accessible extension method 'current' accepting a first argument of type 'IEnumerator<long>' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 128 in csharp/Euler/include/prime.cs

View workflow job for this annotation

GitHub Actions / csharp (6, macos-13)

'IEnumerator<long>' does not contain a definition for 'current' and no accessible extension method 'current' accepting a first argument of type 'IEnumerator<long>' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 128 in csharp/Euler/include/prime.cs

View workflow job for this annotation

GitHub Actions / csharp (6, windows-latest)

'IEnumerator<long>' does not contain a definition for 'current' and no accessible extension method 'current' accepting a first argument of type 'IEnumerator<long>' could be found (are you missing a using directive or an assembly reference?)
if (first == n)
return 0;
return first;
}

public static bool isPrime(long n)
{
if (n < 2)
return false;
return isComposite(n) == 0;
}
}
}
Empty file removed csharp/Euler/include/primes.cs
Empty file.
24 changes: 24 additions & 0 deletions csharp/Euler/p0003.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
Project Euler Problem 3
More lazy functions this time. Took a little while to figure out how to
eliminate the special case for 2.
Problem:
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
*/
using System;

namespace Euler
{
public class p0003 : IEuler
{
public object Answer()
{
return (short)Enumerable.Max(Prime.PrimeFactors(600851475143));
}
}
}
1 change: 1 addition & 0 deletions csharp/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ Problems Solved

- ☒ `1 <./Euler/p0001.cs>`__
- ☒ `2 <./Euler/p0002.cs>`__
- ☒ `3 <./Euler/p0003.cs>`__
- ☒ `4 <./Euler/p0004.cs>`__
- ☒ `6 <./Euler/p0006.cs>`__
- ☒ `8 <./Euler/p0008.cs>`__
Expand Down
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ Problems Solved
+-----------+------------+------------+------------+------------+------------+------------+------------+
|:prob:`2` |:c-d:`0002` |:cp-d:`0002`|:cs-d:`0002`|:ja-d:`0002`|:js-d:`0002`|:py-d:`0002`|:rs-d:`0002`|
+-----------+------------+------------+------------+------------+------------+------------+------------+
|:prob:`3` |:c-d:`0003` | | | |:js-d:`0003`|:py-d:`0003`|:rs-d:`0003`|
|:prob:`3` |:c-d:`0003` | |:cs-d:`0003`| |:js-d:`0003`|:py-d:`0003`|:rs-d:`0003`|
+-----------+------------+------------+------------+------------+------------+------------+------------+
|:prob:`4` |:c-d:`0004` |:cp-d:`0004`|:cs-d:`0004`|:ja-d:`0004`|:js-d:`0004`|:py-d:`0004`|:rs-d:`0004`|
+-----------+------------+------------+------------+------------+------------+------------+------------+
Expand Down
29 changes: 29 additions & 0 deletions docs/src/csharp/lib/csharp.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
prime.cs
========

View source code :source:`csharp/include/prime.cs`

.. csharp:namespace:: Euler
.. csharp:class:: Prime
.. csharp:method:: static IEnumerable<long> Primes(long? stop = null)
Iterate over the prime numbers, optionally stopping before the specified value. Primes are cached between
calls so we don't waste effort.

.. csharp:method:: static IEnumerable<long> PrimeFactors(long n)
Iterate over the prime factors of a number (but also ``-1`` and ``0`` in some cases).

.. csharp:method:: static long isComposite(long n)
Returns ``0`` if the given number is prime, and otherwise returns its smallest prime factor.

.. csharp:method:: static bool isPrime(long n)
Returns ``true`` if a number is prime, and ``false`` otherwise.

.. literalinclude:: ../../../../csharp/Euler/include/prime.cs
:language: csharp
:linenos:
18 changes: 18 additions & 0 deletions docs/src/csharp/p0003.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
C# Implementation of Problem 3
==============================

View source code :source:`csharp/Euler/p0003.cs`

.. csharp:namespace:: Euler
.. csharp:class:: p0003
.. csharp:inherits:: Euler.IEuler
.. csharp:method:: object Answer()
.. literalinclude:: ../../../csharp/Euler/p0003.cs
:language: csharp
:linenos:

.. tags:: fibonacci-number, divisibility

0 comments on commit d518847

Please sign in to comment.