|
| 1 | +""" N-Queens solutions. """ |
| 2 | + |
| 3 | +__author__ = "Caleb Madrigal" |
| 4 | +__date__ = "2015-02-19" |
| 5 | + |
| 6 | +import numpy as np |
| 7 | + |
| 8 | + |
| 9 | +def right_to_left_diagonals_valid(board): |
| 10 | + """ Returns True if there is no more than 1 queen in each diagonal, False otherwise. |
| 11 | +
|
| 12 | + [[ 0. 1. 2. 3. 4. 5. 6. 7.] |
| 13 | + [ 8. 9. 10. 11. 12. 13. 14. 15.] |
| 14 | + [ 16. 17. 18. 19. 20. 21. 22. 23.] |
| 15 | + [ 24. 25. 26. 27. 28. 29. 30. 31.] |
| 16 | + [ 32. 33. 34. 35. 36. 37. 38. 39.] |
| 17 | + [ 40. 41. 42. 43. 44. 45. 46. 47.] |
| 18 | + [ 48. 49. 50. 51. 52. 53. 54. 55.] |
| 19 | + [ 56. 57. 58. 59. 60. 61. 62. 63.]] |
| 20 | +
|
| 21 | + The algorithm works like this: |
| 22 | +
|
| 23 | + TBD |
| 24 | +
|
| 25 | + """ |
| 26 | + |
| 27 | + flat = board.reshape((1, size*size))[0] |
| 28 | + # Check right-to-left diagonals |
| 29 | + for row_index in range(1, size): |
| 30 | + #print("row_index:", row_index) |
| 31 | + index = row_index |
| 32 | + diag_sum = 0 |
| 33 | + for diag_index in range(row_index+1): |
| 34 | + #print("\tdiag_index: {0}, value: {1}".format(index, flat[index])) |
| 35 | + diag_sum += flat[index] |
| 36 | + index += (size - 1) |
| 37 | + if diag_sum > 1: |
| 38 | + return False |
| 39 | + |
| 40 | + col_diag_index = 0 |
| 41 | + diag_lengths = list(range(size-1, 0, -1)) |
| 42 | + for last_col_index in range(2*size-1, size*size-1, size): |
| 43 | + #print("col_index:", last_col_index) |
| 44 | + index = last_col_index |
| 45 | + diag_sum = 0 |
| 46 | + diag_len = diag_lengths[col_diag_index] |
| 47 | + col_diag_index += 1 |
| 48 | + for diag_index in range(diag_len): |
| 49 | + #print("\tdiag_index: {0}, value: {1}".format(index, flat[index])) |
| 50 | + diag_sum += flat[index] |
| 51 | + index += (size - 1) |
| 52 | + if diag_sum > 1: |
| 53 | + return False |
| 54 | + |
| 55 | + return True |
| 56 | + |
| 57 | +def diags_valid(board): |
| 58 | + if not right_to_left_diagonals_valid(board): |
| 59 | + return False |
| 60 | + rotated_board = np.rot90(board) |
| 61 | + return right_to_left_diagonals_valid(rotated_board) |
| 62 | + |
| 63 | + |
| 64 | +def rows_valid(board): |
| 65 | + for row in board: |
| 66 | + if np.sum(row) > 1: |
| 67 | + return False |
| 68 | + return True |
| 69 | + |
| 70 | + |
| 71 | +def cols_valid(board): |
| 72 | + for col_index in len(board): |
| 73 | + if np.sum(board[:,col_index]) > 1: |
| 74 | + return False |
| 75 | + return True |
| 76 | + |
| 77 | + |
| 78 | +def is_valid(board): |
| 79 | + return rows_valid(board) and cols_valid(board) and diags_valid(board) |
| 80 | + |
| 81 | + |
| 82 | +def n_queens(size): |
| 83 | + board = np.zeros((size, size)) |
| 84 | + for row in range(size): |
| 85 | + for col in range(size): |
| 86 | + board[row][col] = size * row + col |
| 87 | + return board |
| 88 | + |
| 89 | +if __name__ == '__main__': |
| 90 | + size = 8 |
| 91 | + solution = n_queens(size) |
| 92 | + print(solution) |
| 93 | + print(diags_valid(solution)) |
| 94 | + |
0 commit comments