Extremely Begineer friendly code in PYTHON
This is my first dicsussion submission post, and I wish it helps someone trying to understand this paticular problem. The approach I have used is not the most e
This is my first dicsussion submission post, and I wish it helps someone trying to understand this paticular problem. The approach I have used is not the most effcient approach and tbh there are some beautiful and much shorter approches to this problem already up. \n\nI took the time to write this post, to help someone who is not able to visualise the problem efficiently. The code is long, but its extremely concise and I have added explainaitions for each and every part without skipping anything. \n\nAny kind of feedback is much appreciated. \n\n\n```\n\nclass Solution(object):\n    def queensAttacktheKing(self, queens, kings): # Note I have changed to input parameter from king to kings\n        max_len, q = self.maxlength(queens, kings), [] # The function maxlength() returns the maximum number among the given list of queens and kings\n        dp = self.FormBoard(queens, kings, max_len)    # FormBoard() function retuns the board of size max_len * max_len\n        for i in range(max_len +1):\n            for j in range(max_len + 1):\n                if dp[i][j] == "Q" and self.Solver(dp, i, j): # Whenever we encounter a queen on the board we call the Solver\n                    q.append([i, j])    # If the co-ordinates of the queen match all the criterias, they are appended in the queue \n        return q # Return the Queue \n\n    def Solver(self, dp, i, j):\n        if i<0 or i>=len(dp) or j<0 or j>=len(dp[0]) or dp[i][j] != "Q":\n            return False \n\n        \'\'\' Now we check all the 8 directions. I have defined two funcitons for doing this task. The first function, CheckDirection, \n            checks the four directions of Left, Right, Up and Down and the second function, CheckDiagonal, checks the four diagonals,\n            Left_up(LU), Left_down(LD), Right_up(RU), and Right_down(RD). If any of the directions return a True, that means the paticular\n            queen can attack the king and hence all the fuction calls are logically OR\'ed\'\'\'\n\n        if self.CheckDirection(\'Left\', i, j, dp) or self.CheckDirection(\'Right\', i, j, dp)   or \\\n           self.CheckDirection(\'Up\', i, j, dp)   or self.CheckDirection(\'Down\', i, j, dp)    or \\\n           self.CheckDiagonal(\'LU\', i, j, dp)    or self.CheckDiagonal(\'LD\', i, j, dp)       or \\\n           self.CheckDiagonal(\'RD\', i, j, dp)    or self.CheckDiagonal(\'RU\', i, j, dp) :\n            return True\n        # If all the directions return a False, the king cannot be attacked by the paticular queen and hence return False\n        return False \n\n    def CheckDirection(self, direction, row, col, dp):\n\n        \'\'\' This function is used to check the four mainstream directions. The four directions are indexd into the dictionary\n            \'direction_mapper\'. Next a queue is defined which holds the start, end, step and static variables of the for loop, for each \n            paticular direction. What I mean by static here is the fact that, if our direction is Up or Down, we move through\n            only the rows and hence the column remain static. Similarly, While moving Right or Left, we move along the columns \n            and the row remains static. So, for each direction I have also added a static variable to signify which part(row or column)\n            remains static while moving in a paticluar direction \'\'\'\n\n        direction_mapper = {\'Left\' : 0, \'Right\' : 1, \'Up\' : 2, \'Down\' : 3}\n\n        \'\'\' The bounds are as follows \n            1. Left : we start one column before the current column(at which the current queen is placed) and go till the first column. Hence, \n                      start = col -1, end = -1 (As end is -1, the for loop stops at 0), step = -1 (We are moving backwards), \n                      static = row (as we move through the columns)\n            2. Right : we start from the next column, of the current column and stop only if we reach the last column. Hence :\n                       start = col+1, end = len(dp[0]) (The last column), step = 1 ( We are moving forwards), static = row (column wise movement)\n            3. Up    : we start from the previous row of the current row and move till the last row. Hence, \n                       start = row - 1, end = -1, step = -1 ( Moving backwards ), static = col (As we move through the rows)\n            4. Down  : we start from the next row of the current row, and move till we reach the last row. hence \n                       start = row + 1, end = len(dp) (Which gives the last row), step = 1 (forward movement), static = col\'\'\'\n\n\n        q = [(col-1, -1, -1, row), (col+1, len(dp[0]), 1, row), (row-1,-1, -1, col), (row+1, len(dp), 1, col)]\n        start, end, step, static = q.pop( direction_mapper[ direction ])\n\n        \'\'\' Now we reach the part where I have declared two flags : flag_queen and flag_king. At each iteration, if a queen is in our path, flag_queen is set to 1\n            and if a king in in our path, flag_king is set to 1. NOTE : for a queen to successfully attack a king, it should encounter a king in its path, \n            before it encounters any other queen. We keep this fact in our mind and at every point of the iteration, we check: IF flag_king is one( Which \n            means we have encountered a king) AND flag_queen is zero ( which means we have not encountered a queen yet), the function returns True, or else False.\n            This check of flags is performed by the CheckFlag() function\'\'\'\n\n\n        flag_queen, flag_king = 0, 0\n        if row == col:\n\n            \'\'\' One non trivial thing which happens is when the row number = column number in the co-ordinates of the queen. During this time\n                I had to explicitly define the loops to ensure that the static column or the row is choosen. This loop works the following way :\n                if row number == column number, it checks the direction. If the direction is Up or Down, The column is set static. Else-If the \n                direction is Left or Right, the row is set static\'\'\'\n\n            if direction == \'Up\' or direction == \'Down\':\n                for i in range(start, end, step):\n                    if dp[i][col] == "Q":                  \n                        flag_queen = 1  # If encountered Queen, flag_queen is set to 1\n                    elif dp[i][col] == "K":\n                        flag_king = 1  # If encountered King, flag_king is set to 2\n                    if self.CheckFlag(flag_queen, flag_king): # Function to check both the flags at every point \n                        return True \n            elif direction == \'Left\' or direction ==\'Right\':\n                for i in range(start, end, step):\n                    if dp[row][i] == "Q":\n                        flag_queen = 1\n                    elif dp[row][i] == "K":\n                        flag_king = 1\n                    if self.CheckFlag(flag_queen, flag_king):\n                        return True \n\n        # This part is for when row number != Column Number\n\n        elif static == row: \n            for i in range(start, end, step):\n                if dp[row][i] == "Q":\n                    flag_queen = 1\n                elif dp[row][i] == "K":\n                    flag_king = 1\n                if self.CheckFlag(flag_queen, flag_king):\n                    return True \n        elif static == col:\n            for i in range(start, end, step):\n                if dp[i][col] == "Q":\n                    flag_queen = 1\n                elif dp[i][col] == "K":\n                    flag_king = 1\n                if self.CheckFlag(flag_queen, flag_king):\n                    return True \n        return False \n\n    def CheckDiagonal(self, direction, row, col, dp):\n\n        \'\'\' Here we define the directions : Left_up (LU), Left_Down(LD), Right_Up(RU) and Right_Down(RD).\n            Here we have 6 variables in each tuple of our queue. First off, there are total of 4 tuples in \n            the queue referring to the four directions. Now each tuple contains : start, end, step, start1, end1, step1.\n            The start, end, step is for the row and start1, end1, step1 is for the column. In a diagonal movement, neither the \n            row nor the column remains static at any point hence we specify the ranges for both row and col\'\'\'\n\n        direction_mapper = {\'LU\' : 0, \'LD\' : 1, \'RU\' : 2, \'RD\' : 3}\n\n        \'\'\'The bounds are :\n\n        1. Left Up    : The row starts from the previous row and ends at the first row with a negative one step \n                        and the column starts from the previous column, going till the first column with a negative step\n        2. Left Down  : The row start from the next row and iterates till it reaches the final row which is (len(dp)) \n                        and the column starts from the previous column all the way to the first column with a negative step \n        3. Right Up   : The row starts from the previous row and iterates all the way to the first, and the column starts from \n                        the next column all the way to the last \n        4. Right Down : The row starts from the next row, and the column too from the next column and they both end at the last\n                        row and column respectively  \'\'\'\n\n\n\n        q = [(row-1, -1, -1, col-1, -1, -1), (row+1, len(dp), 1, col-1, -1, -1), \\\n             (row-1, -1, -1, col+1, len(dp[0]), 1), (row+1, len(dp), 1, col+1, len(dp[0]), 1)]\n        start, end, step, start1, end1, step1 = q.pop( direction_mapper[direction] )\n        flag_queen, flag_king = 0, 0 # Same idea as previous function \n\n        for i, j in zip(range(start, end, step), range(start1, end1, step1)): #zip is used to iterate through both the specified counds of rows and cols Together\n            if dp[i][j] == "Q":\n                flag_queen = 1\n            elif dp[i][j] == "K":\n                flag_king = 1\n            if self.CheckFlag(flag_queen, flag_king):\n                return True\n        return False\n\n    def CheckFlag(self, flag_queen, flag_king): # Trivial defination\n        if flag_queen == 0 and flag_king == 1:\n            return True \n        return False \n\n    def maxlength(self, queens, kings): # This function returns the max number in the given lists \n        length = 0 \n        for queen in queens:\n            length = max(length, queen[0], queen[1], kings[0], kings[1])\n        return length \n\n    def FormBoard(self, queens, kings, max_len): # This returns a board of size max_len * max_len \n        dp = [[0 for _ in range(max_len+1)]for _ in range(max_len+1)]\n        for queen in queens:\n            dp[ queen[0] ][ queen[1] ] = \'Q\'\n        dp[ kings[0] ][ kings[1] ] = \'K\'\n        return dp \n\n\n```\n\nI Hope this explainaition was clear and concise. Thank you for checking it out.
['Python']