internal PartialSumsData(int maxSum) { FoundData = new HashSet <int>(); Datas = new BestSumsData(); Minuniques = int.MaxValue; SumsCount = -1; Created = 0; Sums = null; Storage = new BitArrayStorage(maxSum); }
private static bool CreateAllSumsDatas(Span <int> numbers, BitArraySlim currSums, PartialSumsData data) { if (numbers.Length > 1) { int midPoint = numbers.Length / 2; Span <int> firstPart = numbers.Slice(0, midPoint); Span <int> secondPart = numbers.Slice(midPoint); BitArraySlim secondPartSums = CreatePartialSums(secondPart, currSums, data); if (!CreateAllSumsDatas(firstPart, secondPartSums, data)) { data.Storage.Push(secondPartSums); } BitArraySlim firstPartSums = CreatePartialSums(firstPart, currSums, data); if (!CreateAllSumsDatas(secondPart, firstPartSums, data)) { data.Storage.Push(firstPartSums); } } else { data.Created++; int actualSumCount = BoolArrayTrueCount(currSums); if (data.SumsCount - actualSumCount > data.Minuniques) { return(false); } int number = numbers[0]; if (!data.FoundData.Contains(number)) { BestSumsData newData = new BestSumsData(number, FinishCreateSumsData(number, currSums, actualSumCount, data)); data.Minuniques = Math.Min(data.Minuniques, data.Datas.Data.Uniques); if (newData.Data.Uniques < data.Datas.Data.Uniques || (newData.Data.Uniques == data.Datas.Data.Uniques && newData.Number < data.Datas.Number)) { if (data.Datas.Data.BitArray != null) { data.Storage.Push(data.Datas.Data.BitArray); } data.Datas = newData; return(true); } } } return(false); }
private static (int number, int newNumber) CreateCollisionAvoidanceArray(BitArraySlim sums, BestSumsData bestData, PartialSumsData data) { SumsData sumData = bestData.Data.ToSumsData(bestData.Number, data.SumsCount); foreach (var unique in sumData.Uniques) { sums.ForceSet(unique, 0); } for (int i = 1; i <= sums.Length;) { bool foundObstacle = false; foreach (var newSum in sumData.NewSums) { int overlapIndex = newSum - (bestData.Number - i); int offset = 0; while (overlapIndex + offset < sums.Length && sums[overlapIndex + offset] == 1) { offset++; } i += offset; if (offset > 0) { foundObstacle = true; break; } } if (!foundObstacle) { return(bestData.Number, i); } } throw new Exception("impossible!.... i thought"); }