Tuesday, August 30, 2016

Mini Parser for NestedInteger

Question:
Given a nested list of integers represented as a string, implement a parser to deserialize it.
Each element is either an integer, or a list -- whose elements may also be integers or other lists.
Note: You may assume that the string is well-formed:
  • String is non-empty.
  • String does not contain white spaces.
  • String contains only digits 0-9, [, - ,, ].
The following NestedInteger interface is already provided:
 /**
 * // This is the interface that allows for creating nested lists.
 * // You should not implement it, or speculate about its implementation
 * interface NestedInteger {
 *
 *     // Constructor initializes an empty nested list.
 *     public NestedInteger();
 *
 *     // Constructor initializes a single integer.
 *     public NestedInteger(int value);
 *
 *     // @return true if this NestedInteger holds a single integer, rather than a nested list.
 *     bool IsInteger();
 *
 *     // @return the single integer that this NestedInteger holds, if it holds a single integer
 *     // Return null if this NestedInteger holds a nested list
 *     int GetInteger();
 *
 *     // Set this NestedInteger to hold a single integer.
 *     public void SetInteger(int value);
 *
 *     // Set this NestedInteger to hold a nested list and adds a nested integer to it.
 *     public void Add(NestedInteger ni);
 *
 *     // @return the nested list that this NestedInteger holds, if it holds a nested list
 *     // Return null if this NestedInteger holds a single integer
 *     IList<NestedInteger> GetList();
 * }
 */


Example 1:
Given s = "324",

You should return a NestedInteger object which contains a single integer 324.

Example 2:
Given s = "[123,[456,[789]]]",

Return a NestedInteger object containing a nested list with 2 elements:

1. An integer containing value 123.
2. A nested list containing two elements:
    i.  An integer containing value 456.
    ii. A nested list with one element:
         a. An integer containing value 789.

Answer: The way we go about solving this is to read the string character by character and perform 
an operation based on the character. It is a state machine where the state may change based on 
whatever the current input character is. Important transitions happen when characters like '[', ']', 
',' are seen. We use a stack to keep track of the parent at any point of time.

Solution is as follows:

public NestedInteger Deserialize(string s) 
{
       if (string.IsNullOrEmpty(s))
        {
            return null;
        }
        
        var st = new Stack<NestedInteger>();
        int value = 0;
        int numDigits = 0;
        NestedInteger curr = null;
        NestedInteger rtnValue = null;
        var negativeMultiplier = 1;
        
        for (int i = 0; i < s.Length; i++)
        {
            // A new NestedInteger object needs to be created. 
            if (s[i] == '[')
            {
                value = 0;
                var n = new NestedInteger();

                // This is the first object/outer-most from the string
                if (rtnValue == null)
                {
                    rtnValue = n;
                }
                else
                {
                    curr.Add(n);
                    st.Push(curr);
                }
                
                curr = n;
            }
            else if (s[i] == ',')
            {
                if (numDigits > 0)
                {
                    var n = new NestedInteger(negativeMultiplier * value);
                    curr.Add(n);
                }
                value = 0;
                negativeMultiplier = 1;
                numDigits = 0;
            }
            else if (s[i] == ']')
            {
                if (numDigits > 0)
                {
                    var n = new NestedInteger(negativeMultiplier * value);
                    curr.Add(n);
                }
                value = 0;
                numDigits = 0;
                if (st.Count > 0)
                {
                    curr = st.Pop();
                }
                else
                {
                    curr = null;
                }
                negativeMultiplier = 1;
            }
            else if (s[i] >= '0' && s[i] <='9')
            {
                numDigits++;
                value = value * 10 + int.Parse(s[i].ToString());
            }
            else if (s[i] == '-')
            {
                negativeMultiplier = -1;
            }
            else
            {
                throw new Exception ("Incorrect string");
            }
        }
        
        // This will be executed for something like example 2
        if (rtnValue == null)
        {
            if (numDigits > 0)
            {
                rtnValue = new NestedInteger(negativeMultiplier * value);
            }
            else
            {
                rtnValue = new NestedInteger();
            }
        }
        
        return rtnValue;
    }


Tuesday, August 23, 2016

Eight queens on a chess board

Question: The challenge is to place 8 queens (ministers) on a chess board so that no 2 queens are in the same row or same column or same diagonal. The solution in C# is given below:

The approach is to place a queen at a position only if there are no other queens in the row or column or the diagonals that the new queen is being placed on. In a normal approach, this would be mean checking the row, column and both the diagonals (which would be O(6n) operations - n for rows, n for columns, 2n each for the diagonals). In my approach, I have used 4 arrays - rowArray, colArray, leadingArray and trailingArray, tha last 2 of which are for the diagonals). If any rows of column 0 are filled, the element 0 of the column array will be filled. Similar is the case with row array. While the row and column arrays have a length of 8, the diagonal arrays have a length of 15. This is because we want to cover all the cells being mapped to an array - eg. cell (7, 0) maps to element 0 in the leading array and cells (6, 0) and (7, 1) map to element 1 in the leading array and this goes on. Similar is the case with trailing array.

The approach is as follows - try o put a queen in each of the columns in a row. Once a queen can be successfully be placed, pass the state and try to place a queen in the next row. If a queen cannot be placed in a (row, col) combination, try to move to the next col for the same row and keep continuing. Finally if a queen can be placed in the last row, save the state of the board in the finalist and return. At this point, we remove the queen and try to put it in another location and try again.

class EightQueensOnBoardAllCombinations
    {
        private bool[] rowArray = new bool[8];
        private bool[] colArray = new bool[8];
        private bool[] leadingArray = new bool[15];
        private bool[] trailngArray = new bool[15];
        private List<List<KeyValuePair<int, int>>> finalList = new List<List<KeyValuePair<int, int>>>();
       
        /// <summary>
        /// Method that can be called from an external method
        /// </summary>
        public static void Test()
        {
            var instance = new EightQueensOnBoardAllCombinations();
            instance.Arrange();
        }

        /// <summary>
        /// Entry method to start placing the queens
        /// </summary>
        public void Arrange()
        {
            List<KeyValuePair<int, int>> rtnList;
            for (var row = 0; row <= 7; row++)
            {
                PlaceQueens(0, row, new List<KeyValuePair<int, int>>());
            }
            foreach (var list in finalList)
            {
                PrintBoard(list);
                Console.WriteLine();
            }
            Console.WriteLine("Total number of combinations = {0}", finalList.Count);
        }

        /// <summary>
        /// Prints the board of queens
        /// </summary>
        /// <param name="rtnList"></param>
        private void PrintBoard(List<KeyValuePair<int, int>> rtnList)
        {
            foreach (var kvp in rtnList)
            {
                Console.WriteLine(kvp.Key + ", " + kvp.Value);
                RemoveQueen(kvp.Key, kvp.Value);
            }
        }

        /// <summary>
        /// Given a row where a queen was already placed and the number of queens already placed,
        /// returns a list of KVPs on where queens could be placed, and null if there is no possible combination
        /// </summary>
        /// <param name="num"></param>
        /// <param name="row"></param>
        /// <returns></returns>
        private void PlaceQueens(int num, int row, List<KeyValuePair<int, int>> input)
        {
           
            for (var col = 0; col <= 7; col ++)
            {
                if (PlaceQueen(row, col) == true)
                {
                    var newInput = new List<KeyValuePair<int, int>>();
                    newInput.AddRange(input);
                    newInput.Add(new KeyValuePair<int, int>(row, col));
                    if (num < 7)
                    {
                        PlaceQueens(num + 1, (row + 1) % 8, newInput);
                    }
                    else
                    {
                        finalList.Add(newInput);
                    }
                    RemoveQueen(row, col);
                }
            }
            return;
        }

        /// <summary>
        /// Given a row and column on the chess board, returns true if a queeen could be placed there, else returns false
        /// </summary>
        /// <param name="row"></param>
        /// <param name="col"></param>
        /// <returns></returns>
        private bool PlaceQueen(int row, int col)
        {
            if (rowArray[row] == true)
            {
                return false;
            }
            if (colArray[col] == true)
            {
                return false;
            }
            var leadingDiagonal = col + 7 - row;
            if (leadingArray[leadingDiagonal] == true)
            {
                return false;
            }
            var trailingDiagonal = col + row;
            if (trailngArray[trailingDiagonal] == true)
            {
                return false;
            }
            rowArray[row] = true;
            colArray[col] = true;
            leadingArray[leadingDiagonal] = true;
            trailngArray[trailingDiagonal] = true;
            return true;
        }

        /// <summary>
        /// Method to remove a queen at a row and col on the board
        /// </summary>
        /// <param name="row"></param>
        /// <param name="col"></param>
        private void RemoveQueen(int row, int col)
        {
            rowArray[row] = false;
            colArray[col] = false;
            var leadingDiagonal = col + 7 - row;
            leadingArray[leadingDiagonal] = false;
            var trailingDiagonal = col + row;
            trailngArray[trailingDiagonal] = false;
        }
    }





























































































Thursday, August 11, 2016

Shortest path for knight to move from source to destination on a chess board

Question: You have a chess board and are given source and destination cells. You need to come up with the shortest path for the knight to travel from the source to the destination.

Answer/Explanation: Given a source cell, a knight can travel to all the remaining cells on the chess board. From a given location, a knight has at most 8 possible steps that it can take - we need to ensure that the knight does not leave the boundaries. If we consider each cell to be a node and a move from one cell to another as an edge, we can be build a graph. However in the interest of this problem, we want to build a tree instead - since there is no point getting back to a cell that was already visited. Since we want the shortest path, we want to exhaust all possibilities at a level in the tree before we go to the next level - sounds familiar? We can use a BST to traverse and check if the destination was reached. We also keep track of the parent cell in the BST so as to be able to build the path at the end.

/// <summary>
/// Class to keep track of the cells in the chess board.
/// </summary>
public class Cell:IComparable<Cell>
{
    public int Row { get; set;}

    public int Column { get; set; }

    public Cell Parent { get; set; }

    public int CompareTo(Cell other)
    {
        var otherCell = (Cell)other;
        return (this.Row == otherCell.Row && this.Column == otherCell.Column) ? 0 : 1;
    }

    public override int GetHashCode()
    {
        var key = Row.ToString() + Column.ToString();
        return key.GetHashCode();
    }

    public override bool Equals(object obj)
    {
        var other = obj as Cell;
        return (other != null) && (other.Row == this.Row) && (other.Column == this.Column);
    }
}

/// <summary>
/// Class that has implementation of the logic to move the knight
/// </summary>
public class MoveKnight
{
    public static void Test()
    {
        var src = new Cell() { Row = 4, Column = 5 };
        var dest = new Cell() { Row = 0, Column = 0 };
        var instance = new MoveKnight();
        var result = instance.Move(src, dest);
    }

    /// <summary>
    /// Method that performs the BST and returns one of the shortest paths
    /// for the knight to move from source to destination
    /// </summary>
    /// <param name="source"></param>
    /// <param name="dest"></param>
    /// <returns></returns>
    public List<Cell> Move(Cell source, Cell dest)
    {
        var dict = new Dictionary<Cell, bool>();
        List<Cell> rtnList = null;
        var queue = new Queue<Cell>();
        queue.Enqueue(source);
        dict.Add(source, true);

        while(queue.Count != 0)
        {
            var cell = queue.Dequeue();
            if (cell.Row == dest.Row && cell.Column == dest.Column)
            {
                rtnList = GetList(cell, dict);
                break;
            }

            var moves = GetMoves(cell, dict);
            AddItemsToQueue(queue, moves, cell);
        }

        return rtnList;
    }

    /// <summary>
    /// Returns the list of cells from the dest to the source by backtracking
    /// </summary>
    /// <param name="dest"></param>
    /// <param name="dict"></param>
    /// <returns></returns>
    private List<Cell> GetList(Cell dest, Dictionary<Cell, bool> dict)
    {
        var rtnList = new List<Cell>();
        var parent = dest.Parent;
        rtnList.Add(dest);
        while (parent != null)
        {
            rtnList.Add(parent);
            parent = parent.Parent;
        }
        return rtnList;
    }

    /// <summary>
    /// Adds cells to the queue for BST, this also keeps track of the parent for back tracking
    /// </summary>
    /// <param name="queue"></param>
    /// <param name="list"></param>
    /// <param name="parent"></param>
    private void AddItemsToQueue(Queue<Cell> queue, List<Cell> list, Cell parent)
    {
        foreach (var cell in list)
        {
            cell.Parent = parent;
            queue.Enqueue(cell);
        }
    }

    /// <summary>
    /// Given a source cell and a dictionary of visited cells, 
    /// returns that list of cells that the knight can move to.
    /// </summary>
    /// <param name="source"></param>
    /// <param name="dict"></param>
    /// <returns></returns>
    private List<Cell> GetMoves(Cell source, Dictionary<Cell, bool> dict)
    {
        var rtnValue = new List<Cell>();
        Cell cell = null;
        // top left
        var row = source.Row - 2;
        var col = source.Column - 1;
        cell = new Cell { Row = row, Column = col };
        if (IsValid(row) && IsValid(col) && !dict.ContainsKey(cell))
        {
            rtnValue.Add(cell);
            dict.Add(cell, true);
        }

        // top right
        row = source.Row - 2;
        col = source.Column + 1;
        cell = new Cell { Row = row, Column = col };
        if (IsValid(row) && IsValid(col) && !dict.ContainsKey(cell))
        {
            rtnValue.Add(cell);
            dict.Add(cell, true);
        }

        // left top
        row = source.Row - 1;
        col = source.Column - 2;
        cell = new Cell { Row = row, Column = col };
        if (IsValid(row) && IsValid(col) && !dict.ContainsKey(cell))
        {
            rtnValue.Add(cell);
            dict.Add(cell, true);
        }

        // left bottom
        row = source.Row + 1;
        col = source.Column - 2;
        cell = new Cell { Row = row, Column = col };
        if (IsValid(row) && IsValid(col) && !dict.ContainsKey(cell))
        {
            rtnValue.Add(cell);
            dict.Add(cell, true);
        }

        // right top
        row = source.Row - 1;
        col = source.Column + 2;
        cell = new Cell { Row = row, Column = col };
        if (IsValid(row) && IsValid(col) && !dict.ContainsKey(cell))
        {
            rtnValue.Add(cell);
            dict.Add(cell, true);
        }

        // right bottom
        row = source.Row + 1;
        col = source.Column + 2;
        cell = new Cell { Row = row, Column = col };
        if (IsValid(row) && IsValid(col) && !dict.ContainsKey(cell))
        {
            rtnValue.Add(cell);
            dict.Add(cell, true);
        }

        // bottom left
        row = source.Row + 2;
        col = source.Column - 1;
        cell = new Cell { Row = row, Column = col };
        if (IsValid(row) && IsValid(col) && !dict.ContainsKey(cell))
        {
            rtnValue.Add(cell);
            dict.Add(cell, true);
        }

        // bottom right
        row = source.Row + 2;
        col = source.Column + 1;
        cell = new Cell { Row = row, Column = col };
        if (IsValid(row) && IsValid(col) && !dict.ContainsKey(cell))
        {
            rtnValue.Add(cell);
            dict.Add(cell, true);
        }
        return rtnValue;
    }

    /// <summary>
    /// Checks whether a given a given index is valid on the chess board
    /// </summary>
    /// <param name="rowCol">Input index</param>
    /// <returns></returns>
    private bool IsValid(int rowCol)
    {
        if (rowCol >= 0 && rowCol <=7)
        {
            return true;
        }

        return false;
    }

}




Thursday, July 7, 2016

Locker code with 5-digit key

Question: You are given a locker that takes 5 digits as input. It always uses the last 5 digits as input. For example if 23456 have been entered, it checks if that is correct or else return failure. Now if a number 7 is entered, it reuses the last 4 of the previous number and checks for 34567 to see if that can open the key. The goal of the problem is to enter the least number of keys and open the locker.

Answer: Since we want to try to get to the key with the least number of keystrokes, we need to try to re-use as many numbers as possible from the last entry. So the approach here is to try to find an un-entered number by using as many digits as possible from the last key. In the below example, the key is hard coded as 98345.

class LockerKey
{
    private static string key = "98345";
    private static string sequence;
    private static int numKeysEntered;
    private static int numComparisonsMade;
    private static Dictionary<string, bool> elapsedSet = new Dictionary<string, bool>();

    /// <summary>
    /// This method gets called from an external source to solve for the key
    /// Start with 00000 as the key and then try to find the key
    /// </summary>
    /// <returns>the key</returns>
    public static string Solve()
    {
        sequence = "00000";
        elapsedSet.Add(sequence, true);

        // Using this as an exit condition
        while (numComparisonsMade < 100000)
        {
            for (int i = 1; i <= 4; i++)
            {
                var newKeys = GetKeyOfLength(i, 5);
                if (newKeys != null)
                {
                    var isMatchFound = EnterKeys(newKeys);

                    if (isMatchFound)
                    {
                        var start = sequence.Length - 5;
                        var finalKey = sequence.Substring(start, 5);
                        Console.WriteLine("Match Found: {0}, NumKeyPresses: {1}, NumComparisonsMade: {2}", finalKey, numKeysEntered, numComparisonsMade);
                        return finalKey;
                    }
                    break;
                }
            }
        }
        return null;
    }

    /// <summary>
    /// Checks whether the entered value is the key
    /// </summary>
    /// <returns>true if the last 5 digits make up the key</returns>
    private static bool IsKey()
    {
        numComparisonsMade++;
        var start = sequence.Length - 5; 
        var newKey = sequence.Substring(start, 5);
        elapsedSet.Add(newKey, true);
        if (newKey == key)
        {
            return true;
        }
        return false;
    }

    /// <summary>
    /// Enters keys as represented by the string input
    /// </summary>
    /// <param name="newKeys"></param>
    /// <returns></returns>
    private static bool EnterKeys(string newKeys)
    {
        foreach (char c in newKeys.ToCharArray())
        {
            sequence += c.ToString();
            numKeysEntered++;
        }

        var rtnValue = IsKey();
        return rtnValue;
    }


    private static string GetKeyOfLength(int  length, int maxLength)
    {
        Console.WriteLine("GetKeyOfLength called with {0} and {1}", length, maxLength);
        string appendedString = null;
        var maxValue = Math.Pow(10, length);
        var reuseLength = maxLength - length;
        var reuseStart = sequence.Length - reuseLength;
        var reuseString = sequence.Substring (reuseStart, reuseLength);
        for (int i = 0; i < maxValue; i++)
        {
            appendedString = i.ToString().PadLeft(length, '0');
            var newKey = reuseString + appendedString;
            if (!elapsedSet.Keys.Contains(newKey))
            {
                Console.WriteLine("AppendedString: {0} New Key: {1} i: {2} maxValue: {3}", appendedString, newKey, i, maxValue);
                break;
            }
            else
            {
                appendedString = null;
            }
        }
        return appendedString;
    }
}