Example #1
0
        private static bool RemoveFromCollection(PermutationsCollection target, BitArray mustBeOn, BitArray mustBeOff, int inputIx, int targetIx, CancellationToken cancellationToken)
        {
            var coll  = target[targetIx];
            var count = coll.RemoveAll(permutation => CanPermutationBeRemoved(permutation, mustBeOn, mustBeOff, inputIx, targetIx, cancellationToken));

            return(count > 0);
        }
Example #2
0
        private static ProcessStepResult Step(PermutationsCollection rows, PermutationsCollection cols, CancellationToken cancellationToken)
        {
            try
            {
                var firstPass = RemovePermutations(cols, rows, cancellationToken);
                if (firstPass == ProcessStepResult.Unsolvable || firstPass == ProcessStepResult.Cancelled)
                {
                    return(firstPass);
                }

                if (cancellationToken.IsCancellationRequested)
                {
                    return(ProcessStepResult.Cancelled);
                }

                var secondPass = RemovePermutations(rows, cols, cancellationToken);
                if (secondPass == ProcessStepResult.Unsolvable || secondPass == ProcessStepResult.Cancelled)
                {
                    return(secondPass);
                }

                bool keepGoing = firstPass == ProcessStepResult.KeepGoing || secondPass == ProcessStepResult.KeepGoing;
                return(keepGoing ? ProcessStepResult.KeepGoing : ProcessStepResult.Finished);
            }
            catch (OperationCanceledException)
            {
                return(ProcessStepResult.Cancelled);
            }
        }
Example #3
0
        /// <summary>
        /// Go through all permutations within <paramref name="input"/> and see which fields are commonly on or commonly off between all of them.
        /// Then, remove any mismatches from <paramref name="target"/>, bringing the total permutation count down, hopefully to 1.
        ///
        /// If we end up with no permutations in the target, the Nonogram is unsolvable.
        /// </summary>
        /// <param name="input">The collection that we're using to try to determine which permutations to remove from <paramref name="target"/>.</param>
        /// <param name="target">The collection that we're trying to remove permutations from.</param>
        /// <param name="cancellationToken">A cancellationToken to support canceling this method</param>
        /// <returns>
        /// Whether we successuly removed permutations from <paramref name="target"/>.
        /// * <see cref="ProcessStepResult.KeepGoing"/> means that permutations were removed, and that we should loop once more.
        /// * <see cref="ProcessStepResult.Finished"/> means that no further permutations were removed. We're possibly done with <paramref name="target"/> for good.
        /// * <see cref="ProcessStepResult.Unsolvable"/> means that there are no further permutations left in at least one element of <paramref name="target"/> - the Nonogram is unsolvable.
        /// * <see cref="ProcessStepResult.Cancelled"/> means that the <paramref name="cancellationToken"/> was cancelled, likely due to a timeout or user cancellation
        /// </returns>
        private static ProcessStepResult RemovePermutations(PermutationsCollection input, PermutationsCollection target, CancellationToken cancellationToken)
        {
            bool keepGoing = false;

            for (int inputIx = 0; inputIx < input.Count; inputIx++)
            {
                DetermineMustBeOnOff(input[inputIx], target.Count, cancellationToken, out var mustBeOn, out var mustBeOff);

                for (int targetIx = 0; targetIx < target.Count; targetIx++)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    if (RemoveFromCollection(target, mustBeOn, mustBeOff, inputIx, targetIx, cancellationToken))
                    {
                        keepGoing = true;
                    }

                    if (target[targetIx].Count == 0)
                    {
                        return(ProcessStepResult.Unsolvable);
                    }
                }
            }
            return(keepGoing ? ProcessStepResult.KeepGoing : ProcessStepResult.Finished);
        }
Example #4
0
        /// <summary>
        /// Create Row and Column Permutations.
        /// </summary>
        /// <returns>FALSE if we hit the timeout, TRUE if everything went well.</returns>
        internal bool PopulatePermutations()
        {
            var  rowPermutations = new PermutationsCollection(Nonogram.RowHints.Count);
            var  colPermutations = new PermutationsCollection(Nonogram.ColumnHints.Count);
            var  colLength       = Nonogram.ColumnHints.Count;
            var  rowLength       = Nonogram.RowHints.Count;
            bool result          = true;

            Stopwatch.Restart();
            if (UseMultipleCores)
            {
                var po = new ParallelOptions {
                    CancellationToken = CancellationToken, MaxDegreeOfParallelism = Environment.ProcessorCount
                };
                void AddAndCheckTimeout(BitArray ba, PermutationsCollection collection, int index)
                {
                    collection[index].Add(ba);
                    if (WillHitTimeout || CancellationToken.IsCancellationRequested)
                    {
                        CancelToken();
                    }
                }

                try
                {
                    Parallel.For(0, rowLength, po, ix =>
                    {
                        PermutationGenerator.GeneratePermutationsForHintData(Nonogram.RowHints[ix], colLength, ba => AddAndCheckTimeout(ba, rowPermutations, ix));
                    });

                    Parallel.For(0, colLength, po, ix =>
                    {
                        PermutationGenerator.GeneratePermutationsForHintData(Nonogram.ColumnHints[ix], rowLength, ba => AddAndCheckTimeout(ba, colPermutations, ix));
                    });

                    result = true;
                }
                catch (OperationCanceledException)
                {
                    result = false;
                }
            }
            else
            {
                for (int ix = 0; ix < rowLength; ix++)
                {
                    PermutationGenerator.GeneratePermutationsForHintData(Nonogram.RowHints[ix], colLength, rowPermutations[ix].Add);
                    if (WillHitTimeout || CancellationToken.IsCancellationRequested)
                    {
                        CancelToken();
                        result = false;
                        break;
                    }
                }

                if (result)
                {
                    for (int ix = 0; ix < colLength; ix++)
                    {
                        PermutationGenerator.GeneratePermutationsForHintData(Nonogram.ColumnHints[ix], rowLength, colPermutations[ix].Add);
                        if (WillHitTimeout || CancellationToken.IsCancellationRequested)
                        {
                            CancelToken();
                            result = false;
                            break;
                        }
                    }
                }
            }
            Stopwatch.Stop();
            UpdateElapsed();

            RowPermutations                = rowPermutations;
            ColumnPermutations             = colPermutations;
            InitialRowPermutationsCount    = rowPermutations.GetTotalPermutationCount();
            InitialColumnPermutationsCount = colPermutations.GetTotalPermutationCount();
            return(result);
        }