public static (int number, int newNumber) Solve(int[] numbers) { Array.Sort(numbers); int maxSum = 0; for (int i = 0; i < numbers.Length; i++) { maxSum += numbers[i]; } PartialSumsData data = new PartialSumsData(maxSum); BitArraySlim currSums = new BitArraySlim(1); currSums.ForceSet(0, 1); CreateAllSumsDatas(numbers, currSums, data); return(CreateCollisionAvoidanceArray(data.Sums, data.Datas, data)); }
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"); }