Esempio n. 1
0
        private bool GetMinRowCol_Rows(SkyscraperData d, out int row, out int col)
        {
            row = -1;
            col = -1;

            int currminbits = _n + 1;
            int setbits     = 0;

            for (int i = 0; i < _n; i++)
            {
                int setbitsinrow = d.CountBits(d.SetInRow[i]);
                for (int j = 0; j < d.Rows[i].Count; j++)
                {
                    int bits = d.CountBits(i, d.Rows[i][j]);
                    if ((bits < currminbits) ||
                        ((bits == currminbits) && (setbitsinrow < setbits))) //w wierszu najmniej ustawionych bitow
                    {
                        row         = i;
                        col         = d.Rows[i][j];
                        currminbits = bits;
                        setbits     = setbitsinrow;
                    }
                }
            }
            return(currminbits != _n + 1);
        }
Esempio n. 2
0
        private bool GetMinRowCol_Default(SkyscraperData d, out int row, out int col)
        {
            row = -1;
            col = -1;

            int currminbits = _n + 1;
            int setbits     = 0;

            for (int i = 0; i < _n; i++)
            {
                if (d.SetInRow[i] != SkyscraperData.InitialValues[_n])
                {
                    int setbitsinrow = d.CountBits(d.SetInRow[i]);
                    for (int j = 0; j < _n; j++)
                    {
                        int bits = d.CountBits(i, j);
                        if (bits > 1)
                        {
                            if ((bits < currminbits) ||
                                ((bits == currminbits) && (setbitsinrow < setbits))) //w wierszu najmniej ustawionych bitow
                            {
                                row         = i;
                                col         = j;
                                currminbits = bits;
                                setbits     = d.SetInRow[i];
                            }
                        }
                    }
                }
            }
            return(currminbits != _n + 1);
        }
 private bool CheckDataUniqueElements(SkyscraperData d)
 {
     for (int i = 0; i < _n; i++)
     {
         int mask = 0, mask2 = 0;
         int cnt = 0, cnt2 = 0;
         for (int j = 0; j < _n; j++)
         {
             if (d.CountBits(i, j) == 1)
             {
                 mask ^= d.Data[i, j];
                 cnt++;
             }
             if (d.CountBits(j, i) == 1)
             {
                 mask2 ^= d.Data[j, i];
                 cnt2++;
             }
         }
         if ((d.CountBits(mask) != cnt) || (d.CountBits(mask2) != cnt2))
         {
             return(false);
         }
     }
     return(true);
 }
Esempio n. 4
0
 private bool ReduceRowsCols(SkyscraperData d, List <Tuple <int, int> > proc)
 {
     //int iproc = 0;
     //while (iproc < proc.Count)
     //{
     //    if (!ReduceRowCol(d, proc[iproc].Item1, proc[iproc].Item2)) return false;
     //    iproc++;
     //}
     return(proc.All(p => ReduceRowCol(d, p.Item1, p.Item2)));
 }
Esempio n. 5
0
        public SkyscraperData CreateInitialData()
        {
            SkyscraperData d = new SkyscraperData(_n);

            for (int i = 0; i < _n; i++)
            {
                for (int j = 0; j < _n; j++)
                {
                    d.Data[i, j] = SkyscraperData.InitialValues[_n];
                }
            }
            return(d);
        }
Esempio n. 6
0
 public SkyscraperData(SkyscraperData obj)
 {
     _size    = obj._size;
     Data     = (int[, ])obj.Data.Clone();
     SetInRow = (int[])obj.SetInRow.Clone();
     SetInCol = (int[])obj.SetInCol.Clone();
     Rows     = new List <int> [_size];
     Cols     = new List <int> [_size];
     for (int i = 0; i < _size; i++)
     {
         Rows[i] = obj.Rows[i].ToList();
         Cols[i] = obj.Cols[i].ToList();
     }
 }
 public bool CheckData(SkyscraperData d, int[] constraints)
 {
     //incorrectElements = false;
     //if (!CheckDataUniqueElements(d))
     //{
     //    incorrectElements = true;
     //    return false;
     //}
     if (!CheckDataReduced(d))
     {
         return(false);
     }
     return(CheckDataConstraints(d, constraints));
 }
Esempio n. 8
0
 public bool ReduceData(SkyscraperData d, List <Tuple <int, int> > proc)
 {
     if (!ReduceRowsCols(d, proc))
     {
         return(false);
     }
     if (!SetRowsColsWherePossible(d))
     {
         return(false);
     }
     //if (!ReduceRowsCols(d, proc)) return false;
     //proc.Clear();
     //SetRowsColsWherePossibleDoubles(d, proc);
     return(true);
 }
Esempio n. 9
0
        private bool TrySetSingleElement(SkyscraperData d, int row, int col, int mask)
        {
            int v = (mask ^ -1) & (d.Data[row, col] & ((d.SetInRow[row] | d.SetInCol[col]) ^ -1));  //zostaja jedynki tam gdzie w masce sa 0, dodatkowo wylaczone juz ustawione bity

            if (d.CountBits(v) == 1)
            {
                d.SetSingleElementMask(row, col, v);
                if (!ReduceRowCol(d, row, col))
                {
                    return(false);
                }
                return(true);
            }
            return(false);
        }
        private bool CheckDataReduced(SkyscraperData d)
        {
            //for (int i = 0; i < _n; i++)
            //    for (int j = 0; j < _n; j++)
            //        if (d.CountBits(i, j) != 1) return false;
            //return true;

            for (int i = 0; i < _n; i++)
            {
                if (d.SetInRow[i] != SkyscraperData.InitialValues[_n])
                {
                    return(false);
                }
            }
            return(true);
        }
 private bool CheckDataElements(SkyscraperData d)
 {
     for (int i = 0; i < _n; i++)
     {
         int mask = 0, mask2 = 0;
         for (int j = 0; j < _n; j++)
         {
             mask  |= d.Data[i, j];
             mask2 |= d.Data[j, i];
         }
         if ((mask != SkyscraperData.InitialValues[_n]) || (mask2 != SkyscraperData.InitialValues[_n]))
         {
             return(false);
         }
     }
     return(true);
 }
Esempio n. 12
0
        public SkyscraperData FindSolution(SkyscraperData d, int[] constraints)
        {
            if (_dataValidator.CheckData(d, constraints))
            {
                return(d);
            }

            //wybierany pierwszy element o najmniejszej ilosci mozliwych pozycji
            //analiza drzewa rozwiazan w glab
            int row = -1, col = -1;

            //if (GetMinRowCol_Default(d, out row, out col))
            if (GetMinRowCol_Rows(d, out row, out col))
            {
                //Console.WriteLine($"{SkyscrapersCounters.Level}, {row}, {col}");
                int el = d.Data[row, col];
                for (int m = 1; m <= _n; m++)
                {
                    if ((el & SkyscraperData.Masks[m]) != 0)
                    {
                        //Console.WriteLine($"{SkyscrapersCounters.Level}, {row}, {col}, {m}");
                        SkyscrapersCounters.NewData++;
                        SkyscraperData newd = new SkyscraperData(d);
                        newd.SetSingleElement(row, col, m);
                        List <Tuple <int, int> > proc = new List <Tuple <int, int> >()
                        {
                            new Tuple <int, int>(row, col)
                        };
                        SkyscraperData nextd = null;
                        SkyscrapersCounters.Level++;
                        if (_dataReductor.ReduceData(newd, proc))
                        {
                            nextd = FindSolution(newd, constraints);
                        }
                        SkyscrapersCounters.Level--;
                        if (nextd != null)
                        {
                            return(nextd);
                        }
                    }
                }
            }

            return(null);
        }
Esempio n. 13
0
 private void SetRowsColsWherePossibleDoubles(SkyscraperData d, List <Tuple <int, int> > proc)
 {
     //wierszami
     //for (int i = 0; i < _n; i++)
     //{
     //    //listy indeksow elementow dla masek
     //    Dictionary<int, PrecalcData<int>> rowels = new Dictionary<int, PrecalcData<int>>();
     //    for (int j = 0; j < _n; j++)
     //    {
     //        //rozbicie elementu (wybranie ustawionych bitow)
     //        PrecalcData<int> el = new PrecalcData<int>();
     //        for (int m = 1; m <= _n; m++)
     //            if ((d.Data[i, j] & SkyscraperData.Masks[m]) != 0) el.Add(SkyscraperData.Masks[m]);
     //        //wyznaczenie list z calego wiersza dla wszystkich par danego elementu
     //        for (int f = 0; f < el.Count - 1; f++)
     //            for (int n = f + 1; n < el.Count; n++)
     //            {
     //                int p = el[f] | el[n];
     //                if (rowels.ContainsKey(p)) continue;
     //                PrecalcData<int> tl = new PrecalcData<int>();
     //                for (int k = 0; k < _n; k++)
     //                    if ((d.Data[i, k] & p) == p) tl.Add(k);
     //                rowels.Add(p, tl);
     //            }
     //    }
     //    //analiza par
     //    int removedmask = 0;    //moga pojawic sie pary dla powtarzajacych sie pozycji - mozna tylko raz pozycje usunac
     //    foreach (var rowel in rowels.Where(x => x.Value.Count==2))
     //    {
     //        if ((rowel.Key & removedmask) != 0) continue;
     //        for (int k = 0; k < _n; k++)
     //        {
     //            if (rowel.Value.Contains(k))
     //                d.Data[i, k] = rowel.Key;
     //            else
     //                TryReduceSingleElement(d, proc, i, k, rowel.Key ^ -1);
     //        }
     //        removedmask |= rowel.Key;
     //    }
     //}
 }
Esempio n. 14
0
        private bool ReduceRowCol(SkyscraperData d, int row, int col)
        {
            SkyscrapersCounters.ReduceRCReductions++;
            int mask = d.Data[row, col] ^ -1;
            int i    = 0;

            while (i < d.Rows[row].Count)
            {
                bool singleset = false;
                if (col != d.Rows[row][i])
                {
                    if (!TryReduceSingleElement(d, row, d.Rows[row][i], mask, out singleset))
                    {
                        return(false);
                    }
                }
                if (!singleset)
                {
                    i++;
                }
            }
            i = 0;
            while (i < d.Cols[col].Count)
            {
                bool singleset = false;
                if (row != d.Cols[col][i])
                {
                    if (!TryReduceSingleElement(d, d.Cols[col][i], col, mask, out singleset))
                    {
                        return(false);
                    }
                }
                if (!singleset)
                {
                    i++;
                }
            }
            return(true);
        }
Esempio n. 15
0
 private bool TryReduceSingleElement(SkyscraperData d, int row, int col, int mask, out bool singleset)
 {
     singleset = false;
     //if (d.CountBits(row, col) > 1)
     {
         d.RemoveElementMask(row, col, mask);
         if (d.CountBits(row, col) == 1)
         {
             if (((d.Data[row, col] & d.SetInRow[row]) != 0) || ((d.Data[row, col] & d.SetInCol[col]) != 0))
             {
                 SkyscrapersCounters.ReduceRCDoublesCut++;
                 return(false);
             }
             d.SetSingleElementMask(row, col, d.Data[row, col]);
             if (!ReduceRowCol(d, row, col))
             {
                 return(false);
             }
             singleset = true;
         }
     }
     return(true);
 }
Esempio n. 16
0
        public int[][] Solve(int[] constraints)
        {
            //Console.WriteLine("***");
            SkyscrapersCounters.Clear();
            SkyscraperData d = CreateInitialData();

            ApplyConstraints(d, constraints);

            SkyscraperData dres = FindSolution(d, constraints);

            Console.WriteLine($"NewData: {SkyscrapersCounters.NewData}");
            //Console.WriteLine($"ReduceRCIters: {SkyscrapersCounters.ReduceRCIters}");
            //Console.WriteLine($"ReduceRCLoops: {SkyscrapersCounters.ReduceRCLoops}");
            //Console.WriteLine($"ReduceRCLoopsRemoves: {SkyscrapersCounters.ReduceRCLoopsRemoves}");
            Console.WriteLine($"ReduceRCReductions: {SkyscrapersCounters.ReduceRCReductions}");
            Console.WriteLine($"ReduceRCDoublesCut: {SkyscrapersCounters.ReduceRCDoublesCut}");
            //Console.WriteLine($"CheckDataCorrectCalls: {SkyscrapersCounters.CheckDataCorrectCalls}");
            //Console.WriteLine($"CorrectData: {SkyscrapersCounters.CorrectData}");
            //Console.WriteLine($"FirstCorrectDataInCall: {SkyscrapersCounters.FirstCorrectDataInCall}");
            Console.WriteLine($"SetRowsCols: {SkyscrapersCounters.SetRowsCols}");
            Console.WriteLine($"CountBits: {SkyscrapersCounters.CountBits}");

            if (dres == null)
            {
                return(null);               //throw new Exception("dres == null");
            }
            int[][] res = new int[_n][];
            for (int i = 0; i < _n; i++)
            {
                res[i] = new int[_n];
                for (int j = 0; j < _n; j++)
                {
                    res[i][j] = Array.IndexOf(SkyscraperData.Masks, dres.Data[i, j]);
                }
            }
            return(res);
        }
Esempio n. 17
0
        public void ApplyConstraints(SkyscraperData d, int[] constraints)
        {
            //ograniczenia od lewej do prawej po N rzedow
            //po przejsciu N rzedow obrot tablicy w prawo i analiza kolejnych rzedow
            for (int i = constraints.Length - 1; i >= 0; i--)
            {
                if (constraints[i] > 0)
                {
                    int row = _n - 1 - i % _n;
                    if (constraints[i] == _n)
                    {
                        for (int k = 0; k < _n; k++)
                        {
                            d.Data[row, k] = SkyscraperData.Masks[k + 1];
                        }
                    }
                    else if (constraints[i] == 1)
                    {
                        d.Data[row, 0] = SkyscraperData.Masks[_n];
                    }
                    else
                    {
                        for (int el = _n; el > 1; el--)
                        {
                            for (int k = 0; k < constraints[i] - 1 - (_n - el); k++)
                            {
                                d.RemoveElement(row, k, el);
                            }
                        }
                    }
                }
                if (i % _n == 0)
                {
                    d.RotateRight();
                }
            }
            //po nalozeniu ograniczen wygenerowanie list indeksow pozycji nie jednobitowych
            for (int i = 0; i < _n; i++)
            {
                for (int j = 0; j < _n; j++)
                {
                    if (d.CountBits(i, j) > 1)
                    {
                        d.Rows[i].Add(j);
                        d.Cols[j].Add(i);
                    }
                }
            }

            //po nalozeniu ograniczen uwzglednienie wszystkich powstalych pozycji jednoelementowych (redukcja w wierszach i kolumnach)
            List <Tuple <int, int> > proc = new List <Tuple <int, int> >();

            for (int i = 0; i < _n; i++)
            {
                for (int j = 0; j < _n; j++)
                {
                    if (d.CountBits(i, j) == 1)
                    {
                        d.SetSingleElementMask(i, j, d.Data[i, j]);
                        proc.Add(new Tuple <int, int>(i, j));
                    }
                }
            }
            _dataReductor.ReduceData(d, proc);
        }
        private bool CheckDataConstraints(SkyscraperData d, int[] constraints)
        {
            int v;
            int highest;

            for (int i = 0; i < _n; i++)
            {
                //poziomo
                if (constraints[4 * _n - 1 - i] != 0)
                {
                    v       = 1;
                    highest = d.Data[i, 0];
                    for (int j = 0; j < _n; j++)
                    {
                        CheckDataConstraintsSingleCheck(ref v, ref highest, d.Data[i, j]);
                    }
                    if (constraints[4 * _n - 1 - i] != v)
                    {
                        return(false);
                    }
                }
                if (constraints[_n + i] != 0)
                {
                    v       = 1;
                    highest = d.Data[i, _n - 1];
                    for (int j = _n - 1; j >= 0; j--)
                    {
                        CheckDataConstraintsSingleCheck(ref v, ref highest, d.Data[i, j]);
                    }
                    if (constraints[_n + i] != v)
                    {
                        return(false);
                    }
                }
                //pionowo
                if (constraints[i] != 0)
                {
                    v       = 1;
                    highest = d.Data[0, i];
                    for (int j = 0; j < _n; j++)
                    {
                        CheckDataConstraintsSingleCheck(ref v, ref highest, d.Data[j, i]);
                    }
                    if (constraints[i] != v)
                    {
                        return(false);
                    }
                }
                if (constraints[3 * _n - 1 - i] != 0)
                {
                    v       = 1;
                    highest = d.Data[_n - 1, i];
                    for (int j = _n - 1; j >= 0; j--)
                    {
                        CheckDataConstraintsSingleCheck(ref v, ref highest, d.Data[j, i]);
                    }
                    if (constraints[3 * _n - 1 - i] != v)
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
Esempio n. 19
0
        private bool SetRowsColsWherePossible(SkyscraperData d)
        {
            SkyscrapersCounters.SetRowsCols++;

            //for (int i = 0; i < _n; i++)
            //{
            //    int j = 0;
            //    while (j < d.Rows[i].Count)
            //    {
            //        int mask = 0;
            //        for (int k = 0; k < d.Rows[i].Count; k++)
            //            if (k != j) mask |= d.Data[i, d.Rows[i][k]];
            //        if (!TrySetSingleElement(d, i, d.Rows[i][j], mask)) j++;
            //    }
            //}
            //for (int i = 0; i < _n; i++)
            //{
            //    int j = 0;
            //    while (j < d.Cols[i].Count)
            //    {
            //        int mask = 0;
            //        for (int k = 0; k < d.Cols[i].Count; k++)
            //            if (k != j) mask |= d.Data[d.Cols[i][k], i];
            //        if (!TrySetSingleElement(d, d.Cols[i][j], i, mask)) j++;
            //    }
            //}

            for (int i = 0; i < _n; i++)
            {
                int j        = 0;
                int leftmask = 0;
                while (j < d.Rows[i].Count)
                {
                    int mask = leftmask;
                    for (int k = j + 1; k < d.Rows[i].Count; k++)
                    {
                        mask |= d.Data[i, d.Rows[i][k]];
                    }
                    leftmask |= d.Data[i, d.Rows[i][j]];
                    if (!TrySetSingleElement(d, i, d.Rows[i][j], mask))
                    {
                        j++;
                    }
                }
            }
            for (int i = 0; i < _n; i++)
            {
                int j        = 0;
                int leftmask = 0;
                while (j < d.Cols[i].Count)
                {
                    int mask = leftmask;
                    for (int k = j + 1; k < d.Cols[i].Count; k++)
                    {
                        mask |= d.Data[d.Cols[i][k], i];
                    }
                    leftmask |= d.Data[d.Cols[i][j], i];
                    if (!TrySetSingleElement(d, d.Cols[i][j], i, mask))
                    {
                        j++;
                    }
                }
            }

            return(true);
        }