예제 #1
0
 internal PartialSumsData(int maxSum)
 {
     FoundData  = new HashSet <int>();
     Datas      = new BestSumsData();
     Minuniques = int.MaxValue;
     SumsCount  = -1;
     Created    = 0;
     Sums       = null;
     Storage    = new BitArrayStorage(maxSum);
 }
예제 #2
0
        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);
        }
예제 #3
0
        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");
        }