示例#1
0
        private bool CheckListsAndFindShortest(SkyscraperNxNDataLists dataLists, out int shortestIndex)
        {
            shortestIndex = -1;
            int currLen = int.MaxValue;

            for (int i = 0; i < dataLists.Lists.Length; i++)
            {
                if (dataLists.Lists[i] == null)
                {
                    continue;
                }
                SkyscrapersNxNDataObject list = dataLists.Lists[i];
                if (list.Idx.Count == 0)
                {
                    return(false);
                }
                if ((list.Idx.Count > 1) && (list.Idx.Count < currLen))
                {
                    currLen       = list.Idx.Count;
                    shortestIndex = i;
                }
            }

            return(true);
        }
示例#2
0
        private int ReduceListsSingleItemOnList(SkyscraperNxNDataLists dataLists, int singleItemIndex)
        {
            int side        = singleItemIndex / _n; //strona kwadratu
            int lvl         = singleItemIndex % _n; //indeks na stronie kwadratu
            int orientation = side % 2;             //wskazana lista jest pionowa (parzyste) czy pozioma (nieparzyste)
            int top         = (side / 2);           //gorna czy dolna (prawa czy lewa)

            int iopp = GetOppositeListIndex(singleItemIndex);

            if (dataLists.Lists[iopp] != null)
            {
                ReduceListOppositePairSingle(dataLists, singleItemIndex, iopp, false);
                if (dataLists.Lists[iopp].Idx.Count == 1)   //jezeli po redukcji listy przeciwleglej zostaje 1 element to mozna ta liste usunac, bo jest identyczna z biezaca
                {
                    dataLists.Lists[iopp] = null;
                }
                else  //w przeciwnym wypadku zostanie 0 i nie ma potrzeby dalej redukowac, bo caly uklad jest niepoprawny
                {
                    return(0);
                }
            }

            //odpowiednie indeksy w kolejnosci stron: gorna, dolna, prawa, lewa
            int[][] sideindexes = new int[4][] { new int[] { 3, 1, 0, 2 }, new int[] { 1, 3, 2, 0 }, new int[] { 0, 2, 1, 3 }, new int[] { 2, 0, 3, 1 } };
            int[]   sideix      = sideindexes[orientation * 2 + top];

            int[] row     = dataLists.Lists[singleItemIndex].PrecalcData[dataLists.Lists[singleItemIndex].Idx[0]];
            int   deleted = 0;

            for (int i = 0; i < _n; i++)
            {
                deleted += ReduceListsSingleItemOnListSideReduction(dataLists, sideix[0], sideix[1], sideix[2], sideix[3], i, lvl, row);
            }
            return(deleted);
        }
示例#3
0
        private SkyscraperNxNDataLists ReduceLists(SkyscraperNxNDataLists dataLists, out SkyscraperData_Perms data)
        {
            data = null;
            PerformListReduction(dataLists);
            int shortest;

            if (!CheckListsAndFindShortest(dataLists, out shortest))
            {
                return(null);
            }
            if (shortest == -1)
            {
                TryPopulateResultsData(dataLists, out data);
                return(dataLists);
            }
            for (int i = 0; i < dataLists.Lists[shortest].Idx.Count; i++)
            {
                SkyscraperNxNDataLists next = new SkyscraperNxNDataLists(dataLists);
                next.Lists[shortest].Idx = new List <int>()
                {
                    dataLists.Lists[shortest].Idx[i]
                };
                ReduceListsSingleItemOnList(next, shortest);
                SkyscraperNxNDataLists nextres = ReduceLists(next, out data);
                if ((nextres != null) && TryPopulateResultsData(nextres, out data))
                {
                    return(nextres);
                }
            }
            return(null);
        }
示例#4
0
 private void PrepareInitialData(SkyscraperNxNDataLists dataLists)
 {
     for (int i = 0; i < dataLists.Lists.Length; i++)
     {
         if ((dataLists.Lists[i] != null) && (dataLists.Lists[i].Idx.Count == 1))
         {
             ReduceListsSingleItemOnList(dataLists, i);
         }
     }
 }
示例#5
0
        private bool PopulateResultsData(SkyscraperNxNDataLists dataLists, SkyscraperData_Perms data)
        {
            //ustawienie elementow ze zredukowanych list
            for (int i = 0; i < dataLists.Lists.Length; i++)
            {
                if (dataLists.Lists[i] != null)
                {
                    for (int j = 0; j < _n; j++)
                    {
                        data.SetSingleElement(GetDataRowCol(i, j), dataLists.Lists[i].PrecalcData[dataLists.Lists[i].Idx[0]][j]);
                    }
                }
            }

            //lista nieustawionych elementow
            List <Tuple <int, int> > notSet = new List <Tuple <int, int> >();

            for (int row = 0; row < _n; row++)
            {
                for (int col = 0; col < _n; col++)
                {
                    if (data.Data[row, col] == 0)
                    {
                        notSet.Add(new Tuple <int, int>(row, col));
                    }
                }
            }

            //ustawienie brakujacych elementow
            while (notSet.Count > 0)
            {
                int savedcnt = notSet.Count;
                int p        = 0;
                while (p < notSet.Count)
                {
                    int x = (data.SetInRow[notSet[p].Item1] | data.SetInCol[notSet[p].Item2]) ^ SkyscraperData_Perms.InitialValues[_n];
                    if (data.CountBits(x) == 1)
                    {
                        data.SetSingleElementMask(notSet[p].Item1, notSet[p].Item2, x);
                        notSet.RemoveAt(p);
                    }
                    else
                    {
                        p++;
                    }
                }
                if ((notSet.Count > 0) && (savedcnt == notSet.Count))
                {
                    return(false);
                }
            }
            return(true);
        }
示例#6
0
 private List <int>[][] CreateAllowedItemsList(SkyscraperNxNDataLists dataLists, int nPart)
 {
     List <int>[][] res = new List <int> [_n][];
     for (int i = 0; i < _n; i++)
     {
         if (dataLists.Lists[nPart * _n + i] != null)
         {
             res[i] = GetAllowedItems(dataLists.Lists[nPart * _n + i]);
         }
     }
     return(res);
 }
示例#7
0
        private bool TryPopulateResultsData(SkyscraperNxNDataLists dataLists, out SkyscraperData_Perms data)
        {
            data = null;
            SkyscraperData_Perms tdata = new SkyscraperData_Perms(_n);

            if (PopulateResultsData(dataLists, tdata))
            {
                data = tdata;
                return(true);
            }
            return(false);
        }
        public SkyscraperNxNDataLists(SkyscraperNxNDataLists src)
        {
            Lists = new SkyscrapersNxNDataObject[src.Lists.Length];  //tablica list zainicjalizowana nulami

            //skopiowanie list ze zrodla
            for (int i = 0; i < src.Lists.Length; i++)
            {
                if (src.Lists[i] != null)
                {
                    Lists[i] = new SkyscrapersNxNDataObject(src.Lists[i]);
                }
            }
        }
示例#9
0
        private int ReduceListsSingleItemOnListOneEq(SkyscraperNxNDataLists dataLists, int listIndex, int[] singleRow, bool backwards)
        {
            if (dataLists.Lists[listIndex] == null)
            {
                return(0);
            }
            int deleted = dataLists.Lists[listIndex].Idx.RemoveAll(ix => CheckIfSingleItemPermToRemove(dataLists.Lists[listIndex].PrecalcData[ix], singleRow, backwards));

            if ((deleted > 0) && (dataLists.Lists[listIndex].Idx.Count == 1))
            {
                deleted += ReduceListsSingleItemOnList(dataLists, listIndex);
            }
            return(deleted);
        }
示例#10
0
        private int ReduceListsSingleItemOnListOneNonEq(SkyscraperNxNDataLists dataLists, int listIndex, int lvlIndex,
                                                        int rowValue)
        {
            if (dataLists.Lists[listIndex] == null)
            {
                return(0);
            }
            int deleted = dataLists.Lists[listIndex].Idx.RemoveAll(ix => dataLists.Lists[listIndex].PrecalcData[ix][lvlIndex] != rowValue);

            if ((deleted > 0) && (dataLists.Lists[listIndex].Idx.Count == 1))
            {
                deleted += ReduceListsSingleItemOnList(dataLists, listIndex);
            }
            return(deleted);
        }
示例#11
0
        private int ReduceListOppositePairSingle(SkyscraperNxNDataLists dataLists, int i1, int i2, bool reducesingleitem = true)
        {
            int deleted = 0;

            List <int>[] allowed = GetAllowedItems(dataLists.Lists[i1]);
            for (int i = 0; i < _n; i++)
            {
                deleted += dataLists.Lists[i2].Idx.RemoveAll(ix => (!allowed[i].Contains(dataLists.Lists[i2].PrecalcData[ix][_n - i - 1])));
            }
            if (reducesingleitem && (deleted > 0) && (dataLists.Lists[i2].Idx.Count == 1))
            {
                deleted += ReduceListsSingleItemOnList(dataLists, i2);
            }
            return(deleted);
        }
示例#12
0
 private void PerformListReduction(SkyscraperNxNDataLists dataLists)
 {
     while (true)
     {
         //redukcja w poziomie i pionie wszystkich list
         while (ReduceListsHorizVert(dataLists) > 0)
         {
             ;
         }
         //redukcje par przeciwleglych
         if (ReduceListsOpposite(dataLists) == 0)
         {
             return;
         }
     }
 }
示例#13
0
        private int ReduceListOppositePair(SkyscraperNxNDataLists dataLists, int i1, int i2)
        {
            int deleted = ReduceListOppositePairSingle(dataLists, i1, i2);

            int currdeleted = 1;

            while (currdeleted > 0)
            {
                int t = i1;
                i1          = i2;
                i2          = t;
                currdeleted = ReduceListOppositePairSingle(dataLists, i1, i2);
                deleted    += currdeleted;
            }

            return(deleted);
        }
示例#14
0
        private int ReduceListsDir(SkyscraperNxNDataLists dataLists, int nPart, List <int>[][] allowedTop, List <int>[][] allowedBottom)
        {
            int deleted = 0;

            for (int i = 0; i < _n; i++)
            {
                if ((dataLists.Lists[nPart * _n + i] != null) && (dataLists.Lists[nPart * _n + i].Idx.Count > 1))
                {
                    deleted += dataLists.Lists[nPart * _n + i].Idx.RemoveAll(ix => CheckIfPermToRemove(dataLists.Lists[nPart * _n + i].PrecalcData[ix], i, allowedTop, allowedBottom));
                    if (dataLists.Lists[nPart * _n + i].Idx.Count == 1)
                    {
                        ReduceListsSingleItemOnList(dataLists, nPart * _n + i);
                    }
                }
            }
            return(deleted);
        }
示例#15
0
        private int ReduceListsSingleItemOnListSideReduction(SkyscraperNxNDataLists dataLists, int ieq1, int ieq2,
                                                             int inoneq1, int inoneq2, int i, int lvl, int[] row)
        {
            //prostopadle
            int deleted = ReduceListsSingleItemOnListOneNonEq(dataLists, ieq1 * _n + (_n - i - 1), lvl, row[i]);

            deleted += ReduceListsSingleItemOnListOneNonEq(dataLists, ieq2 * _n + i, _n - lvl - 1, row[i]);
            //rownolegle
            if (i != lvl)
            {
                deleted += ReduceListsSingleItemOnListOneEq(dataLists, inoneq1 * _n + i, row, false);
            }
            if (_n - i - 1 != lvl)
            {
                deleted += ReduceListsSingleItemOnListOneEq(dataLists, inoneq2 * _n + i, row, true);
            }
            return(deleted);
        }
示例#16
0
        private int ReduceListsHorizVert(SkyscraperNxNDataLists dataLists)
        {
            //reduce horizontal
            //z list gornych i dolnych wyznaczane dopuszczalne wartosci na pozycjach i na tej podstawie filtrowane listy prawe i lewe
            List <int>[][] allowedTop    = CreateAllowedItemsList(dataLists, 0); //top
            List <int>[][] allowedBottom = CreateAllowedItemsList(dataLists, 2); //bottom

            int deleted = ReduceListsDir(dataLists, 1, allowedTop, allowedBottom);

            deleted += ReduceListsDir(dataLists, 3, allowedBottom, allowedTop);

            //reduce vertical
            //analogicznie, na podstawie prawych i lewych filtrowane listy gorne i dolne
            allowedTop    = CreateAllowedItemsList(dataLists, 1); //right
            allowedBottom = CreateAllowedItemsList(dataLists, 3); //left

            deleted += ReduceListsDir(dataLists, 0, allowedBottom, allowedTop);
            deleted += ReduceListsDir(dataLists, 2, allowedTop, allowedBottom);

            return(deleted);
        }
示例#17
0
        public int[][] Solve(int[] constraints)
        {
            //ograniczenia do logu
            //Console.WriteLine($"{string.Join(", ", constraints)}");

            //redukcja list
            SkyscraperNxNDataLists initData = new SkyscraperNxNDataLists(constraints, _n, _precalc);

            PrepareInitialData(initData);
            SkyscraperData_Perms   data;
            SkyscraperNxNDataLists resLists = ReduceLists(initData, out data);

            if (resLists == null)
            {
                throw new Exception("solution not found");
            }

            //wygenerowanie wynikowej tabeli
            //SkyscraperData_Perms data = new SkyscraperData_Perms(_n);
            //PopulateResultsData(resLists, data);
            return(ConvertToResultTable(data));
        }
示例#18
0
        private int ReduceListsOpposite(SkyscraperNxNDataLists dataLists)
        {
            int deleted = 0;

            //redukcja list przeciwleglych
            //dla listy 1 generowane listy dopuszczalnych wartosci i lista 2 filtrowana na odpowiadajacych pozycjach
            //pionowe
            for (int i = 0; i < _n; i++)
            {
                if ((dataLists.Lists[i] != null) && (dataLists.Lists[GetOppositeListIndex(i)] != null))
                {
                    deleted += ReduceListOppositePair(dataLists, i, GetOppositeListIndex(i));
                }
            }
            //poziome
            for (int i = 0; i < _n; i++)
            {
                if ((dataLists.Lists[_n + i] != null) && (dataLists.Lists[GetOppositeListIndex(_n + i)] != null))
                {
                    deleted += ReduceListOppositePair(dataLists, _n + i, GetOppositeListIndex(_n + i));
                }
            }
            return(deleted);
        }