NumTable GetDiagonalDown(NumTable table)
        {
            var tableDiagonalDown = new NumTable();

            // get bottom-left triangle
            for (int row = 0; row < table.Height(); ++row)
            {
                var newList = new NumList();
                for (int col = 0; col + row < table.Width(); ++col)
                {
                    var diagOffset = col;
                    newList.Add(table[row + diagOffset][col]);
                }
                newList.TrimExcess();
                tableDiagonalDown.Add(newList);
            }

            // get top-right triangle
            // offset col by 1 because [0][0] was collected by last loop
            for (int col = 1; col < table.Width(); ++col)
            {
                var newList = new NumList();
                for (int row = 0; row + col < table.Width(); ++row)
                {
                    var diagOffset = col - 1;
                    newList.Add(table[row + diagOffset][col]);
                }
                newList.TrimExcess();
                tableDiagonalDown.Add(newList);
            }
            tableDiagonalDown.TrimExcess();
            return(tableDiagonalDown);
        }
        NumTable GetTopToBottom(NumTable table)
        {
            var tableTopToBottom = new NumTable();

            for (int i = 0; i < table.Width(); ++i)
            {
                NumList listTopToBottom = new NumList();
                for (int row = 0; row < table.Height(); ++row)
                {
                    listTopToBottom.Add(table[row][i]);
                }
                listTopToBottom.TrimExcess();
                tableTopToBottom.Add(listTopToBottom);
            }

            tableTopToBottom.TrimExcess();
            return(tableTopToBottom);
        }
        NumTable GetDiagonalUp(NumTable table)
        {
            var tableDiagonalUp = new NumTable();

            var maxIndexHeight = table.Height() - 1;
            var maxIndexWidth  = table.Width() - 1;

            // get top-left triangle
            for (int row = 0; row > table.Height(); ++row)
            {
                var newList = new NumList();
                for (int col = maxIndexWidth; col >= 0; --col)
                {
                    var diagOffset = col;
                    newList.Add(table[row + diagOffset][col]);
                }
                newList.TrimExcess();
                tableDiagonalUp.Add(newList);
            }

            // get bottom-right triangle
            // offset row by 1 because [0][0] was collected by last loop
            for (int row = 1; row < table.Height(); ++row)
            {
                var newList = new NumList();
                for (int col = maxIndexWidth; col <= maxIndexWidth - col; --col)
                {
                    var diagOffset = maxIndexWidth - col;
                    newList.Add(table[row + diagOffset][col]);
                }
                tableDiagonalUp.Add(newList);
            }

            tableDiagonalUp.TrimExcess();
            return(tableDiagonalUp);
        }