Beispiel #1
0
        internal CaseOutput Solve()
        {
            var weightsPerExercise      = input.ExerciseWeightCounts.Select(ex => ex.Sum()).ToArray();
            var exerciseWeightPositions = weightsPerExercise.Select(count => Enumerable.Repeat((long)-1, (int)count).ToArray()).ToArray();
            var mid = new CaseMidpoint
            {
                Exercises                          = input.Exercises,
                MaxWeight                          = input.MaxWeight,
                WeightsPerExercise                 = weightsPerExercise,
                ExerciseWeightPositions            = exerciseWeightPositions,
                ExerciseStackLockPointInbound      = new long[input.Exercises],
                ExerciseInboundLockedStackContents = new long[input.Exercises][]
            };

            var isFirstLoop = true;

            for (long ex = mid.Exercises - 1; ex >= 1; ex--)
            {
                var thisExWeightCounts = input.ExerciseWeightCounts[ex];
                var prevExWeightCounts = input.ExerciseWeightCounts[ex - 1];
                var outboundLockPoint  = isFirstLoop ? mid.WeightsPerExercise[ex] : mid.ExerciseStackLockPointInbound[ex + 1];
                //var thisExFlexibleWeights = 0;
                var minWeightsCounts = Enumerable.Zip(thisExWeightCounts, prevExWeightCounts, Math.Min).ToArray();
                var lockPoint        = minWeightsCounts.Sum() - 1;

                var inboundUnlockedWeightCounts      = Enumerable.Zip(prevExWeightCounts, minWeightsCounts, (prev, min) => prev - min).ToArray();
                var inboundUnlockedWeightsTotalCount = inboundUnlockedWeightCounts.Sum();
                if (lockPoint + 1 + inboundUnlockedWeightsTotalCount != mid.WeightsPerExercise[ex - 1])
                {
                    Thrower.TriggerMemLimit();
                }

                var outboundUnlockedWeightCounts      = Enumerable.Zip(thisExWeightCounts, minWeightsCounts, (th, min) => th - min).ToArray();
                var outboundUnlockedWeightsTotalCount = outboundUnlockedWeightCounts.Sum();
                if (lockPoint + 1 + outboundUnlockedWeightsTotalCount != mid.WeightsPerExercise[ex])
                {
                    Thrower.TriggerMemLimit();
                }

                var inboundUnlockedWeightPositions  = inboundUnlockedWeightCounts.SelectMany((count, index) => Enumerable.Repeat(index, (int)count)).ToArray();
                var outboundUnlockedWeightPositions = outboundUnlockedWeightCounts.SelectMany((count, index) => Enumerable.Repeat(index, (int)count)).ToArray();

                mid.ExerciseStackLockPointInbound[ex]      = lockPoint;
                mid.ExerciseInboundLockedStackContents[ex] = minWeightsCounts;

                for (int i = 0; i < inboundUnlockedWeightsTotalCount; i++)
                {
                    mid.ExerciseWeightPositions[ex - 1][lockPoint + 1 + i] = inboundUnlockedWeightPositions[i];
                }
                mid.ExerciseInboundLockedStackContents[ex] = minWeightsCounts;

                isFirstLoop = false;
            }

            return(OutputFromMidPoint(mid));
        }
Beispiel #2
0
        internal CaseOutput OutputFromMidPoint(CaseMidpoint solution)
        {
            solution.ExerciseStackLockPointInbound[0] = -1;

            for (int ex = 0; ex < solution.Exercises - 1; ex++)
            {
                var thisEx = solution.ExerciseWeightPositions[ex];
                var nextEx = solution.ExerciseWeightPositions[ex + 1];

                var minLength = Math.Min(thisEx.LongLength, nextEx.LongLength);

                var calculatedLockPoint = minLength - 1;
                for (int i = 0; i < minLength; i++)
                {
                    if (thisEx[i] != nextEx[i])
                    {
                        calculatedLockPoint = i - 1;
                        break;
                    }
                }

                if (calculatedLockPoint != solution.ExerciseStackLockPointInbound[ex + 1])
                {
                    Thrower.TriggerMemLimit();
                }

                //solution.ExerciseStackLockPointInbound[ex + 1] = calculatedLockPoint;
            }

            long currentStackCount = 0;
            long operationCount    = 0;

            for (int ex = 0; ex < solution.Exercises; ex++)
            {
                var removeOps = currentStackCount - (solution.ExerciseStackLockPointInbound[ex] + 1);
                currentStackCount = solution.ExerciseStackLockPointInbound[ex] + 1;
                operationCount   += removeOps;

                var addOps = solution.WeightsPerExercise[ex] - currentStackCount;
                operationCount   += addOps;
                currentStackCount = solution.WeightsPerExercise[ex];
            }

            var finalRemoveOps = currentStackCount;

            currentStackCount = 0;
            operationCount   += finalRemoveOps;

            return(new CaseOutput(operationCount));
        }