protected override void Solve(out string answer) { answer = $"Solution not created yet..."; StringBuilder progress = new StringBuilder("Composites checked: "); CompositeSolver compositeSolver = new CompositeSolver(); List <long> oddComposites = new List <long>(); //Pseudo code foreach (long candidate in Enumerable64.Range(1, 34000)) { if (compositeSolver.IsOddComposite(candidate)) { oddComposites.Add(candidate); if (compositeSolver.IsSumOfPrimeAndTwiceSquare(candidate)) { progress.Append($"{candidate}, "); //UpdateProgress(progress.ToString()); } else { answer = $"The smallest odd composite that cannot be written as the sum of a prime and twice a square is: {candidate}."; return; } } } }
/// <summary>Thread1: Makes sure that queue is filled with at least 100 units of computation</summary> private void InputGenerator() { var inputMax = 30000; //Desired input queue size var inputThreshold = inputMax * 0.8; //Minimum before we should refill while (ThreadContinueFlag) { int newBatches = 0; if (inputBatches.Count < inputThreshold) //If length of input queue is shorter than target, populate it to 3000 { foreach (int i in Enumerable.Range(1, inputMax - inputBatches.Count)) { var tnew = Enumerable64.Range(bigInteger, batchSize); bigInteger += batchSize; lock (Locker) { inputBatches.Enqueue(tnew); newBatches++; } } AddStatusThreadsafe($"Input thread added {newBatches} new batches."); } Task.Delay(TimeSpan.FromSeconds(10)).Wait(); } AddStatusThreadsafe($"Input task finished."); }
private void GenerateNumbers(long min, long max, Dictionary <long, long> triangleNumbers, Dictionary <long, long> pentagonalNumbers, Dictionary <long, long> hexagonalNumbers) { foreach (long n in Enumerable64.Range(min, max - min)) { triangleNumbers.Add(n, n * (n + 1) / 2); pentagonalNumbers.Add(n, n * (3 * n - 1) / 2); hexagonalNumbers.Add(n, n * (2 * n - 1)); } }
/// <summary> /// Computes and returns the list of all primes which are smaller than the <paramref name="upperBound"/>. /// </summary> /// <param name="upperBound"></param> /// <returns>List of primes</returns> public List <long> GetPrimesSmallerThan(long upperBound) { List <long> retVal = new List <long>(); foreach (int candidate in Enumerable64.Range(1, upperBound)) { if (IsPrime(candidate)) { retVal.Add(candidate); } } return(retVal); }
protected override void Solve(out string answer) { PentagonManager pentagonManager = new PentagonManager(); //Generate numbers up to 5000 long maxCount = 5000; foreach (long j in Enumerable64.Range(1, maxCount)) { PentagonNumber pj = new PentagonNumber(j); pentagonManager.Add(pj); } long count = maxCount * maxCount; long progressDone = 0; //Create all pairs 5000x5000 Parallelization.GetParallelRanges(1, maxCount, 50).ForAll(sequence => { foreach (long j in sequence) { foreach (long k in Enumerable64.Range(1, maxCount)) { PentagonPair pjk = pentagonManager.CreatePair(j, k); if (pentagonManager.IsSumPentagonal(pjk)) { if (pentagonManager.IsDifPentagonal(pjk)) { lock (pentagonManager) { pentagonManager.StorePair(pjk); } } } lock (this) { progressDone++; if (progressDone % 100_000 == 0) { int percent = (int)(progressDone * 100.0 / count); UpdateProgress($"Pairs checked out of {count}: Done {percent}%. Hits: {pentagonManager.storedPairs.Count}..."); } } } } }); var solution = pentagonManager.storedPairs.OrderBy(pair => pair.AbsDifValue).First(); answer = $"Candiates = {pentagonManager.storedPairs.Count}, D = {solution.AbsDifValue}."; }
/// <summary> /// Checks if candidate can be expressed as [n = p + 2 * a^2], where n is <paramref name="candidate"/>, p is some prime and 'a' is an integer. /// </summary> /// <param name="candidate"></param> /// <returns>Returns true if it can be expressed as p + 2 * a^2. False otherwise.</returns> internal bool IsSumOfPrimeAndTwiceSquare(long candidate) { var primes = primeSolver.GetPrimesSmallerThan(candidate); foreach (var prime in primes) { foreach (long a in Enumerable64.Range(1, candidate / 2)) { var twiceASquared = 2 * a * a; if (candidate == prime + twiceASquared) { return(true); } } } return(false); }
/// <summary> /// Long (Int64) version. /// Gets a list of sub-ranges that can be used in parallel loop to iterate over whole range. /// Typical use: Call .ForAll() delegate on the returned query to distribute work on multiple processors. /// </summary> /// <param name="start">The value of the first long in this sequence.</param> /// <param name="count">The number of sequential long to generate.</param> /// <param name="partitions">The number of partitions (sub-ranges) into which to divide the whole range produced.</param> public static ParallelQuery <IEnumerable <long> > GetParallelRanges(long start, long count, int partitions) { List <IEnumerable <long> > enumerables = new List <IEnumerable <long> >(); long partitionSize = (count + 1) / partitions; //Handle odd counts properly #region Hadle case when partitions is larget than count //In this case you have to ensure partition size must be at least 1 partitionSize = Math.Max(partitionSize, 1); #endregion long end = count + start; for (long pos = start, range = partitionSize; pos < end; pos += partitionSize) { if ((pos + range) > end) //Make sure the last partition is capped to ensure proper total count { range = end - pos; } var item = Enumerable64.Range(pos, range); enumerables.Add(item); } var parallels = enumerables.AsParallel(); return(parallels); }