diff --git a/ProjectEulerCS/ProblemSelection.cs b/ProjectEulerCS/ProblemSelection.cs index 88fef99..dc722f8 100644 --- a/ProjectEulerCS/ProblemSelection.cs +++ b/ProjectEulerCS/ProblemSelection.cs @@ -32,7 +32,7 @@ namespace ProjectEulerCS{ private static readonly List _PROBLEM_NUMBERS = new List() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 67}; + 20, 21, 67}; public static System.Collections.Generic.List PROBLEM_NUMBERS{ get { return _PROBLEM_NUMBERS; } } @@ -61,6 +61,7 @@ namespace ProjectEulerCS{ case 18: problem = new Problem18(); break; case 19: problem = new Problem19(); break; case 20: problem = new Problem20(); break; + case 21: problem = new Problem21(); break; case 67: problem = new Problem67(); break; } return problem; diff --git a/ProjectEulerCS/Problems/Problem20.cs b/ProjectEulerCS/Problems/Problem20.cs index 59b148a..70d310e 100644 --- a/ProjectEulerCS/Problems/Problem20.cs +++ b/ProjectEulerCS/Problems/Problem20.cs @@ -1,4 +1,4 @@ -//ProjectEuler/ProjectEulerCS/src/Problems/Problem19.cs +//ProjectEuler/ProjectEulerCS/src/Problems/Problem20.cs //Matthew Ellison // Created: 08-27-20 //Modified: 08-27-20 diff --git a/ProjectEulerCS/Problems/Problem21.cs b/ProjectEulerCS/Problems/Problem21.cs new file mode 100644 index 0000000..e9c8213 --- /dev/null +++ b/ProjectEulerCS/Problems/Problem21.cs @@ -0,0 +1,151 @@ +//ProjectEuler/ProjectEulerCS/src/Problems/Problem21.cs +//Matthew Ellison +// Created: 09-02-20 +//Modified: 09-02-20 +//Evaluate the sum of all the amicable numbers under 10000 +//Unless otherwise listed all non-standard includes are my own creation and available from https://bibucket.org/Mattrixwv/CSClasses +/* + Copyright (C) 2020 Matthew Ellison + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + + +using System.Collections.Generic; + + +namespace ProjectEulerCS.Problems{ + public class Problem21 : Problem{ + //Variables + //Static variables + private const int LIMIT = 10000; //The number that is > the largest number to be checked + //Instance variables + private List divisorSum; //Holds the sum of the divisors of the subscript number + private List amicable; //Holds all amicable numbers + public List Amicable{ + get{ + if(!solved){ + throw new Unsolved(); + } + return amicable; + } + } + public int Sum{ + get{ + if(!solved){ + throw new Unsolved(); + } + return mee.Algorithms.GetSum(amicable); + } + } + public override string Result{ + get{ + if(!solved){ + throw new Unsolved(); + } + string result = $"All amicable numebrs less than {LIMIT} are\n"; + foreach (int num in amicable){ + result += $"{num}\n"; + } + result += $"The sum of all of these amicable numbers is {Sum}"; + return result; + } + } + + //Functions + //Constructor + public Problem21() : base($"Evaluate the sum of all the amicable numbers under {LIMIT}"){ + divisorSum = new List(); + amicable = new List(); + reserveArray(); + } + //Operational functions + //Reserve the size of the array to speed up insertion + private void reserveArray(){ + divisorSum.Capacity = LIMIT; //Reserving it now makes it faster later + //Make sure the list is filled with 0's + while(divisorSum.Count < LIMIT){ + divisorSum.Add(0); + } + } + //Solve the problem + public override void Solve(){ + //If the problem has already been solved do nothing and end the function + if(solved){ + return; + } + + //Start the timer + timer.Start(); + + //Generate the divisors of all numbers < 10000, get their sum, and add it to the list + for(int cnt = 1;cnt < LIMIT;++cnt){ + List divisors = mee.Algorithms.GetDivisors(cnt); //Get all the divisors of a number + if(divisors.Count > 1){ + divisors.Remove(divisors[^1]); //Remove the last entry because it will be the number itself + } + divisorSum[cnt] = mee.Algorithms.GetSum(divisors); //Add the sum of the divisors of the vector + } + //Check every sum of divisors in the list for a matching sum + for(int cnt = 1;cnt < divisorSum.Count;++cnt){ + int sum = divisorSum[cnt]; + //If the sum is greater than the number of divisors then it is impossible to be amicable. Skip the number and continue + if(sum >= divisorSum.Count){ + continue; + } + //We know that divisorSum.at(cnt) == sum, so if divisorSum.at(sum) == cnt we found an amicable number + if(divisorSum[sum] == cnt){ + //A number can't be amicable with itself + if(sum == cnt){ + continue; + } + //Add it to the list of amicable numbers + amicable.Add(cnt); + } + } + + //Sort the list for neatness + amicable.Sort(); + + //Stop the timer + timer.Stop(); + + //Throw a flag to show the problem is solved + solved = true; + } + //Reset the problem so it can be run again + public override void Reset(){ + base.Reset(); + divisorSum.Clear(); + amicable.Clear(); + reserveArray(); + } + } +} + +/* Results: +All amicable numebrs less than 10000 are +220 +284 +1184 +1210 +2620 +2924 +5020 +5564 +6232 +6368 +The sum of all of these amicable numbers is 31626 +It took an average of 5.076 milliseconds to run this problem through 100 iterations +*/