|
| 1 | +""" |
| 2 | +Checkerboard |
| 3 | +Given an array with two numbers, the first being the number of rows and the second being the number of columns, return a matrix (an array of arrays) filled with "X" and "O" characters of the given size. |
| 4 | +
|
| 5 | +The characters should alternate like a checkerboard. |
| 6 | +The top-left cell must always be "X". |
| 7 | +For example, given [3, 3], return: |
| 8 | +
|
| 9 | +[ |
| 10 | + ["X", "O", "X"], |
| 11 | + ["O", "X", "O"], |
| 12 | + ["X", "O", "X"] |
| 13 | +] |
| 14 | +""" |
| 15 | + |
| 16 | +import unittest |
| 17 | + |
| 18 | +class CheckboardTest(unittest.TestCase): |
| 19 | + |
| 20 | + def test1(self): |
| 21 | + self.assertEqual(create_board([3, 3]), [["X", "O", "X"], ["O", "X", "O"], ["X", "O", "X"]]) |
| 22 | + |
| 23 | + def test2(self): |
| 24 | + self.assertEqual(create_board([6, 1]), [["X"], ["O"], ["X"], ["O"], ["X"], ["O"]]) |
| 25 | + |
| 26 | + def test3(self): |
| 27 | + self.assertEqual(create_board([2, 10]), [["X", "O", "X", "O", "X", "O", "X", "O", "X", "O"], ["O", "X", "O", "X", "O", "X", "O", "X", "O", "X"]]) |
| 28 | + |
| 29 | + def test4(self): |
| 30 | + self.assertEqual(create_board([5, 4]), [["X", "O", "X", "O"], ["O", "X", "O", "X"], ["X", "O", "X", "O"], ["O", "X", "O", "X"], ["X", "O", "X", "O"]]) |
| 31 | + |
| 32 | + |
| 33 | + |
| 34 | +def create_board(dimenstions): |
| 35 | + |
| 36 | + rows, cols = dimenstions |
| 37 | + spot = "X" |
| 38 | + checker_board = [] |
| 39 | + for r in range(rows): |
| 40 | + row_board = [] |
| 41 | + for c in range(cols): |
| 42 | + if spot == "X": |
| 43 | + row_board.append(spot) |
| 44 | + spot = "O" |
| 45 | + else: |
| 46 | + row_board.append(spot) |
| 47 | + spot = "X" |
| 48 | + checker_board.append(row_board) |
| 49 | + |
| 50 | + return checker_board |
| 51 | + |
| 52 | + |
| 53 | +""" |
| 54 | +Checkerboard bug : |
| 55 | +
|
| 56 | +This is close, but the core bug is that the variable spot is global across the entire board. |
| 57 | +It flips with every cell, including across row boundaries, so the start of each new row depends on how |
| 58 | +the previous row ended. That breaks the rule "top-left is X and characters alternate like a checkerboard, because every row must start with |
| 59 | +X if the number of columns is odd, and with alternating X/O if even, based on row party. |
| 60 | +
|
| 61 | +=> Root cause: spot isn't reset at the start of each row. |
| 62 | +=> Symptom: Rows may start with O when they should start with X (or vice versa,) depending on the last cell of teh previous row. |
| 63 | +
|
| 64 | +=> Correct rule: Cell (r, c) is X if (r + c) % 2 == 0, else O. |
| 65 | +Alternatively, recompute the row's starting spot per row from parity. |
| 66 | +
|
| 67 | +
|
| 68 | +""" |
| 69 | + |
| 70 | +# Parity-based (cleanest) |
| 71 | +def create_board(dimensions): |
| 72 | + rows , cols = dimensions |
| 73 | + checker_board = [] |
| 74 | + |
| 75 | + for r in range(rows): |
| 76 | + row_board = [] |
| 77 | + for c in range(cols): |
| 78 | + row_board.append("X" if (r + c) % 2 == 0 else "O") |
| 79 | + |
| 80 | + checker_board.append(row_board) |
| 81 | + |
| 82 | + return checker_board |
| 83 | + |
| 84 | + |
| 85 | +""" |
| 86 | +Edge cases: |
| 87 | +
|
| 88 | +Top-left constraint: with either fix, (0, 0) is always "X". |
| 89 | +
|
| 90 | +=> Odd vs even columns: |
| 91 | + => if ccols is odd, each new row must start with the opposite of the previous row to |
| 92 | + maintain the checkerboard. The parity formula handles this automatically. |
| 93 | +
|
| 94 | + => if cols is even, each row starts with the same as the previous row, parity formula also handles this. |
| 95 | +""" |
| 96 | +# Reset spot each row(previous flip style) |
| 97 | +def create_board_flip(dimensions): |
| 98 | + |
| 99 | + rows, cols = dimensions |
| 100 | + |
| 101 | + checker_board = [] |
| 102 | + |
| 103 | + for r in range(rows): |
| 104 | + # Start each row based on row parity: even rows start with "X", odd tiwh "O" |
| 105 | + spot = "X" if r % 2 == 0 else "O" |
| 106 | + row_board = [] |
| 107 | + for _ in range(cols): |
| 108 | + row_board.append(spot) |
| 109 | + spot = "O" if spot == "X" else "X" |
| 110 | + checker_board.append(row_board) |
| 111 | + |
| 112 | + |
| 113 | + return checker_board |
0 commit comments