예제 #1
0
        private bool _CollectDupSegments(
            int inDupCount,
            CSegmentPool inSegmentPool,
            int inMaxAllowedDup)
        {
            bool wasSuccessful = true;

            if (inDupCount > 0)
            {
                if (inDupCount <= inMaxAllowedDup)
                {
                    int theMinimalDistance = inSegmentPool.GetMinDist();
                    for (int i = 0, j = 0; i < _mArray.Length - 1 || j < inDupCount; i++)
                    {
                        var theDistance = Math.Abs(_mArray[i + 1]) - Math.Abs(_mArray[i]);
                        if (theDistance == theMinimalDistance && inSegmentPool.GetSegment(0).StartingPoint.Index != i
                            ) // Be careful about the same segment
                        {
                            int      theStartIndex = i, theEndIndex = i + 1;
                            CSegment theSegment = CSegment.Create(_mArray, theStartIndex, ref theEndIndex);
                            inSegmentPool.Add(theSegment);
                            j++;
                        }
                    }
                }
                else
                {
                    wasSuccessful = false;
                }
            }

            return(wasSuccessful);
        }
예제 #2
0
        public CSegmentSquad(
            int[] inArray)
        {
            _mArray = inArray;

            _minialSegmentPool     = new CSegmentPool();
            _subMinimalSegmentPool = new CSegmentPool();

            _minimalResidency    = new SegmentResidency();
            _transientResidency  = new SegmentResidency();
            _subMinimalResidency = new SegmentResidency();
        }
예제 #3
0
        public bool Attack(
            CSegmentPool inSegmentPool)
        {
            bool wasSuccessful = false;

            CPoint theHuntedPoint = inSegmentPool.Injure();

            if (theHuntedPoint != null)
            {
                if (_remainingForAxe <= 0)
                {
                    throw new Exception("The axe can't attack anymore!");
                }

                _remainingForAxe--;
                _pointCage[_pointCageSize++] = theHuntedPoint;
                wasSuccessful = true;
            }

            return(wasSuccessful);
        }
예제 #4
0
        public int Solve(int[] input)
        {
            // Implement your solution here, and return the correct result instead of 0

            int theResult = 0;

            if (input.Length < 5)
            {
                return(0);
            }

            Array.Sort(input);
            foreach (int i in input)
            {
                Console.Write(i + " ");
            }

            CPoint.SetBackingArray(input);
            CSegmentSquad theSegmentSquad = new CSegmentSquad(input);

            for (int i = 0; i < input.Length;)
            {
                bool canRecruit = theSegmentSquad.Recruit(ref i);
            }
            bool isFeasible = theSegmentSquad.FinalizeRecruit();

            if (!isFeasible)
            {
                return(0);
            }

            CAxe theAxe = new CAxe(theSegmentSquad);

            theSegmentSquad.Arm();

            CSegmentPool theMinimals    = theSegmentSquad.GetMinimals();
            CSegmentPool theSubMinimals = theSegmentSquad.GetSubMinimals();
            CSegmentPool thePool        = theMinimals;

            while (theAxe.CanAttack())
            {
                if (!theAxe.Attack(thePool))
                {
                    break;
                }

                if (thePool == theMinimals)
                {
                    if (theSubMinimals.GetMinDist() < thePool.GetMinDist())
                    {
                        thePool = theSubMinimals;
                    }
                }
                else
                {
                    if (theMinimals.GetMinDist() < theSubMinimals.GetMinDist())
                    {
                        thePool = theMinimals;
                    }
                }
            }

            if (theSegmentSquad.Disarmed())
            {
                CPoint[] theCage = theAxe.GetCage();
                foreach (var thePoint in theCage)
                {
                    theResult += Math.Abs(thePoint.Value);
                }
            }

            return(theResult);
        }
예제 #5
0
        public CPoint Injure(
            CSegmentPool inOwningPool,
            int inPoolIdx)
        {
            CPoint thePointToHunt = null, thePointToInfect = null;
            int    whichEndToHunt = 0; // Init to 'no end'. 1: starting, 2: ending

            // Prefere to depart, so first check if there is any touched points?
            // It's NOT good, because we need to look forward and if there is the possiblility
            //      for moving forward, then try to avoid the point, which was shared by the
            //      prev injured segment!!
            // So if we can move forward ? How we can check about this fact?
            //      (use index to see if this is the last point
            //just check the prev segment and
            // NO No NO!!!!
            // We need to introduce a new concept: InfectedPoint
            //  In a segment, when we haunt an end_point then the other point is 'Infected'
            //      and when we are checking for touch_points, then we choose them only if
            //      it is NOT infected
            if (StartingPoint.IsTouched() && !StartingPoint.IsInfected())
            {
                thePointToHunt   = StartingPoint;
                thePointToInfect = EndingPoint;
                whichEndToHunt   = 1;
            }
            else if (EndingPoint.IsTouched())
            {
                thePointToHunt   = EndingPoint;
                whichEndToHunt   = 2;
                thePointToInfect = StartingPoint;
            }
            else
            {
                // Do the wounding process
                // Look at the neighbors:
                NeighborDistances(out var theStartPrevDist, out var theEndNextDist);
                if (theStartPrevDist == theEndNextDist)
                {
                    // Since the points are sorted, so the starting_point < ending (always!)
                    thePointToHunt   = StartingPoint;
                    whichEndToHunt   = 1;
                    thePointToInfect = EndingPoint;
                }
                else if (theStartPrevDist < theEndNextDist)
                {
                    thePointToHunt   = EndingPoint;
                    whichEndToHunt   = 2;
                    thePointToInfect = StartingPoint;
                }
                else // theStartPrevDist > theEndNextDist
                {
                    thePointToHunt   = StartingPoint;
                    whichEndToHunt   = 1;
                    thePointToInfect = EndingPoint;
                }
            }

            thePointToHunt?.Hunt();
            thePointToInfect?.Infect();

            // Now recalculate the distance, considering the hunted point
            // But what if all two points was haunted?! Hey: The Distance = PrevDist + ThisDist + NextDist
            // Determine the most recently hunted point and then add its relevant neighbor to the distance

            switch (whichEndToHunt)
            {
            case 1:
                _distance         += StartingPoint.PrevDistance();
                _injuryRegistry[0] = true;
                break;


            case 2:
                _distance         += EndingPoint.NextDistance();
                _injuryRegistry[1] = true;
                break;
            }


            return(thePointToHunt);
        }