diff --git a/algorithm-exercises-csharp/src/hackerrank/projecteuler/Euler003.Test.cs b/algorithm-exercises-csharp/src/hackerrank/projecteuler/Euler003.Test.cs new file mode 100644 index 0000000..ce5a5f2 --- /dev/null +++ b/algorithm-exercises-csharp/src/hackerrank/projecteuler/Euler003.Test.cs @@ -0,0 +1,33 @@ +// @link Problem definition [[docs/hackerrank/projecteuler/euler003.md]] +// Notes about final solution please see: +// @link [[docs/hackerrank/projecteuler/euler003-solution-notes.md]] + + +namespace algorithm_exercises_csharp.hackerrank.prohecteuler; + +[TestClass] +public class Euler003Test +{ + public class Euler003TestCase { + public int n; public int? answer; + } + + // dotnet_style_readonly_field = true + private static readonly Euler003TestCase[] tests = [ + new() { n = 1, answer = null}, + new() { n = 10, answer = 5}, + new() { n = 17, answer = 17} + ]; + + [TestMethod] + public void Euler003ProblemTest() + { + int? result; + + foreach (Euler003TestCase test in tests) { + result = Euler003Problem.Euler003(test.n); + Assert.AreEqual(test.answer, result); + } + } +} + diff --git a/algorithm-exercises-csharp/src/hackerrank/projecteuler/Euler003.cs b/algorithm-exercises-csharp/src/hackerrank/projecteuler/Euler003.cs new file mode 100644 index 0000000..884a2e2 --- /dev/null +++ b/algorithm-exercises-csharp/src/hackerrank/projecteuler/Euler003.cs @@ -0,0 +1,42 @@ +// @link Problem definition [[docs/hackerrank/projecteuler/euler003.md]] + +namespace algorithm_exercises_csharp.hackerrank.prohecteuler; + +using System.Diagnostics.CodeAnalysis; + +public class Euler003Problem +{ + [ExcludeFromCodeCoverage] + protected Euler003Problem() {} + + public static int? PrimeFactor(int n) { + if (n < 2) { + return null; + } + + int divisor = n; + int? max_prime_factor = null; + + int i = 2; + while (i <= Math.Sqrt(divisor)) { + if (0 == divisor % i) { + divisor = divisor / i; + max_prime_factor = divisor; + } else { + i += 1; + } + } + + if (max_prime_factor is null) { + return n; + } + + return max_prime_factor; + } + + // Function to find the sum of all multiples of a and b below n + public static int? Euler003(int n) + { + return PrimeFactor(n); + } +} diff --git a/docs/hackerrank/projecteuler/euler003-solution-notes.md b/docs/hackerrank/projecteuler/euler003-solution-notes.md new file mode 100644 index 0000000..24828ec --- /dev/null +++ b/docs/hackerrank/projecteuler/euler003-solution-notes.md @@ -0,0 +1,63 @@ +# About the **Largest prime factor** solution + +## Brute force method + +> [!WARNING] +> +> The penalty of this method is that it requires a large number of iterations as +> the number grows. + +The first solution, using the algorithm taught in school, is: + +> Start by choosing a number $ i $ starting with $ 2 $ (the smallest prime number) +> Test the divisibility of the number $ n $ by $ i $, next for each one: +> +>> - If $ n $ is divisible by $ i $, then the result is +>> the new number $ n $ is reduced, while at the same time +>> the largest number $i$ found is stored. +>> +>> - If $ n $ IS NOT divisible by $ i $, $i$ is incremented by 1 +> up to $ n $. +> +> Finally: +>> +>> - If you reach the end without finding any, it is because the number $n$ +>> is prime and would be the only factual prime it has. +>> +>> - Otherwise, then the largest number $i$ found would be the largest prime factor. + +## Second approach, limiting to half iterations + +> [!CAUTION] +> +> Using some test entries, quickly broke the solution at all. So, don't use it. +> This note is just to record the failed idea. + +Since by going through and proving the divisibility of a number $ i $ up to $ n $ +there are also "remainder" numbers that are also divisible by their opposite, +let's call it $ j $. + +At first it seemed attractive to test numbers $ i $ up to half of $ n $ then +test whether $ i $ or $ j $ are prime. 2 problems arise: + +- Testing whether a number is prime could involve increasing the number of +iterations since now the problem would become O(N^2) complex in the worst cases + +- Discarding all $ j $ could mean discarding the correct solution. + +Both problems were detected when using different sets of test inputs. + +## Final solution using some optimization + +> [!WARNING] +> +> No source was found with a mathematical proof proving that the highest prime +> factor of a number n (non-prime) always lies under the limit of $ \sqrt{n} $ + +A solution apparently accepted in the community as an optimization of the first +brute force algorithm consists of limiting the search to $ \sqrt{n} $. + +Apparently it is a mathematical conjecture without proof +(if it exists, please send it to me). + +Found the correct result in all test cases. diff --git a/docs/hackerrank/projecteuler/euler003.md b/docs/hackerrank/projecteuler/euler003.md new file mode 100644 index 0000000..af878d6 --- /dev/null +++ b/docs/hackerrank/projecteuler/euler003.md @@ -0,0 +1,43 @@ +# [Largest prime factor](https://www.hackerrank.com/contests/projecteuler/challenges/euler003) + +- Difficulty: #easy +- Category: #ProjectEuler+ + +The prime factors of $ 13195 $ are $ 5 $, $ 7 $, $ 13 $ and $ 29 $. + +What is the largest prime factor of a given number $ N $ ? + +## Input Format + +First line contains $ T $, the number of test cases. This is +followed by $ T $ lines each containing an integer $ N $. + +## Constraints + +- $ 1 \leq T \leq 10 $ +- $ 10 \leq N \leq 10^{12} $ + +## Output Format + +Print the required answer for each test case. + +## Sample Input 0 + +```text +2 +10 +17 +``` + +## Sample Output 0 + +```text +5 +17 +``` + +## Explanation 0 + +- Prime factors of $ 10 $ are $ {2, 5} $, largest is $ 5 $. + +- Prime factor of $ 17 $ is $ 17 $ itselft, hence largest is $ 17 $.