Ejemplo n.º 1
0
        private Entry findEntryWithMinChoices(LatinSquare lq)
        {
            int minChoices = lq.entries.Length;
            int targetRow  = -1;
            int targetCol  = -1;

            for (int row = 0; row < lq.entries.Length; row++)
            {
                for (int col = 0; col < lq.entries.Length; col++)
                {
                    int choices = lq.entries[row][col].GetNumPossibleValues();
                    if (choices == 2)
                    {
                        return(new Entry(row, col, NumberSet.UNKNOWN));
                    }
                    if (choices > 1 && choices < minChoices)
                    {
                        minChoices = choices;
                        targetRow  = row;
                        targetCol  = col;
                    }
                }
            }
            return(new Entry(targetRow, targetCol, NumberSet.UNKNOWN));
        }
Ejemplo n.º 2
0
        /**
         * Creates an instance linked with its two alternative forms.
         */
        public static LatinSquare create(int size)
        {
            LatinSquare result = new LatinSquare(size);

            result.nextTransposition = new LatinSquare(new LatinSquare(result));
            return(result);
        }
Ejemplo n.º 3
0
        public virtual LatinSquare CreateCopy()
        {
            LatinSquare result = new LatinSquare(entries, this);
            LatinSquare nnt    = new LatinSquare(nextTransposition.nextTransposition.entries, result);
            LatinSquare nt     = new LatinSquare(nextTransposition.entries, nnt);

            result.nextTransposition = nt;
            return(result);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Create a deep copy of this (including transposed forms)
        /// </summary>
        /// <returns>instance of Sudoku</returns>
        public override LatinSquare CreateCopy()
        {
            // TODO: in base constructor param is transposition, here it is original
            Sudoku      result = new Sudoku(this);
            LatinSquare nnt    = new LatinSquare(nextTransposition.nextTransposition.entries, result);
            LatinSquare nt     = new LatinSquare(nextTransposition.entries, nnt);

            result.nextTransposition = nt;
            return(result);
        }
Ejemplo n.º 5
0
        private void addOneEntry(LatinSquare square)
        {
            try
            {
                while (solution == null)
                {
                    square.AddFindings();
                    var target = findEntryWithMinChoices(square);
                    if (target.Row == -1)
                    {
                        solution = square;
                        tasks.AbortAll();
                        return;
                    }

                    List <int> values = square.entries[target.Row][target.Col].GetAllowedValues();
                    if (Reverse)
                    {
                        values.Reverse();
                    }

                    int remaining = values.Count;
                    foreach (int num in values)
                    {
                        if (--remaining > 0)
                        {
                            try
                            {
                                LatinSquare candidate = square.CreateCopy();
                                candidate.SetEntry(target.Row, target.Col, num);
                                tasks.Add(candidate);
                            }
                            catch (IllegalEntryException)
                            {
                                Effort++;
                            }
                        }
                        else
                        {
                            square.SetEntry(target.Row, target.Col, num); // just continue loop instead of wait for another task
                        }
                    }
                }
            }
            catch (IllegalEntryException)
            {
                Effort++;
            }
        }
Ejemplo n.º 6
0
        public LatinSquare CompleteParallel(LatinSquare square, int numberThreads)
        {
            tasks.Add(square);

            List <Thread> threads = new List <Thread>();

            for (int i = 0; i < numberThreads; i++)
            {
                threads.Add(new Thread(AddEntry));
            }
            threads.ForEach(t => t.Start());
            threads.ForEach(t => t.Join());

            if (solution == null)
            {
                throw new IllegalEntryException();
            }
            return(solution);
        }
Ejemplo n.º 7
0
 private void AddEntry()
 {
     while (solution == null)
     {
         LatinSquare square = tasks.GetNext();
         if (square == null)
         {
             return;
         }
         try
         {
             addOneEntry(square);
         }
         finally
         {
             tasks.Done();
         }
     }
 }
Ejemplo n.º 8
0
        public override bool Equals(object obj)
        {
            if (obj == null || GetType() != obj.GetType())
            {
                return(false);
            }
            LatinSquare other = (LatinSquare)obj;

            for (int row = 0; row < entries.Length; row++)
            {
                for (int col = 0; col < entries[row].Length; col++)
                {
                    if (GetEntry(row, col) != other.GetEntry(row, col))
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
Ejemplo n.º 9
0
        public LatinSquare Complete(LatinSquare square)
        {
            if (square == null)
            {
                throw new ArgumentNullException(nameof(square));
            }

            square.AddFindings();

            var target = findEntryWithMinChoices(square);

            if (target.Row == -1)
            {
                return(square);
            }
            IllegalEntryException last = null;

            List <int> values = square.entries[target.Row][target.Col].GetAllowedValues();

            if (Reverse)
            {
                values.Reverse();
            }
            int remaining = values.Count;

            foreach (int num in values)
            {
                try
                {
                    LatinSquare candidate = (--remaining == 0 ? square : square.CreateCopy());
                    candidate.SetEntry(target.Row, target.Col, num);
                    return(Complete(candidate));
                }
                catch (IllegalEntryException e)
                {
                    Effort++;
                    last = e;
                }
            }
            throw last;
        }
Ejemplo n.º 10
0
 internal LatinSquare(NumberSet[][] originalEntries, LatinSquare nt)
 {
     entries           = CloneEntries(originalEntries);
     nextTransposition = nt;
 }
Ejemplo n.º 11
0
 /**
  * Not to be used except in inheriting classes. Protected would not permit call from static methods.
  */
 internal LatinSquare(LatinSquare nt) : this(nt.entries.Length)
 {
     nextTransposition = nt;
 }