Skip to content

Commit 716f750

Browse files
committed
feat(day 130): implement checkerboard matrix generator with correct alternating X/O pattern using row-column parity
1 parent b336e09 commit 716f750

1 file changed

Lines changed: 113 additions & 0 deletions

File tree

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
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

Comments
 (0)