using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; public class Test { class Program { public static Mutex mux = new Mutex(); static void Main(string[] args) { int number = 10000000; //int number = 10000; //int number = 100; var sw = Stopwatch.StartNew(); int testIterations = 100; //int testIterations = 100000; //int testIterations = 1000000; int testCount = 0; while (testCount++ < testIterations) { //parallel(number); //parallelNoList(number); //notParallel(number); //opSolution2(number); //counting(number); //multiPersonalize(number); //multi(number, new[] { 3, 5 }); //multiPersonalizeEnhanted(number); //multiEnhanted(number, new[] { 3, 5 }); unrolled(number); } sw.Stop(); Console.Write("Elapsed " + sw.ElapsedMilliseconds / testCount + "ms"); //avr //Console.Write("Elapsed " + sw.ElapsedMilliseconds + "ms"); //total Console.ReadKey(); } static List parallel(int limit) //434ms, 85447ms , 348600ms { return Enumerable.Range(0, limit+1).AsParallel().Where(n => n % 3 == 0 || n % 5 == 0).OrderBy(x => x).ToList(); } static List parallelEnhanted(int limit) { List finalResult = new List(); var result = Enumerable.Range(0, limit + 1).AsParallel().Where(n => n % 3 == 0 || n % 5 == 0).OrderBy(x => x); result.ForAll(x => { //mux.WaitOne(); finalResult.Add(x); //mux.ReleaseMutex(); }); return finalResult; } static void parallelNoList(int limit) //136ms, 51266ms, 273409ms { Enumerable.Range(0, limit+1).AsParallel().Where(n => n % 3 == 0 || n % 5 == 0).OrderBy(x => x).ForAll(x => { }); } static List notParallel(int number) //154ms, 14559ms, 1985ms { return Enumerable.Range(0, number+1).Where(n => n % 3 == 0 || n % 5 == 0).ToList(); } static List opSolution2(int number) //69ms, 5791ms, 879ms { List list = new List(); for (var i = 0; i <= number; i++) { if (i % 3 == 0 || i % 5 == 0) { list.Add(i); } } return list; } static List counting(int number) //34ms, 2398ms, 521ms { List list = new List { 0 }; int count3 = 0; int count5 = 0; int step3 = 3; int step5 = 5; while (count3 < number || count5 < number) { if ((count3 + step3) <= (count5 + step5)) { count3 += step3; if(count3 == (count5 + step5)) count5 += step5; if (count3 <= number) { list.Add(count3); } } else { count5 += step5; if (count5 <= number) { list.Add(count5); } } } return list; } static List unrolled(int max) //32ms, 2072ms, 464ms { List result = new List { 0 }; int i = 0; while (true) { i += 3; if (i > max) break; result.Add(i); i += 2; if (i > max) break; result.Add(i); i += 1; if (i > max) break; result.Add(i); i += 3; if (i > max) break; result.Add(i); i += 1; if (i > max) break; result.Add(i); i += 2; if (i > max) break; result.Add(i); i += 3; if (i > max) break; result.Add(i); } return result; } static List multiPersonalizeEnhanted(int max) //37ms, 2655ms, 501ms { int[] deltas = { 3, 2, 1, 3, 1, 2, 3 }; List result = new List { 0 }; int i = 0; do { foreach (int delta in deltas) { i += delta; if (i > max) break; result.Add(i); } } while (i < max); return result; } static List multiPersonalize(int max) //43ms, 3498ms, 654ms { int[] deltas = { 3, 2, 1, 3, 1, 2, 3 }; List result = new List(); int j = 0; for (int i = 0; i <= max; i += deltas[j++ % deltas.Length]) { result.Add(i); } return result; } static List multiEnhanted(int max, int[] divs) //37ms, 2701ms, 1149ms { int[] deltas = calcDeltas(divs); List result = new List { 0 }; int i = 0; do { foreach (int delta in deltas) { i += delta; if (i > max) break; result.Add(i); } } while (i < max); return result; } static List multi(int max, int[] divs) //47ms, 3529ms, 1270ms { int[] deltas = calcDeltas(divs); List result = new List(); int j = 0; for (int i = 0; i <= max; i += deltas[j++ % deltas.Length]) { result.Add(i); } return result; } static int[] calcDeltas(int[] divs) { long max = 1; foreach (int div in divs) max = lcm(max, div); List ret = new List(); foreach (int div in divs) { for (int i = div; i <= max; i += div) { int idx = ret.BinarySearch(i); if (idx < 0) { ret.Insert(~idx, i); } } } for (int i = ret.Count - 1; i > 0; i--) ret[i] -= ret[i - 1]; return ret.ConvertAll(x => (int)x).ToArray(); } static long gcf(long a, long b) { while (b != 0) { long temp = b; b = a % b; a = temp; } return a; } static long lcm(long a, long b) { return (a / gcf(a, b)) * b; } } }