Last active
December 24, 2015 09:49
-
-
Save RichardVasquez/6780214 to your computer and use it in GitHub Desktop.
WAY overdoing Euler Project Problem 1. It was fun, though.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.Linq; | |
namespace OverOiled01 | |
{ | |
/// <summary> | |
/// WAY overdoing Euler Project Problem 1. | |
/// | |
/// It was fun, though. | |
/// </summary> | |
class Program | |
{ | |
/// <summary> | |
/// The highest number to consider in finding our sum. | |
/// </summary> | |
private const long Max = 999; | |
/// <summary> | |
/// The first number we need to find the multiples of. | |
/// </summary> | |
private const int Factor1 = 3; | |
/// <summary> | |
/// The second number we need to find multiples of. | |
/// </summary> | |
private const int Factor2 = 5; | |
/// <summary> | |
/// The number that is the product of <see cref="Factor1"/> amd <see cref="Factor2"/> | |
/// </summary> | |
private const int Factor3 = Factor1 * Factor2; | |
/// <summary> | |
/// A formatting string that will create a dynamic formatting string in <see cref="MakeOutput"/> | |
/// </summary> | |
private const string PreFormat = "{{3,{0}}}: {{0:N0}}\t{{1,8:N0}} ticks\t{{2,15}} ns"; | |
/// <summary> | |
/// A measuring value that shows closely the accuracy of a <see cref="Stopwatch.Frequency"/> in terms of nanoseconds. | |
/// </summary> | |
private static readonly double Nanos = (1000 * 1000 * 1000) / (double)Stopwatch.Frequency; | |
static void Main(string[] args) | |
{ | |
WriteOutput | |
( | |
new List<Tracker> {ProcessElegance(), ProcessFunction(), ProcessLinq(), ProcessBruteForce()} | |
.OrderBy(tr => tr.Duration.Ticks) | |
.ToList() | |
); | |
Console.ReadLine(); | |
} | |
#region Output methods | |
/// <summary> | |
/// Presents the results of all the time measuring methods. | |
/// </summary> | |
private static void WriteOutput(IEnumerable<Tracker> ltr) | |
{ | |
var trackers = ltr as Tracker[] ?? ltr.ToArray(); | |
int maxLen = trackers.Select(tracker => tracker.Name.Length).Concat(new[] {0}).Max(); | |
foreach (Tracker tracker in trackers) | |
{ | |
Console.WriteLine(MakeOutput(maxLen, tracker.Name, tracker.Result, tracker.Duration)); | |
} | |
Console.WriteLine(); | |
Console.WriteLine("Frequency: {0:n0} ticks per second.", Stopwatch.Frequency); | |
Console.WriteLine("Frequency: ~{0:n3} ns per tick.", Nanos); | |
} | |
/// <summary> | |
/// Creates the output line used to present the measurements of a specific tracking mechanism. | |
/// </summary> | |
private static string MakeOutput(int maxLen, string name, long total, TimeSpan ts) | |
{ | |
string format = string.Format(PreFormat, maxLen); | |
return string.Format | |
( | |
format, | |
total, ts.Ticks, (ts.Ticks * Nanos).ToString("N3"), name | |
); | |
} | |
#endregion | |
#region Various calculation methods | |
/// <summary> | |
/// The quickest way so far that I know of to solve this. | |
/// | |
/// Find the multiples of 3, find the multiples of 5, find the multiples of 15. | |
/// Use n*(n+1) to get the triangle number. | |
/// Add 3s and 5s. Subtract 15s since they've already been counted twice. | |
/// </summary> | |
private static Tracker ProcessElegance() | |
{ | |
Stopwatch sw = new Stopwatch(); | |
sw.Start(); | |
const long nFactor1 = (((Max / Factor1) * (Max / Factor1) + (Max / Factor1)) / 2) * Factor1; | |
const long nFactor2 = (((Max / Factor2) * (Max / Factor2) + (Max / Factor2)) / 2) * Factor2; | |
const long nFactor3 = (((Max / Factor3) * (Max / Factor3) + (Max / Factor3)) / 2) * Factor3; | |
const long total = nFactor1 + nFactor2 - nFactor3; | |
sw.Stop(); | |
return new Tracker(sw.Elapsed, total, "Elegance"); | |
} | |
/// <summary> | |
/// Abstract one of the aspects of <see cref="ProcessElegance()"/> | |
/// via a function that returns the same results. | |
/// </summary> | |
private static Tracker ProcessFunction() | |
{ | |
Stopwatch sw = new Stopwatch(); | |
sw.Start(); | |
long res = GetSum(Max, Factor1) + GetSum(Max, Factor2) - GetSum(Max, Factor3); | |
sw.Stop(); | |
return new Tracker(sw.Elapsed, res, "Call Function"); | |
} | |
/// <summary> | |
/// Takes the sum of all numbers up to max that are evenly divisable by mod. | |
/// </summary> | |
/// <param name="max">Maximum number to consider. (Inclusive)</param> | |
/// <param name="mod">Number to find multiples of in sequence.</param> | |
private static long GetSum(long max, long mod) | |
{ | |
return ((((max / mod) * (max / mod)) + (max / mod)) / 2) * mod; | |
} | |
/// <summary> | |
/// The LINQ answer to the problem. It's a little easier to have LINQ wander off the deep end | |
/// with larger values of <see cref="Max"/>, so this was thrown into a try/catch block | |
/// </summary> | |
private static Tracker ProcessLinq() | |
{ | |
Stopwatch sw = new Stopwatch(); | |
long e2 = 0; | |
try | |
{ | |
sw.Start(); | |
e2 = Enumerable.Range(1, (int)Max).Sum(i => (i % Factor1 == 0 || i % Factor2 == 0) ? i : 0); | |
} | |
catch (OverflowException) | |
{ | |
Console.WriteLine("Overflow Exception"); | |
} | |
finally | |
{ | |
sw.Stop(); | |
} | |
return new Tracker(sw.Elapsed, e2, "LINQ"); | |
} | |
/// <summary> | |
/// The brute force method counting from 1 to Max and adding it all up. | |
/// </summary> | |
private static Tracker ProcessBruteForce() | |
{ | |
Stopwatch sw = new Stopwatch(); | |
long sum = 0; | |
sw.Start(); | |
for (int i = 0; i <= Max; i++) | |
{ | |
if (i % Factor1 == 0 || i % Factor2 == 0) | |
{ | |
sum += i; | |
} | |
} | |
sw.Stop(); | |
return new Tracker(sw.Elapsed, sum, "Brute Force"); | |
} | |
#endregion | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
namespace OverOiled01 | |
{ | |
/// <summary> | |
/// Stores results of a specific calculation, the provided | |
/// name of the calculation, and the resulting time. | |
/// </summary> | |
public struct Tracker | |
{ | |
public Tracker(TimeSpan duration, long result, string name) | |
: this() | |
{ | |
Name = name; | |
Result = result; | |
Duration = duration; | |
} | |
/// <summary> | |
/// Results of <see cref="System.Diagnostics.Stopwatch.Elapsed"/> | |
/// value after performing calculations. | |
/// </summary> | |
public TimeSpan Duration { get; private set; } | |
/// <summary> | |
/// Actual calculation result. | |
/// </summary> | |
public long Result{ get; private set; } | |
/// <summary> | |
/// Name of calculation method. | |
/// </summary> | |
public string Name { get; private set; } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment