Exemple #1
0
        /// <summary>
        /// If a segment has its first sequence in its entirety touching its first side, then terminate it with a False.
        /// Vice versa for the last sequence.
        /// </summary>
        /// <param name="segment"></param>
        /// <returns></returns>
        public override bool Execute(Segment segment)
        {
            if (!segment.HasBlanks)
            {
                return(false);
            }

            if (segment.TrueCount == 0)
            {
                return(false);
            }
            KnownStartAndEndFalses falseStartAndEndCounts = base.RemoveStartAndEndFalsesFromSegment(segment);
            bool cellsChanged = false;

            // If the sequence is small enough to fit inside and needs to be terminated somewhere,
            Sequence firstSequence = segment.MustHaves.First();

            if (firstSequence.Count < segment.Length)
            {
                // And if it's touching the start in it's entirety
                if (segment.Cells.Take(firstSequence.Count).Count(cell => cell.IsTrue) == firstSequence.Count &&
                    segment.Cells[firstSequence.Count].IsUnMarked)
                {
                    // Then terminate it
                    if (segment.Cells[firstSequence.Count].MarkFalse() && !cellsChanged)
                    {
                        cellsChanged = true;
                    }
                }
            }

            // Last
            Sequence lastSequence = segment.MustHaves.Last();

            if (lastSequence.Count < segment.Length)
            {
                // And if it's touching the end in it's entirety
                if (segment.Cells.Skip(segment.Length - lastSequence.Count).Take(lastSequence.Count).Count(cell => cell.IsTrue) == lastSequence.Count &&
                    segment.Cells[lastSequence.Count].IsUnMarked)
                {
                    // Then terminate it
                    if (segment.Cells[segment.Length - lastSequence.Count - 1].MarkFalse() && !cellsChanged)
                    {
                        cellsChanged = true;
                    }
                }
            }
            base.RecombineFalseStartsAndEndsWithSegment(falseStartAndEndCounts, segment);
            return(cellsChanged);
        }
        /// <summary>
        /// If we have a single sequence and we know at least 1 part of it, mark anything
        ///     out of possible bounds as False
        /// </summary>
        /// <param name="segment"></param>
        /// <returns></returns>
        public override bool Execute(Segment segment)
        {
            if (!segment.HasBlanks)
            {
                return(false);
            }

            KnownStartAndEndFalses falseStartAndEndCounts = base.RemoveStartAndEndFalsesFromSegment(segment);

            bool cellsChanged = false;

            // If there's exactly 1 sequence
            if (segment.MustHaves.Count == 1)
            {
                Sequence theSequence = segment.MustHaves.First();
                // But there's already more than 1 known True cell,
                IEnumerable <Cell> trueCells = segment.Cells.Where(cell => cell.IsTrue);
                if (trueCells.Any())
                {
                    // Find the known bounds
                    int minimumTrue = trueCells.Min(cell => cell.IndexIn(segment));
                    int maximumTrue = trueCells.Max(cell => cell.IndexIn(segment));

                    // Exclude known bounds below the minimum and above the maxium
                    for (int i = 0; i < maximumTrue + 1 - theSequence.Count; i++)
                    {
                        if (segment.Cells[i].IsUnMarked)
                        {
                            if (segment.Cells[i].MarkFalse() && !cellsChanged)
                            {
                                cellsChanged = true;
                            }
                        }
                    }
                    for (int i = segment.Length - 1; i > minimumTrue - 1 + theSequence.Count; i--)
                    {
                        if (segment.Cells[i].IsUnMarked)
                        {
                            if (segment.Cells[i].MarkFalse() && !cellsChanged)
                            {
                                cellsChanged = true;
                            }
                        }
                    }
                }
            }
            base.RecombineFalseStartsAndEndsWithSegment(falseStartAndEndCounts, segment);
            return(cellsChanged);
        }
        /// <summary>
        /// After a cap-trim, if start or end is [unmarked][false] and [unmarked.count] < sequences.first.count, then it can't fit, so mark [unmarked] as falses
        /// </summary>
        /// <param name="segment"></param>
        /// <returns></returns>
        public override bool Execute(Segment segment)
        {
            if (!segment.HasBlanks)
            {
                return(false);
            }
            KnownStartAndEndFalses falseStartAndEndCounts = base.RemoveStartAndEndFalsesFromSegment(segment);
            bool cellsChanged = false;

            // Start
            int startingUnmarked = segment.Cells.TakeWhile(cell => cell.IsUnMarked).Count();

            if (startingUnmarked < segment.MustHaves.First().Count&&
                segment.Cells.Skip(startingUnmarked).First().IsFalse)
            {
                foreach (Cell cell in segment.Cells.Take(startingUnmarked))
                {
                    if (cell.MarkFalse() && !cellsChanged)
                    {
                        cellsChanged = true;
                    }
                }
            }

            // End
            segment.Cells.Reverse();
            segment.MustHaves.Reverse();
            startingUnmarked = segment.Cells.TakeWhile(cell => cell.IsUnMarked).Count();
            if (startingUnmarked < segment.MustHaves.First().Count&&
                segment.Cells.Skip(startingUnmarked).First().IsFalse)
            {
                foreach (Cell cell in segment.Cells.Take(startingUnmarked))
                {
                    if (cell.MarkFalse() && !cellsChanged)
                    {
                        cellsChanged = true;
                    }
                }
            }
            segment.Cells.Reverse();
            segment.MustHaves.Reverse();


            base.RecombineFalseStartsAndEndsWithSegment(falseStartAndEndCounts, segment);
            return(cellsChanged);
        }
        /// <summary>
        /// If the sequences and their spacing adds to segment length, then just draw it out,
        /// separated by Falses
        /// </summary>
        /// <param name="segment"></param>
        /// <returns></returns>
        public override bool Execute(Segment segment)
        {
            if (!segment.HasBlanks)
            {
                return(false);
            }

            KnownStartAndEndFalses falseStartAndEndCounts = base.RemoveStartAndEndFalsesFromSegment(segment);

            bool cellsChanged = false;

            if (segment.MustHaves.Sum(seq => seq.Count) + segment.MustHaves.Count - 1 == segment.Length)
            {
                int i = 0;
                foreach (Sequence sequence in segment.MustHaves)
                {
                    for (int j = 0; j < sequence.Count; j++)
                    {
                        // Mark the trues
                        if (segment.Cells[i].MarkTrue() & !cellsChanged)
                        {
                            cellsChanged = true;
                        }
                        i++;
                    }

                    if (i < segment.Length)
                    {
                        // Joining with falses
                        if (segment.Cells[i].MarkFalse() & !cellsChanged)
                        {
                            cellsChanged = true;
                        }
                        i++;
                    }
                }
            }

            base.RecombineFalseStartsAndEndsWithSegment(falseStartAndEndCounts, segment);
            return(cellsChanged);
        }
        /// <summary>
        /// If a segment starts or ends with a True, extend it outward based on first or last sequence
        /// </summary>
        /// <param name="segment"></param>
        /// <returns></returns>
        public override bool Execute(Segment segment)
        {
            if (!segment.HasBlanks)
            {
                return(false);
            }
            KnownStartAndEndFalses falseStartAndEndCounts = base.RemoveStartAndEndFalsesFromSegment(segment);

            bool cellsChanged = false;

            if (segment.TrueCount > 0)
            {
                if (segment.Cells.First().IsTrue)
                {
                    foreach (Cell cell in segment.Cells.Take(segment.MustHaves.First().Count))
                    {
                        if (cell.MarkTrue() && !cellsChanged)
                        {
                            cellsChanged = true;
                        }
                    }
                }

                //End
                if (segment.Cells.Last().IsTrue)
                {
                    segment.Cells.Reverse();
                    foreach (Cell cell in segment.Cells.Take(segment.MustHaves.Last().Count))
                    {
                        if (cell.MarkTrue() && !cellsChanged)
                        {
                            cellsChanged = true;
                        }
                    }
                    segment.Cells.Reverse();
                }
            }

            base.RecombineFalseStartsAndEndsWithSegment(falseStartAndEndCounts, segment);
            return(cellsChanged);
        }
Exemple #6
0
        protected void RecombineFalseStartsAndEndsWithSegment(KnownStartAndEndFalses StartAndEnd, Segment MiddleSegment)
        {
            if (StartAndEnd.StartIndexFalsesEnd != 0)
            {
                for (int i = 0; i < StartAndEnd.StartIndexFalsesEnd; i++)
                {
                    Cell FalseCell = new Cell();
                    FalseCell.MarkFalse();
                    MiddleSegment.Cells.Insert(0, FalseCell);
                }
            }

            if (StartAndEnd.EndIndexFalsesStart != 0)
            {
                for (int i = 0; i < StartAndEnd.EndIndexFalsesStart; i++)
                {
                    Cell FalseCell = new Cell();
                    FalseCell.MarkFalse();
                    MiddleSegment.Cells.Add(FalseCell);
                }
            }
        }
        /// <summary>
        /// If the ENTIRE segment is either all true or all false
        /// </summary>
        /// <param name="segment"></param>
        /// <returns></returns>
        public override bool Execute(Segment segment)
        {
            if (!segment.HasBlanks)
            {
                return(false);
            }

            KnownStartAndEndFalses falseStartAndEndCounts = base.RemoveStartAndEndFalsesFromSegment(segment);

            bool cellsChanged = false;

            if (segment.MustHaves.Count == 1)
            {
                // If it's all true
                if (segment.MustHaves.First().Count == segment.Length)
                {
                    foreach (Cell cell in segment.Cells)
                    {
                        if (cell.MarkTrue() && !cellsChanged)
                        {
                            cellsChanged = true;
                        }
                    }
                }
                // If it's all false
                else if (segment.MustHaves.First().Count == 0)
                {
                    foreach (Cell cell in segment.Cells)
                    {
                        if (cell.MarkFalse() && !cellsChanged)
                        {
                            cellsChanged = true;
                        }
                    }
                }
            }
            base.RecombineFalseStartsAndEndsWithSegment(falseStartAndEndCounts, segment);
            return(cellsChanged);
        }
        /// <summary>
        /// If there's only 1 sequence and we have more than one already True cells,
        ///     then connect them
        /// </summary>
        /// <param name="segment"></param>
        /// <returns></returns>
        public override bool Execute(Segment segment)
        {
            if (!segment.HasBlanks)
            {
                return(false);
            }

            KnownStartAndEndFalses falseStartAndEndCounts = base.RemoveStartAndEndFalsesFromSegment(segment);

            bool cellsChanged = false;

            // If there's only 1 sequence
            if (segment.MustHaves.Count == 1)
            {
                // But there's already more than 1 known True cell,
                IEnumerable <Cell> trueCells = segment.Cells.Where(cell => cell.IsTrue);
                if (trueCells.Count() > 1)
                {
                    // Figure out what to draw between
                    int startDrawingAt = trueCells.Min(cell => cell.IndexIn(segment));
                    int endDrawingAt   = trueCells.Max(cell => cell.IndexIn(segment));

                    // Draw between them
                    for (; startDrawingAt < endDrawingAt; startDrawingAt++)
                    {
                        // startDrawingAt is the index of cell to mark as True
                        // Mark the cells along the path as true
                        if (segment.Cells[startDrawingAt].MarkTrue() && !cellsChanged)
                        {
                            cellsChanged = true;
                        }
                    }
                }
            }
            base.RecombineFalseStartsAndEndsWithSegment(falseStartAndEndCounts, segment);
            return(cellsChanged);
        }
Exemple #9
0
        public override bool Execute(Segment segment)
        {
            if (!segment.HasBlanks)
            {
                return(false);
            }

            KnownStartAndEndFalses falseStartAndEndCounts = base.RemoveStartAndEndFalsesFromSegment(segment: segment, onlyTrimIfNoFalses: true);

            bool cellsChanged = false;

            if (segment.MustHaves.Count == 1)
            {
                // For a single sequence in a segment,
                Sequence theSequence = segment.MustHaves.First();

                // Check for overlap
                int overlapFromMiddle;
                if (segment.Length.IsOdd())
                {
                    overlapFromMiddle = theSequence.Count - (segment.Length / 2) - 1;
                }
                else
                {
                    overlapFromMiddle = theSequence.Count - (segment.Length / 2);
                }

                if (overlapFromMiddle > 0)
                {
                    // Work outwards from the middle
                    double middleIndex = segment.Length / 2.0;

                    // If an odd number is needed, mark the middle
                    bool markedMiddle = false;
                    if (segment.Length.IsOdd())
                    {
                        // Mark the middle
                        if (segment.Cells[(segment.Length - 1) / 2].MarkTrue() &&
                            !cellsChanged)
                        {
                            cellsChanged = true;
                        }

                        markedMiddle = true;
                    }

                    if (!markedMiddle || (markedMiddle && overlapFromMiddle >= 1))
                    {
                        // Regardless, move outwards if we have to
                        for (int i = 0; i < overlapFromMiddle; i++)
                        {
                            // When odd, we need to do each side from the middle equally
                            if (segment.Length.IsOdd())
                            {
                                // 2.5-> 1,3 0,4
                                if (segment.Cells[Convert.ToInt32(Math.Floor(middleIndex)) - (i + 1)].MarkTrue() && !cellsChanged)
                                {
                                    cellsChanged = true;
                                }
                                if (segment.Cells[Convert.ToInt32(Math.Floor(middleIndex)) + (i + 1)].MarkTrue() && !cellsChanged)
                                {
                                    cellsChanged = true;
                                }
                            }
                            else
                            {
                                // 2 -> 1,2 0,3
                                if (segment.Cells[Convert.ToInt32(middleIndex) + (i)].MarkTrue() && !cellsChanged)
                                {
                                    cellsChanged = true;
                                }
                                if (segment.Cells[Convert.ToInt32(middleIndex) - (i + 1)].MarkTrue() && !cellsChanged)
                                {
                                    cellsChanged = true;
                                }
                            }
                        }
                    }
                }
            }
            base.RecombineFalseStartsAndEndsWithSegment(falseStartAndEndCounts, segment);
            return(cellsChanged);
        }