2

Suppose I have 10x10 matrix with the following data:

 1     2     3     4     5     6     7     8     9    10 
11    12    13    14    15    16    17    18    19    20 
21    22    23    24    25    26    27    28    29    30 
31    32    33    34    35    36    37    38    39    40 
41    42    43    44     _    46    47    48    49    50 
51    52    53    54    55    56    57    58    59    60 
61    62    63    64    65    66    67    68    69    70 
71    72    73    74    75    76    77    78    79    80 
81    82    83    84    85    86    87    88    89    90 
91    92    93    94    95    96    97    98    99   100

My position is in [4][4]. How can I list the diagonal values from this position?

For example, the expected outcome would be:

[56, 67, 78, 89, 100, 1, 12, 23, 34]
[54, 63, 72, 81, 9, 18, 27, 36]

My current solution

  def next?(index, row, size)
    (((row + index) % size) + 1 ) % size
  end

  (1...chess_size).each do |l|
    next_el, curr_el = next?(l, row, chess_size), (row + l) % chess_size

    # this gets me the first diagnonal. Note that it prints out wrong value
    tmp[0] << chess[curr_el][curr_el]

    # this gets me the values from current row below to up
    tmp[1] << chess[(row + l) % chess_size][row]
    tmp[2] << chess[-l][l]
    tmp[3] << chess[row][(row + l) % chess_size]
  end

Our matrix will always have the same number of rows and columns.

JamieNguyen
  • 291
  • 3
  • 15
Jamy
  • 115
  • 1
  • 9
  • 2
    Try taking whatever your matrix is and do `Matrix[].each(:diagonal).to_a` Look at these links for a better understanding. If they help you out let me know and I will work with you on a soltuion --[Matrix.rb Implementation](https://github.com/ruby/matrix/blob/master/lib/matrix.rb) --[Ruby Matrix Methods&Documentation](https://ruby-doc.org/stdlib-2.5.1/libdoc/matrix/rdoc/Matrix.html#method-c-diagonal) --(https://stackoverflow.com/questions/36417799/getting-two-diagonals-of-a-matrix) – B. Cratty Oct 24 '18 at 17:06
  • @CarySwoveland does the current solution suffice? – B. Cratty Oct 29 '18 at 10:26
  • I assume `chess` is the given array, but `chess_size` and `tmp` are not defined. Incidentally, please ensure all example inputs are valid Ruby objects and have been assigned to a variable. Here you've given a picture of the array, meaning that every reader who wants to run code has to convert it to an actual array (`[[1,2,3...`). Had it been an array we could have just cut and pasted. By assigning it to a variable (e.g. `arr = [[1, 2,....`) readers could refer to the array in code and comments by that variable without having to define it. – Cary Swoveland Oct 29 '18 at 17:01
  • @CarySwoveland Humbledore has provided a solution without creating a matrix. But he claims that it doesn't work for big test cases. – Jamy Oct 30 '18 at 16:18

7 Answers7

4

Generally to get the diagonal values from i and j, you can iterate over i and j at the same time up to one of them would be zero. Hence, the main diagonal is (i-1, j-1), (i-2, j-2), ... up to i, j >= 0 and (i + 1, j + 1), (i +2, j + 2), ... up to i, j <= n. For the antidiagonal is (i - 1, j + 1), (i - 2, j + 2), ... up to i >= 0 and j <= n, and (i + 1, j-1), (i + 2, j - 2), ... up to i <= n and j >= 0.

OmG
  • 18,337
  • 10
  • 57
  • 90
1

I've applied the logic that @OmG provided. Not sure how efficient it would be.

def stackOverflow(matrixSize, *args)
  pos, obstacles = *args
  chess = (1..(matrixSize * matrixSize)).each_slice(matrixSize).to_a
  obstacles.each do |l| chess[l[0]][l[1]] = '_' end
  row, col = pos[:row] - 1, pos[:col] - 1
  chess[row][col] = '♙'
  directions = [[],[],[],[],[],[],[],[]]

  (1...matrixSize).each do |l|
    directions[0] << chess[row + l][col + l] if (row + l) < matrixSize && (col + l) < chess_size
    directions[1] << chess[row - l][col - l] if (row - l) >= 0 && (col - l) >= 0
    directions[2] << chess[row + l][col - l] if (row + l) < matrixSize && (col - l) >= 0
    directions[3] << chess[row - l][col + l] if (row - l) >= 0 && (col + l) < matrixSize
    directions[4] << chess[row + l][col] if row + l < matrixSize
    directions[5] << chess[row - l][col] if row - l >= 0
    directions[6] << chess[row][col + l] if col + l < matrixSize
    directions[7] << chess[row][col - l] if col - l >= 0
  end
end

stackOverflow(5, 3, {row: 4, col: 3}, [[4,4],[3,1],[1,2]] )
nas.engineer
  • 374
  • 2
  • 8
  • @Cary Swoveland Feedback would be appreciated :) – nas.engineer Oct 25 '18 at 16:14
  • After seeing '♙' I was intrigued by your code. Upon running it (v2.5.1), however, I got an exception: `TypeError (no implicit conversion of Symbol into Integer)`. A transcription error, I assume. – Cary Swoveland Oct 26 '18 at 06:02
  • @CarySwoveland Please have a look at my new solution. Problem I'm facing is that it currently wont work on big test cases – nas.engineer Oct 30 '18 at 16:23
1

@CarySwoveland It seems @Jamy is working on another problem from hackerrank queens-attack.

The problem is quite hard because the idea is to never create a matrix in the first place. That is, the test cases become very large, and thus the space complexity will be an issue.

I've changed my implementation, yet still, fail because of timeout issue (this is because test cases become very large). I'm not sure how to make it performant.

Before I show the code. Let me explain what I'm trying to do using illustration:

This is our chess:

   ---------------------------
 |  1     2     3     4     5 |
 |  6     7     8     9    10 |
 | 11    12    13    14    15 |
 | 16    17    18    19    20 |
 | 21    22    23    24    25 |
   ---------------------------

And this is where our queen is located: queen[2][3]

   ---------------------------
 |  1     2     3     4     5 |
 |  6     7     8     9    10 |
 | 11    12    13     ♙    15 |
 | 16    17    18    19    20 |
 | 21    22    23    24    25 |
   ---------------------------

The queen can attack all 8 directions. I.e:

 horizontal(x2): 
   1. from queen position to left         : [13, 12, 11]
   2. from queen position to right        : [15]

 vertical(x2):
   1. from queen position to top          : [9, 4]
   2. from queen position to bottom       : [19, 24]

 diagonal(x2):
   1. from queen position to bottom-right : [20]
   2. from queen position to top-left     : [8, 2]

 diagonal(x2):
   1. from queen position to bottom-left  : [18, 22]
   2. from queen position to top-right    : [10]

Because there are no obstacles within those 8 paths, the queen can attack a total of 14 attacks.

Say we have some obstacles:

   ---------------------------
 |  1     2     3     4     5 |
 |  6     7     x     9    10 |
 | 11     x    13     ♙    15 |
 | 16    17    18    19     x |
 | 21     x    23     x    25 |
   ---------------------------

Now the queen can attack a total of 7 attacks: [13, 18, 19, 15, 10, 9, 4]

Code

MAXI = 10 ** 5

def queens_attack(size, number_of_obstacles, queen_pos, obstacles)
  # exit the function if...

  # size is negative or more than MAXI. Note MAXI has constraint shown in hackerrank
  return if size < 0 || size > MAXI

  # the obstacles is negative or more than the MAXI
  return if number_of_obstacles < 0 || number_of_obstacles > MAXI

  # the queen's position is outside of our chess dimension
  return if queen_pos[:row] < 1 || queen_pos[:row] > size
  return if queen_pos[:col] < 1 || queen_pos[:col] > size

  # the queen's pos is the same as one of the obstacles
  return if [[queen_pos[:row], queen_pos[:col]]] - obstacles == []

  row, col = queen_pos[:row], queen_pos[:col]

  # variable to increment how many places the queen can attack
  attacks = 0

  # the queen can attack on all directions:
  # horizontals, verticals and both diagonals. So let us create pointers
  # for each direction. Once the obstacle exists in the path, make the 
  # pointer[i] set to true
  pointers = Array.new(8, false)
  (1..size).lazy.each do |i|

    # this is the diagonal from queen's pos to bottom-right
    if row + i <= size && col + i <= size && !pointers[0]
      # set it to true if there is no obstacle in the current [row + i, col + i]
      pointers[0] = true unless [[row + i, col + i]] - obstacles != []
      # now we know the queen can attack this pos
      attacks += 1 unless pointers[0]
    end

    # this is diagonal from queen's pos to top-left
    if row - i > 0 && col - i > 0 && !pointers[1]
      # set it to true if there is no obstacle in the current [row - i, col - i]
      pointers[1] = true unless [[row - i, col - i]] - obstacles != []
      # now we know the queen can attack this pos
      attacks += 1 unless pointers[1]
    end

    # this is diagonal from queen's pos to bottom-left
    if row + i <= size && col - i > 0 && !pointers[2]
      pointers[2] = true unless [[row + i, col - i]] - obstacles != []
      attacks += 1 unless pointers[2]
    end

    # this is diagonal from queen's pos to top-right
    if row - i > 0 && col + i <= size && !pointers[3]
      pointers[3] = true unless [[row - i, col + i]] - obstacles != []
      attacks += 1 unless pointers[3]
    end

    # this is verticle from queen's pos to bottom
    if row + i <=size && !pointers[4]
      pointers[4] = true unless [[row + i, col]] - obstacles != []
      attacks += 1 unless pointers[4]
    end

    # this is verticle from queen's pos to top
    if row - i > 0 && !pointers[5]
      pointers[5] = true unless [[row - i, col]] - obstacles != []
      attacks += 1 unless pointers[5]
    end

    # this is horizontal from queen's pos to right
    if col + i <= size && !pointers[6]
      pointers[6] = true unless [[row, col + i]] - obstacles != []
      attacks += 1 unless pointers[6]
    end

    # this is horizontal from queen's pos to left
    if col - i > 0 && !pointers[7]
      pointers[7] = true unless [[row, col - i]] - obstacles != []
      attacks += 1 unless pointers[7]
    end
  end
  p attacks
end

Problem

Now the problem is, I don't know why my code is doing a timeout error from hackerrank. I do know it because of the test case, where the dimension of chess can be 10,000 X 10,000. But dont know what constraint I'm missing.

nas.engineer
  • 374
  • 2
  • 8
  • Why do you think this is Hackerranks "queens attack" problem (other than use of the word "queen")? For one, the statement of the question makes no reference to "obstacles". If, by "timeout", you mean that your code takes too long to complete for a given (unknown) test case, I would think that's an algorithmic efficiency issue, not that you neglected to deal with a particular "constraint". Incidentally, I think we are given the fact that no obstacles share the queen's location. – Cary Swoveland Oct 30 '18 at 17:17
  • @CarySwoveland Because, I remember reading the problem earlier, and was surfing StackOverflow for some clues, and found that this question resembles the logic very much. And it seems Jamy is only asking questions from hackerrank (checked his backlog). I think your right. But my loop is only O(n) though. Isn't this efficient in enough? – nas.engineer Oct 30 '18 at 17:27
  • Ah, yh dude. Sorry about that. I'm actually working on that problem. The solutions in hackerrank are quite complex. Needed some explanation. – Jamy Oct 30 '18 at 17:32
1

This is a solution to the Hackerrank Queen's attack problem.

Code

def count_moves(n, obs, qrow, qcol)
  qdiff = qrow-qcol
  qsum =  qrow+qcol  
  l = u = -1
  r = d =  n
  ul = qdiff >= 0 ? qrow-qcol-1 : -1
  dr = qdiff >= 0 ? n           : qrow+n-qcol
  ur = qsum < n   ? -1          : qrow-n+qcol
  dl = qsum < n   ? qrow+qcol+1 : n
  obs.uniq.each do |i,j|
    case i <=> qrow
    when -1               # up
      case j <=> qcol
      when -1               # up-left
        ul = [ul,i].max
      when 0                # up same col
        u  = [u,i].max
      when 1                # up-right
        ur = [ur,i].max
      end
    when 0                # same row
      j < qcol ? (l = [l,j].max) : r = [r,j].min
    else                  # down
      case j <=> qcol
      when -1               # down-left
        dl = [dl,i].min
      when 0                # down same col
        d  = [d,i].min
      when 1                # down-right
        dr = [dr,i].min
      end
    end
  end
  r + dl + d + dr - l - ul -u - ur - 8
end

Example

Suppose the chess board has 9 rows and columns, with the queen's location shown by the character q and each obstruction shown with the letter o. All other locations are represented by the letter x. We see that the queen has 16 possible moves (7 up and down, 6 left and right, 1 on the up-left to down-right diagonal and 2 on the up-right to down-left diagonal.

arr = [
  %w| x x x x x x x x x |, # 0
  %w| o x x x x x x x x |, # 1
  %w| x o x x x x x x x |, # 2
  %w| x x o x x x x x o |, # 3
  %w| x x x o x x x x x |, # 4
  %w| x x x x x x o x x |, # 5
  %w| o o x x x q x x x |, # 6
  %w| x x x x x x o x x |, # 7
  %w| x x x x x o x x x |  # 8
#     0 1 2 3 4 5 6 7 8   
]

qrow = qcol = nil
obs = []
n = arr.size
arr.each_with_index do |a,i|
  a.each_with_index do |c,j|
    case c
    when 'o'
      obs << [i,j]
    when 'q'
      qrow=i
      qcol=j
    end
  end
end

qrow
  #=> 6
qcol
  #=> 5
obs
  #=> [[1, 0], [2, 1], [3, 2], [3, 8], [4, 3], [5, 6], [6, 0], [6, 1], [7, 6], [8, 5]]

count_moves(n, obs, qrow, qcol)
  #=> 16

Explanation

  • l is the largest column index of an obstruction in the queen's row that is less than the queen's column index;
  • r is the smalles column index of an obstruction in the queens that is greater than the queen's column index;
  • u is the largest largest row index of an obstruction in the queen's column that is less than the queen's row index;
  • d is the smallest row index of an obstruction in the queen's column that is greater than the queen's row index;
  • ul is the greatest row index of an obstruction on the queen's top-left to bottom-right diagonal that is less than the queen's row index;
  • dr is the smallest row index of an obstruction on the queen's top-left to bottom-right diagonal that is greater than the queen's row index;
  • ur is the greatest row index of an obstruction on the queen's top-right to bottom-left diagonal that is less than the queen's row index; and
  • dl is the smallest row index of an obstruction on the queen's top-right to bottom-left diagonal that is greater than the queen's row index.

For the example above, before obstructions are taken into account, these variables are set to the following values.

l  =  0
r  =  9
ul =  0 
u  = -1
ur =  2
dl =  9
d  =  9
dr =  9

Note that if the queen has row and column indices qrow and qcol,

  • i - j = qrow - qcol for all locations [i, j] on the queen's top-left to bottom- right diagonal; and
  • i + j = grow + gcol for all locations [i, j] on the queen's top-right to bottom- left diagonal

We then loop through all (unique) obstructions, determining, for each, whether it is in the queen's row, queen's column, or one of the queen's diagonals and then replaces the value of the applicable variable with it's row or column index if it is "closer" to the queen than the previously-closest location.

If, for example, the obstruction is in the queen's row and its column index j is less than the queen's column index, the following calculation is made:

l = [l, j].max

Similarly, if the obstruction is on the queen's top-left to bottom-right diagonal and its row index i is less than the queen's row index, the calculation would be:

ul = [ul, i].max

After all obstructions from the above example have been considered the variables have the following values.

l  #=>  1
r  #=>  9
ul #=>  4
u  #=> -1
ur #=>  5
dl #=>  9
d  #=>  8
dr #=>  7

Lastly, we compute the total number of squares to which the queen may move.

qcol - l  - 1 +  # left
r - qcol  - 1 +  # right
u - qrow  - 1 +  # up
grow - d  - 1 +  # down
ul - qrow - 1 +  # up-left
ur - qrow - 1 +  # up-right
qrow - dl - 1 +  # down-left
qrow - dr - 1    # down-right

which simplifies to

r + dl + d + dr - l - ul -u - ur - 8
  #=> 9 + 9 + 8 + 7 - 1 - 4 + 1 - 5 - 8 => 16
Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100
0

I've just learned from a comment posted by the OP that I've solved the wrong problem, despite the fact that the OP's question seems quite clear, especially the example, and is consistent with my interpretation. I will leave this solution to the following problem: "Given an array arr such that Matrix(*arr) is an NxM matrix, and a matrix location i,j, return an array [d,a], where elements d and a are elements on the diagonal and antidiagonal that pass through [d,a] but do not include [d,a] and are each rotated so that row index of the first element is i+1 if i < arr.size-1 and is 0 otherwise.

Code

def diagonals(arr, row_idx, col_idx) 
  ncols = arr.first.size
  sum_idx = row_idx+col_idx
  diff_idx = row_idx-col_idx
  a = Array.new(arr.size * arr.first.size) { |i| i.divmod(ncols) } -[[row_idx, col_idx]]
  [a.select { |r,c| r-c == diff_idx }, a.select { |r,c| r+c == sum_idx }].
    map do |b| b.sort_by { |r,_| [r > row_idx ? 0:1 , r] }.
      map { |r,c| arr[r][c] }
    end
end

All elements of the array arr must be equal in size but there is no requirement that arr.size = arr.first.size.

Example

arr = [
  [ 1,  2,  3,  4,  5,  6,  7,  8,  9,  10],
  [11, 12, 13, 14, 15, 16, 17, 18, 19,  20],
  [21, 22, 23, 24, 25, 26, 27, 28, 29,  30],
  [31, 32, 33, 34, 35, 36, 37, 38, 39,  40],
  [41, 42, 43, 44, 45, 46, 47, 48, 49,  50],
  [51, 52, 53, 54, 55, 56, 57, 58, 59,  60],
  [61, 62, 63, 64, 65, 66, 67, 68, 69,  70],
  [71, 72, 73, 74, 75, 76, 77, 78, 79,  80],
  [81, 82, 83, 84, 85, 86, 87, 88, 89,  90],
  [91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
]

diagonals(arr, 4, 4)
  #=> [[56, 67, 78, 89, 100, 1, 12, 23, 34],
  #    [54, 63, 72, 81, 9, 18, 27, 36]]

Explanation

Suppose

arr = (1..16).each_slice(4).to_a
  #=> [[ 1,  2,  3,  4],
  #    [ 5,  6,  7,  8],
  #    [ 9, 10, 11, 12],
  #    [13, 14, 15, 16]]

row_idx = 2
col_idx = 1

The steps are as follows.

a = Array.new(arr.size) { |i| Array.new(arr.first.size) { |j| [i,j] } }
  #=> [[[0, 0], [0, 1], [0, 2], [0, 3]],
  #    [[1, 0], [1, 1], [1, 2], [1, 3]],
  #    [[2, 0], [2, 1], [2, 2], [2, 3]],
  #    [[3, 0], [3, 1], [3, 2], [3, 3]]]
ncols = arr.first.size
  #=> 4
sum_idx = row_idx+col_idx
  #=> 3
diff_idx = row_idx-col_idx
  #=> 1
a = Array.new(arr.size * arr.first.size) { |i| i.divmod(ncols) } - [[row_idx, col_idx]]
  #=> [[0, 0], [0, 1], [0, 2], [0, 3], [1, 0], [1, 1], [1, 2], [1, 3],
  #    [2, 0], [2, 2], [2, 3], [3, 0], [3, 1], [3, 2], [3, 3]]

Select and sort the locations [r, c] on the top-left to bottom-right diagonal that passes through [row_idx, col_idx].

b = a.select { |r,c| r-c == diff_idx }
  #=> [[1, 0], [3, 2]]
c = b.sort_by { |r,_| [r > row_idx ? 0:1 , r] }
  #=> [[3, 2], [1, 0]]

Select and sort the locations [r, c] on the top-right bottom-left diagonal that passes through [row_idx, col_idx].

d = a.select { |r,c| r+c == sum_idx }
  #=> [[0, 3], [1, 2], [3, 0]]
e = d.sort_by { |r,c| [r > row_idx ? 0:1 , r] }
  #=> [[3, 0], [0, 3], [1, 2]]
[c, e].map { |f| f.map { |r,c| arr[r][c] }
  #=> [c, e].map { |f| f.map { |r,c| arr[r][c] } }
  #=> [[15, 5], [13, 4, 7]]
Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100
  • Wow, I'm overwhelmed. I'm gonna put you on hold for a while. I've managed to make this problem work in O(n), using just one loop. But its still not perfect yet. Gonna let u know soon. – Jamy Oct 25 '18 at 12:43
  • Have a close look at @OmG’s O(n) solution. I would have given it had he/she not already done so. My answer is less efficient but may be of interest for other reasons. – Cary Swoveland Oct 25 '18 at 14:36
  • Unfortunately, I can't make it work in O(n). It seems @Humbledore solution looks good. – Jamy Oct 25 '18 at 16:20
0

I've just learned from a comment posted by the OP that I've solved the wrong problem, despite the fact that the OP's question seems quite clear, especially the example, and is consistent with my interpretation. I will leave this solution to the following problem: "Given an array arr such that Matrix(*arr) is an NxM matrix, and a matrix location i,j, return an array [d,a], where elements d and a are elements on the diagonal and antidiagonal that pass through [d,a] but do not include [d,a] and are each rotated so that row index of the first element is i+1 if i < arr.size-1 and is 0 otherwise.

The following approach uses methods from the Matrix class.

Code

require 'matrix'

def diagonals(arr, row_idx, col_idx)      
  [diag(arr, row_idx, col_idx),
   diag(arr.map(&:reverse).transpose, arr.first.size-1-col_idx, row_idx)]
end

def diag(arr, row_idx, col_idx)
  nrows, ncols = arr.size, arr.first.size
  lr = [ncols-col_idx, nrows-row_idx].min - 1
  ul = [col_idx, row_idx].min
  m = Matrix[*arr]
  [*m.minor(row_idx+1,  lr, col_idx+1,  lr).each(:diagonal).to_a,
   *m.minor(row_idx-ul, ul, col_idx-ul, ul).each(:diagonal).to_a]
end

Example

arr = [
  [ 1,  2,  3,  4,  5,  6,  7,  8,  9,  10],
  [11, 12, 13, 14, 15, 16, 17, 18, 19,  20],
  [21, 22, 23, 24, 25, 26, 27, 28, 29,  30],
  [31, 32, 33, 34, 35, 36, 37, 38, 39,  40],
  [41, 42, 43, 44, 45, 46, 47, 48, 49,  50],
  [51, 52, 53, 54, 55, 56, 57, 58, 59,  60],
  [61, 62, 63, 64, 65, 66, 67, 68, 69,  70],
  [71, 72, 73, 74, 75, 76, 77, 78, 79,  80],
  [81, 82, 83, 84, 85, 86, 87, 88, 89,  90],
  [91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
]

diagonals arr, 4, 4
  #=> [[56, 67, 78, 89, 100, 1, 12, 23, 34], [54, 63, 72, 81, 9, 18, 27, 36]]
diagonals arr, 4, 5
  #=> [[57, 68, 79, 90, 2, 13, 24, 35], [55, 64, 73, 82, 91, 10, 19, 28, 37]]
diagonals arr, 0, 9
  #=> [[], [19, 28, 37, 46, 55, 64, 73, 82, 91]]

Explanation

Suppose the array and target location were as follows.

arr = (1..30).each_slice(6).to_a
  #=> [[ 1,  2,  3,  4,  5,  6],
  #    [ 7,  8,  9, 10, 11, 12],
  #    [13, 14, 15, 16, 17, 18],
  #    [19, 20, 21, 22, 23, 24],
  #    [25, 26, 27, 28, 29, 30]]

row_idx = 2
col_idx = 3

Note arr[2][3] #=> 16. We obtain the diagonal with negative slope by computing the diagonals of two matrix minors:

[[23, 24],
 [29, 30]]

and

[[2, 3],
 [8, 9]]

giving us

[*[23, 30], *[2, 9]]
  #=> [23, 30, 2, 9]

To obtain the other diagonal we rotate the array anti-clockwise 90 degrees, adjust row_idx and col_idx and repeat the above procedure.

arr.map(&:reverse).transpose
  #=> [[6, 12, 18, 24, 30],
  #    [5, 11, 17, 23, 29],
  #    [4, 10, 16, 22, 28],
  #    [3,  9, 15, 21, 27],
  #    [2,  8, 14, 20, 26],
  #    [1,  7, 13, 19, 25]]

ncols = arr.first.size
  #=> 6
row_idx, col_idx = ncols-1-col_idx, row_idx
  #=> [2, 2]

We now extract the diagonals from the matrix minors

[[21, 27],
 [20, 26]]

and

[[6, 12],
 [5, 11]]

to obtain the second diagonal:

[21, 26, 6, 11]
Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100
0
def possible_moves(val):
  # val is a value between 0 and n*n-1
  for i in range(n*n):
    if i == val:
      board[i // n][i % n] = 'Q'
      continue
    #mark row and column with a dot
    if i % n == val % n or i // n == val // n: 
      board[i//n][i%n] = '.'

    # mark diagonals with a dot
    if i % (n + 1) == val % (n + 1) and abs(i % n - val % n) == abs(i // n - val // n): 
      board[i//n][i%n] = '.'
    if i % (n - 1) == val % (n - 1) and abs(i % n - val % n) == abs(i // n - val // n):
      board[i//n][i%n] = '.'

n = 10 #board size = n x n
board = [['0' for x in range(n)] for y in range(n)] #initialize board with '0' in every row and col

possible_moves(40)

At the end you will have a 'Q' where the queen s positioned, '0' where the Q cannot movea and '.' where she can moves