# ryanohs/Euler

Switch branches/tags
Nothing to show
Fetching contributors…
Cannot retrieve contributors at this time
295 lines (265 sloc) 9.66 KB
 namespace Euler { using System; using System.Diagnostics; using System.Linq; using ExpectEx.NUnit; using NUnit.Framework; [TestFixture] public class EulerSolutions : AssertionHelperEx { /// /// Find the sum of all the multiples of 3 or 5 below 1000. /// [Test] public void Problem01() { var sum = Enumerable .Range(1, 999) .Where(n => n%3 == 0 || n%5 == 0) .Sum(); Expect(() => sum == 233168); } [Test] public void Problem01_Algebraic() { // This is about 10-15x faster than iterating and filtering var sum = 0; for (int i = 0; i < 1000; i += 3) { sum += i; } for (int i = 0; i < 1000; i += 5) { sum += i; } for (int i = 0; i < 1000; i += 15) { sum -= i; // subtract multiples of 15 } Expect(() => sum == 233168); } /// /// Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be: /// 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ... /// By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms. /// [Test] public void Problem02() { var sum = Fibonacci.Sequence() .TakeWhile(n => n <= 4000000) .Where(n => n%2L == 0) .Sum(); Expect(() => sum == 4613732); } [Test] public void Problem02_b() { // This is 3-400x faster than the LINQ solution long sum = 0; foreach (var n in Fibonacci.Sequence()) { if (n%2 != 0) continue; if (n > 4000000) break; sum += n; } Expect(() => sum == 4613732); } /// /// What is the largest prime factor of the number 600851475143 ? /// [Test] public void Problem03() { var factors = FermatFactorization.Of(600851475143); Expect(() => factors.Max() == 6857); } /// /// Find the largest palindrome made from the product of two 3-digit numbers. /// [Test] public void Problem04() { /* 999 998 997 996 999 1,1 1,2 1,3 1,4 998 2,2 2,3 2,4 997 3,3 3,4 996 4,4 I will traverse this diagonally on the upper half only: 1,1 ; 1,2 ; 2,2 ; 1,3 ; 2,3 ; 1,4 ; etc This results in the numbers appearing in decreasing order. */ var largestPalindrome = Matrix.Traverse(999, 999, (i, j) => (999 - i)*(999 - j)) .FirstOrDefault(Palindrome.Test); Expect(() => largestPalindrome == 906609); } /// /// What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20? /// [Test] public void Problem05() { var result = Enumerable .Range(1, 20) .Reverse() .Aggregate(1L, (lcm, x) => LeastCommonMultipe.Of(lcm, x)); Expect(() => result == 232792560); } /// /// Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum. /// [Test] public void Problem06() { var sumOfSquares = 100*101*201/6; // sum(i^2) over [1..n] = ((n)(n+1)(2n+1))/6 var sumOf1to100 = 100*101/2; // sum [1..n] = (n)(n+1)/2 var squareOfSum = sumOf1to100*sumOf1to100; var result = squareOfSum - sumOfSquares; Expect(() => result == 25164150); } /// /// What is the 10,001st prime number? /// [Test] public void Problem07() { var prime = PrimeNumbers.Sequence_MemoryIntensive() .Skip(10000) .First(); Expect(() => prime == 104743); } /// /// Find the greatest product of five consecutive digits in the 1000-digit number. /// [Test] public void Problem08() { // Sliding window approach // If the window contains a 0 we can skip it. 398 of the 995 windows contain a zero. // To reduce the number of comparisons, I will just look at the last element of each window. // If the last element of a window is 0, we can skip 5 windows. var n = ("73167176531330624919225119674426574742355349194934" + "96983520312774506326239578318016984801869478851843" + "85861560789112949495459501737958331952853208805511" + "12540698747158523863050715693290963295227443043557" + "66896648950445244523161731856403098711121722383113" + "62229893423380308135336276614282806444486645238749" + "30358907296290491560440772390713810515859307960866" + "70172427121883998797908792274921901699720888093776" + "65727333001053367881220235421809751254540594752243" + "52584907711670556013604839586446706324415722155397" + "53697817977846174064955149290862569321978468622482" + "83972241375657056057490261407972968652414535100474" + "82166370484403199890008895243450658541227588666881" + "16427171479924442928230863465674813919123162824586" + "17866458359124566529476545682848912883142607690042" + "24219022671055626321111109370544217506941658960408" + "07198403850962455444362981230987879927244284909188" + "84580156166097919133875499200524063689912560717606" + "05886116467109405077541002256983155200055935729725" + "71636269561882670428252483600823257530420752963450") .ToCharArray() .Select(x => x - '0') // Convert ASCII code to int .ToArray(); var max = 0; for (int i = 0; i < 995; i++) { if (n[i + 4] == 0) { i += 4; // Skip 4 + the loop iteration = 5 skipped windows continue; } var product = n[i]*n[i + 1]*n[i + 2]*n[i + 3]*n[i + 4]; if (product > max) { max = product; } } Expect(() => max == 40824); } /// /// There exists exactly one Pythagorean triplet for which a + b + c = 1000. /// Find the product abc. /// [Test] public void Problem09() { // Brute force int a, b, c; for (a = 1; a < 998; a++) { for (b = 1; a + b < 999; b++) { for (c = 1; c < 998; c++) { if (a*a + b*b == c*c && a + b + c == 1000) { goto found; } } } } throw new Exception("Not found"); found: var product = a*b*c; Console.WriteLine(new {a, b, c, product}.ToString()); Expect(() => product == 31875000); } /// /// Find the sum of all the primes below two million. /// [Test] public void Problem10() { long sum = 0; foreach (var prime in PrimeNumbers.Sequence_MemoryIntensive()) { if (prime >= 2000000) break; sum += prime; } Expect(() => sum == 142913828922); } /// /// What is the greatest product of four adjacent numbers in the same direction (up, down, left, right, or diagonally) in the 20×20 grid? /// [Test] public void Problem11() { var matrix = new[] { new []{08, 02, 22, 97, 38, 15, 00, 40, 00, 75, 04, 05, 07, 78, 52, 12, 50, 77, 91, 08}, new []{49, 49, 99, 40, 17, 81, 18, 57, 60, 87, 17, 40, 98, 43, 69, 48, 04, 56, 62, 00}, new []{81, 49, 31, 73, 55, 79, 14, 29, 93, 71, 40, 67, 53, 88, 30, 03, 49, 13, 36, 65}, new []{52, 70, 95, 23, 04, 60, 11, 42, 69, 24, 68, 56, 01, 32, 56, 71, 37, 02, 36, 91}, new []{22, 31, 16, 71, 51, 67, 63, 89, 41, 92, 36, 54, 22, 40, 40, 28, 66, 33, 13, 80}, new []{24, 47, 32, 60, 99, 03, 45, 02, 44, 75, 33, 53, 78, 36, 84, 20, 35, 17, 12, 50}, new []{32, 98, 81, 28, 64, 23, 67, 10, 26, 38, 40, 67, 59, 54, 70, 66, 18, 38, 64, 70}, new []{67, 26, 20, 68, 02, 62, 12, 20, 95, 63, 94, 39, 63, 08, 40, 91, 66, 49, 94, 21}, new []{24, 55, 58, 05, 66, 73, 99, 26, 97, 17, 78, 78, 96, 83, 14, 88, 34, 89, 63, 72}, new []{21, 36, 23, 09, 75, 00, 76, 44, 20, 45, 35, 14, 00, 61, 33, 97, 34, 31, 33, 95}, new []{78, 17, 53, 28, 22, 75, 31, 67, 15, 94, 03, 80, 04, 62, 16, 14, 09, 53, 56, 92}, new []{16, 39, 05, 42, 96, 35, 31, 47, 55, 58, 88, 24, 00, 17, 54, 24, 36, 29, 85, 57}, new []{86, 56, 00, 48, 35, 71, 89, 07, 05, 44, 44, 37, 44, 60, 21, 58, 51, 54, 17, 58}, new []{19, 80, 81, 68, 05, 94, 47, 69, 28, 73, 92, 13, 86, 52, 17, 77, 04, 89, 55, 40}, new []{04, 52, 08, 83, 97, 35, 99, 16, 07, 97, 57, 32, 16, 26, 26, 79, 33, 27, 98, 66}, new []{88, 36, 68, 87, 57, 62, 20, 72, 03, 46, 33, 67, 46, 55, 12, 32, 63, 93, 53, 69}, new []{04, 42, 16, 73, 38, 25, 39, 11, 24, 94, 72, 18, 08, 46, 29, 32, 40, 62, 76, 36}, new []{20, 69, 36, 41, 72, 30, 23, 88, 34, 62, 99, 69, 82, 67, 59, 85, 74, 04, 36, 16}, new []{20, 73, 35, 29, 78, 31, 90, 01, 74, 31, 49, 71, 48, 86, 81, 16, 23, 57, 05, 54}, new []{01, 70, 54, 71, 83, 51, 54, 69, 16, 92, 33, 48, 61, 43, 52, 01, 89, 19, 67, 48} }; var max = 0; Action TestMatches = m => { var product = m[0]*m[1]*m[2]*m[3]; if (product > max) max = product; }; Matrix.HorizontalMatch(matrix, 20, 20, 4, TestMatches); Matrix.VerticalMatch(matrix, 20, 20, 4, TestMatches); Matrix.LeftDiagonalMatch(matrix, 20, 20, 4, TestMatches); Matrix.RightDiagonalMatch(matrix, 20, 20, 4, TestMatches); Expect(() => max == 70600674); } } }