refactor(curriculum): restructure sudoku solver python project (#54303)

Co-authored-by: zairahira <33151350+zairahira@users.noreply.github.com>
Co-authored-by: Sem Bauke <semboot699@gmail.com>
This commit is contained in:
Dario-DC
2024-05-07 17:26:09 +02:00
committed by GitHub
parent 8f9913d02b
commit 17f2e184bd
157 changed files with 5531 additions and 6283 deletions

View File

@@ -11,320 +11,316 @@
"superBlock": "scientific-computing-with-python",
"challengeOrder": [
{
"id": "656873ffdc638f7e290f60de",
"id": "66068fb0bfddba2b7977eb60",
"title": "Step 1"
},
{
"id": "656874efd5102b81815c8ef7",
"id": "66069167b3307b2f4067b22b",
"title": "Step 2"
},
{
"id": "65688efcc78c9495e73acfc9",
"id": "6606927d010be4300a4e5330",
"title": "Step 3"
},
{
"id": "65688f22703200963a85dfb7",
"id": "6606933d6813a8308c962dd1",
"title": "Step 4"
},
{
"id": "65688f737b0ef396bf0c22d6",
"id": "660699119472f332798860ad",
"title": "Step 5"
},
{
"id": "65688f93a1b6e9970f710f62",
"id": "660699aabc59c532f2d556e5",
"title": "Step 6"
},
{
"id": "65688fc27e8dda9760c45d7d",
"id": "66069b0b36053733a2f012fe",
"title": "Step 7"
},
{
"id": "65689020cfd5279803976b25",
"id": "66069b992c1c5e3451f3deb0",
"title": "Step 8"
},
{
"id": "6568904b83a2f29878578146",
"id": "66069d65162e61357c793e0c",
"title": "Step 9"
},
{
"id": "6568917528820d99236ad811",
"id": "66069e5759b800364707988e",
"title": "Step 10"
},
{
"id": "656896ffecbf07a2d3402a93",
"id": "66069f86f58f85371d47123e",
"title": "Step 11"
},
{
"id": "6568991b4d4874a4d5271337",
"id": "6606a219f9efbf38ad496f67",
"title": "Step 12"
},
{
"id": "6568994faf481da5d37bfa40",
"id": "6606a2f8a6a36f39518e0439",
"title": "Step 13"
},
{
"id": "6568997f94c673a68b035b60",
"id": "6606a3ccb1eea93a23c066bf",
"title": "Step 14"
},
{
"id": "656899c0478950a7e5db2cc0",
"id": "6606a4641ec48b3a9fe8c2fc",
"title": "Step 15"
},
{
"id": "656899f4214ee6a881bc8649",
"id": "6606b0d602d1e33e81bcef0d",
"title": "Step 16"
},
{
"id": "65689a748de8fbaa00c5617e",
"id": "6606b224a69a293f98f8db8f",
"title": "Step 17"
},
{
"id": "65689aa3d3f2b6aad204a59e",
"id": "6606b63c0fd55e4314d2ec85",
"title": "Step 18"
},
{
"id": "65689ad61dfa81ab9ffafc86",
"id": "6606b6b7760d0643c3b4eb29",
"title": "Step 19"
},
{
"id": "65689b055e6f49ac6f82d3cf",
"id": "6606b8d31356fe4563f0e99c",
"title": "Step 20"
},
{
"id": "6568a242a3e1efc22b07274d",
"id": "6606b961ebcf04460f8af76e",
"title": "Step 21"
},
{
"id": "6568bb1ffe8462c427c0d386",
"id": "6606baaf1828ff46ebcc008c",
"title": "Step 22"
},
{
"id": "6568bb656c67e9c54cced2d7",
"id": "6606bbd52233b247cf0a56e4",
"title": "Step 23"
},
{
"id": "6568bba429481cc693fc2570",
"id": "6606bc4e5535c0484990ccd5",
"title": "Step 24"
},
{
"id": "6568bbc8c3bda1c773e23cf1",
"id": "6606bd3d02e86548d3ce1a0a",
"title": "Step 25"
},
{
"id": "6568bc19f3418dc8a8821187",
"id": "6606beade9200b49aaeecd94",
"title": "Step 26"
},
{
"id": "6568bc85c5beadca3e0f6eb1",
"id": "6606bf4561f8794a0d345919",
"title": "Step 27"
},
{
"id": "6568bd3741e379ccc220af1b",
"id": "6606c05b5624a54ab85808fa",
"title": "Step 28"
},
{
"id": "6568bd85482755cdd26443ae",
"id": "6606c0dd3293064b30d17a72",
"title": "Step 29"
},
{
"id": "6568bdb69e05a9cee01068a8",
"id": "6606c14182435d4bab0de2ee",
"title": "Step 30"
},
{
"id": "6568beebba98a3d1f26f6bf8",
"id": "6606c2d203a8124c83b2234b",
"title": "Step 31"
},
{
"id": "6568bf22bb5de0d2e8260cf3",
"id": "6606c3fd5634684d48a7887b",
"title": "Step 32"
},
{
"id": "6568bf5e5b2f4bd3eb7ef995",
"id": "6606cb019db4f74f224856f4",
"title": "Step 33"
},
{
"id": "6568bf853bf06dd4ed25d4ca",
"id": "6606cc088fd3574fa9010a4f",
"title": "Step 34"
},
{
"id": "6568bfb601a54ed5b367b44f",
"id": "6606cc473675e85017b0c53d",
"title": "Step 35"
},
{
"id": "6568bfd65322add674039bde",
"id": "6606cc754a8834509cd0afb6",
"title": "Step 36"
},
{
"id": "6568c0013b3b62d7617518c7",
"id": "6606cd69f56e27516583b0cc",
"title": "Step 37"
},
{
"id": "6568c024933423d85d5ed93c",
"id": "6606cf1b2b9f65529c161098",
"title": "Step 38"
},
{
"id": "6568c073d5f37fd99ab2ab0c",
"id": "6606d03ff198245383e61d90",
"title": "Step 39"
},
{
"id": "6568c0a5edddc3daa65d20b2",
"id": "6606d32096165654b8e73f21",
"title": "Step 40"
},
{
"id": "6569d83fe4dcc614c2ff971d",
"id": "6606d378de78d55523f08298",
"title": "Step 41"
},
{
"id": "6569d8a4b8d85515cbb1ce72",
"id": "6606d589750ad655fa0df168",
"title": "Step 42"
},
{
"id": "6569d946293d4f185e32e2da",
"id": "6606d6138c49e456920fa818",
"title": "Step 43"
},
{
"id": "6569d98303af38193149b66e",
"id": "6606d7bb9e4c6b574235159a",
"title": "Step 44"
},
{
"id": "6569d9dfd53db11b176d2963",
"id": "6606d8795bd533582425a363",
"title": "Step 45"
},
{
"id": "6569da02e7e2641be14ff922",
"id": "6606d8c323d6205890fbbd54",
"title": "Step 46"
},
{
"id": "6569de93a5340b202667deda",
"id": "6606d9d92fcf78598b3b5184",
"title": "Step 47"
},
{
"id": "6569def38470282151f873ce",
"id": "6606db6a23a1455a402f91ae",
"title": "Step 48"
},
{
"id": "6569df1d6fb83d22623b38c5",
"id": "6606dcf5a31e4e5b43737417",
"title": "Step 49"
},
{
"id": "6569df6916294723e01f0035",
"id": "6606dd63109f9f5c2195e30c",
"title": "Step 50"
},
{
"id": "6569df9e20f74a251d482c5d",
"id": "6606de006a82e05c9a65cebe",
"title": "Step 51"
},
{
"id": "6569dffeee007f26d2b56d46",
"id": "6606e2f27f19ca5f398c6aed",
"title": "Step 52"
},
{
"id": "6569e2a01a97b231862ba2ff",
"id": "6606e3e6231702600bd5860c",
"title": "Step 53"
},
{
"id": "6569e2e1944fe7329ab21c7f",
"id": "660a737f0f72b51de361051c",
"title": "Step 54"
},
{
"id": "6569e309feb5d333867a034a",
"id": "660a7a1cac69b7217cbae22d",
"title": "Step 55"
},
{
"id": "6569e33a708a3834f6d4879b",
"id": "660a7cb75dce3d22ab562c0d",
"title": "Step 56"
},
{
"id": "6569e37ec28e853628f18a86",
"id": "660a7ea6e3a21a243d6aa288",
"title": "Step 57"
},
{
"id": "6569e3a134fea0371fa008de",
"id": "660a7f28d5ce6a24ef856a50",
"title": "Step 58"
},
{
"id": "6569e3d1418b373839a0aa7b",
"id": "660a8b6cd8de406ae82ce910",
"title": "Step 59"
},
{
"id": "6569e41657a9923953aa7d3c",
"id": "660a8c3b21100c6b83e57cb0",
"title": "Step 60"
},
{
"id": "6569e481e67f123ad25c5d20",
"id": "660a8d7c5f33c16c67e58b37",
"title": "Step 61"
},
{
"id": "6569f6b48716b5402504e216",
"id": "660a8ef6b7571f6dddc3553b",
"title": "Step 62"
},
{
"id": "6569f6ebe558bd4136da96cc",
"id": "660a92e93854486efa68fe6f",
"title": "Step 63"
},
{
"id": "6569f70a66ccdc42097ca051",
"id": "660a937220bf966fd844f1ee",
"title": "Step 64"
},
{
"id": "6569f770fd7dc443d6293095",
"id": "660a940b3379fb708a83593a",
"title": "Step 65"
},
{
"id": "6569f7c7f6954944d207775f",
"id": "660a94f55c3c9b71a37e1c8b",
"title": "Step 66"
},
{
"id": "6569f7f2fa74c045e95676ac",
"id": "660a957f44c096728ba9c41f",
"title": "Step 67"
},
{
"id": "6569fa5b9d507748bf4ec722",
"id": "660a95c3da857673124ed698",
"title": "Step 68"
},
{
"id": "6569fa85d8f9ed49c8dfb37d",
"id": "660a968ca0838773c9bbfc85",
"title": "Step 69"
},
{
"id": "6569fabbfe1c094ad838ec4c",
"id": "660a9819ad113774d65a1e7c",
"title": "Step 70"
},
{
"id": "6569fbbfee025a4e850b6eaf",
"id": "660ac1d158923e805d3c3099",
"title": "Step 71"
},
{
"id": "6569fc21837cab5029d82e26",
"id": "660ac2873b090d80d6aa6ce2",
"title": "Step 72"
},
{
"id": "6569fc63a404c8519d918095",
"id": "660ac35d55a15d81afdedd76",
"title": "Step 73"
},
{
"id": "6569fca3cd7a9f52f322a298",
"id": "660ac44c7eec868220318297",
"title": "Step 74"
},
{
"id": "6569fd01dab2ea547d98f093",
"id": "660ac4f4f784b9829e89632a",
"title": "Step 75"
},
{
"id": "6569fd352879475599d0ec66",
"id": "660ac56326c2eb831583c0de",
"title": "Step 76"
},
{
"id": "6569fd6d3cb95856c9ed2190",
"id": "660ac59d7ea60083900b83df",
"title": "Step 77"
},
{
"id": "6569fdc59fe1b658bc9e23a4",
"id": "660ac60e22aa218400acb4b6",
"title": "Step 78"
},
{
"id": "6569fe0fe5b5425a1bb1f534",
"title": "Step 79"
}
],
"helpCategory": "Python"

View File

@@ -1,39 +0,0 @@
---
id: 656874efd5102b81815c8ef7
title: Step 2
challengeType: 20
dashedName: step-2
---
# --description--
A new instance of a class is created by using the function notation: `ClassName()`. The instantiation creates an empty object. Classes can have methods, which are like local functions for each instance. Methods are declared as follows:
```python
class ClassName:
def method_name():
pass
```
The `__init__` method is a special method that allows you to instantiate an object to a customized state. When a class implements an `__init__` method, `__init__` is automatically called upon instantiation.
Create an `__init__` method inside your `Board` class.
# --hints--
Your method should be named `__init__`. Don't add any parameters.
```js
assert.match(code, / +def\s+__init__\s*\(\s*\)\:/);
```
# --seed--
## --seed-contents--
```py
--fcc-editable-region--
class Board:
--fcc-editable-region--
```

View File

@@ -1,33 +0,0 @@
---
id: 65688efcc78c9495e73acfc9
title: Step 3
challengeType: 20
dashedName: step-3
---
# --description--
Add two parameters to the `__init__` method, order matters:
- `self`: This is a reference to the instance of the class. It is a convention to name this parameter self.
- `board`: The board parameter is expected to be passed when creating an instance of the `Board` class.
# --hints--
You should add the parameter `self` and `board` to the method.
```js
assert.match(code, /def\s+__init__\s*\(\s*self\s*,\s*board\s*\):/);
```
# --seed--
## --seed-contents--
```py
--fcc-editable-region--
class Board:
def __init__():
--fcc-editable-region--
```

View File

@@ -1,32 +0,0 @@
---
id: 65688f22703200963a85dfb7
title: Step 4
challengeType: 20
dashedName: step-4
---
# --description--
Inside the `__init__` method, assign the value of the `board` parameter (which is passed when creating an instance of the `Board` class) to an instance variable named `board` using `self.board`.
`self.board` refers to the board attribute of the instance of the class. It's a variable that belongs to the object created from the `Board` class.
# --hints--
You should have `self.board = board` within the `__init__` method.
```js
assert.match(code, /self\.board\s*=\s*board/);
```
# --seed--
## --seed-contents--
```py
--fcc-editable-region--
class Board:
def __init__(self, board):
--fcc-editable-region--
```

View File

@@ -1,60 +0,0 @@
---
id: 65688f737b0ef396bf0c22d6
title: Step 5
challengeType: 20
dashedName: step-5
---
# --description--
Now you will move to the actual construction of the board, which is a 9x9 grid.
The input puzzle would look like this:
```py
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
```
The resulting grid would look like this:
<img class="img-responsive" alt="a board of sudoku" src="https://cdn.freecodecamp.org/curriculum/python/sample-board.png" style="background-color: white; height:300px; width:300px; padding: 10px;">
Define a method `__str__` within the `Board` class. Also, add the `self` parameter. This method is automatically called when you use the `str()` function on an instance of the class or when you use `print()` with the object.
# --hints--
Your method should be named `__str__`.
```js
assert.match(code, /def\s+__str__\s*\(/);
```
You should add the parameter `self` to the method.
```js
assert.match(code, /def\s+__str__\s*\(\s*self\s*\)\s*:/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -1,35 +0,0 @@
---
id: 65688f93a1b6e9970f710f62
title: Step 6
challengeType: 20
dashedName: step-6
---
# --description--
To create the top border of the board, create an `upper_lines` variable and assign it the value of `f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}╗\n'`.
This string represents the top border of the sudoku board in a visually appealing ASCII art style. It uses special Unicode characters to draw the borders and intersections.
# --hints--
Assign the value of `f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}╗\n'` to a variable named `upper_lines`.
```js
({ test: () => assert.match(code, /upper_lines\s*=\s*f("|')\\n╔═══\{\s*(?=[^\1])("|')╤═══\2\s*\*\s*2\s*\}\{\s*\2╦═══\2\s*\}\{\s*\2╤═══\2\s*\*\s*2\s*\}\{\s*\2╦═══\2\s*\}\{\s*\2╤═══\2\s*\*\s*2\s*\}╗\\n\1/m) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
--fcc-editable-region--
def __str__(self):
--fcc-editable-region--
```

View File

@@ -1,34 +0,0 @@
---
id: 65688fc27e8dda9760c45d7d
title: Step 7
challengeType: 20
dashedName: step-7
---
# --description--
To create middle borders of the sudoku board, create a `middle_lines` variable and assign it the value of `f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}╢\n'`.
# --hints--
You should assign the value of `f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}╢\n'` to a variable named `middle_lines`.
```js
({ test: () => assert.match(code, /middle_lines\s*=\s*f("|')╟───\{\s*(?=[^\1])("|')┼───\2\s*\*\s*2\s*\}\{\s*\2╫───\2\s*\}\{\s*\2┼───\2\s*\*\s*2\s*\}\{\s*\2╫───\2\s*\}\{\s*\2┼───\2\s*\*\s*2\s*\}╢\\n\1/m) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
--fcc-editable-region--
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
--fcc-editable-region--
```

View File

@@ -1,35 +0,0 @@
---
id: 65689020cfd5279803976b25
title: Step 8
challengeType: 20
dashedName: step-8
---
# --description--
To create the bottom border of the sudoku board, create a `lower_lines` variable and assign it the value of `f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}╝\n'`.
# --hints--
You should add `lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}╝\n'` to the code.
```js
({ test: () => assert.match(code, /lower_lines\s*=\s*f("|')╚═══\{\s*(?=[^\1])("|')╧═══\2\s*\*\s*2\s*\}\{\s*\2╩═══\2\s*\}\{\s*\2╧═══\2\s*\*\s*2\s*\}\{\s*\2╩═══\2\s*\}\{\s*\2╧═══\2\s*\*\s*2\s*\}╝\\n\1/m) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
--fcc-editable-region--
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
--fcc-editable-region--
```

View File

@@ -1,42 +0,0 @@
---
id: 6568904b83a2f29878578146
title: Step 9
challengeType: 20
dashedName: step-9
---
# --description--
Initialize a `board_string` variable with the content of `upper_lines`. This will be the starting point for building the entire visual representation of the sudoku board.
# --hints--
You should have `board_string = upper_lines` within the `__str__` method.
```js
({ test: () =>
{
const str = __helpers.python.getDef(code.replace(/\r/g, ''), "__str__");
const {function_body} = str;
assert(function_body.match(/board_string\s*=\s*upper_lines/));
}
})
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
--fcc-editable-region--
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
--fcc-editable-region--
```

View File

@@ -1,53 +0,0 @@
---
id: 6568917528820d99236ad811
title: Step 10
challengeType: 20
dashedName: step-10
---
# --description--
Now, you need to go over each row in the sudoku board.
Enumeration is a convenient way to keep track of both the element and its position on a list.
The `enumerate()` function is a built-in function in Python that takes an iterable (such as a list, tuple, or string) and returns an iterator that produces tuples containing indices and corresponding values from the iterable.
Initiate a `for` loop to iterate over each row (`line`) in the sudoku board (`self.board`).
Use enumeration to get both the index (`index`) and the content (`line`) of each row.
The general syntax would be like this:
```js
for x, y in enumerate(parameter):
```
# --hints--
You should have `for index, line in enumerate(self.board):` within the `__str__` method.
```js
assert.match(
code,
/for\s+(\w+)\s*,\s*(?!\1)(\w+)\s+in\s+enumerate\s*\(\s*self\.board\s*\)\s*:/m
);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -1,57 +0,0 @@
---
id: 656896ffecbf07a2d3402a93
title: Step 11
challengeType: 20
dashedName: step-11
---
# --description--
Inside the loop, initialize an empty list `row_list` to store the elements of a single row in the sudoku board.
# --hints--
You should have a `row_list` variable.
```js
({ test: () =>
{
const str = __helpers.python.getDef(code.replace(/\r/g, ''), "__str__");
const {function_body} = str;
assert(function_body.match(/row_list\s*=/));
}
})
```
`row_list` should be an empty list.
```js
({ test: () =>
{
const str = __helpers.python.getDef(code.replace(/\r/g, ''), "__str__");
const {function_body} = str;
assert(function_body.match(/row_list\s*=\s*\[\s*\]/));
}
})
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
--fcc-editable-region--
for index, line in enumerate(self.board):
--fcc-editable-region--
```

View File

@@ -1,48 +0,0 @@
---
id: 6568991b4d4874a4d5271337
title: Step 12
challengeType: 20
dashedName: step-12
---
# --description--
Next, you are going to split each row in three segments, in order to represent the 3x3 squares properly.
Create a nested `for` loop to iterate over each segment of the row. Use `square_no` and `part` as the iterating variable and the `enumerate()` function. For now, leave the `enumerate()` call empty.
# --hints--
The inner loop should have `square_no` as the counter and `part` as the element from iterable.
```js
assert.match(code, /for\s+square_no\s*,\s*part/)
```
You should have `for square_no, part in enumerate()` within the existing `for` loop.
```js
assert.match(code, /for\s+square_no\s*,\s*part\s+in\s+enumerate\s*\(\s*\)\:/)
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
--fcc-editable-region--
for index, line in enumerate(self.board):
row_list = []
--fcc-editable-region--
```

View File

@@ -1,42 +0,0 @@
---
id: 6568994faf481da5d37bfa40
title: Step 13
challengeType: 20
dashedName: step-13
---
# --description--
Now, you need to create the three line segments to pass to the `enumerate` function.
Use list slicing to create the three lists of equal length representing the `line` segment of each 3x3 square and pass them to the `enumerate()` call. Add `start = 1` to start the enumeration from `1` instead of `0`.
# --hints--
You should have `enumerate([line[:3], line[3:6], line[6:]], start=1)` within the inner `for` loop.
```js
assert.match(code, /\[\s*line\s*\[\s*:3\s*\]\s*,\s*line\s*\[\s*3\s*:\s*6\s*\]\s*,\s*line\s*\[\s*6\s*:\s*\]\s*\]\s*,\s*start\s*=\s*1/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
--fcc-editable-region--
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate():
--fcc-editable-region--
```

View File

@@ -1,60 +0,0 @@
---
id: 6568997f94c673a68b035b60
title: Step 14
challengeType: 20
dashedName: step-14
---
# --description--
Now, you would join the elements of the segment (`part`) with the pipe character (`|`).
For that, first, use a `for` loop `for item in part` to access all elements.
Then, use the `join()` method on the `|` character to join the elements of the segment (`part`).
After that, convert each element to a string using `str(item)`.
# --hints--
You should use the `join()` method on the `|` character to join the elements of the segment (`part`).
add test for "" as well
```js
assert.match(code, /('|")\|\1\.join\s*\(/)
```
You should call `str()` on each element in `part` using a generator expression.
```js
({ test: () => assert.match(code, /\(\s*str\s*\(\s*(\w+)\s*\)\s+for\s+\1\s+in\s+part\s*\)/) })
```
You should have `'|'.join(str(item) for item in part)` within the inner `for` loop.
```js
({ test: () => assert.match(code, /("|')\|\1\.join\s*\(\s*str\s*\(\s*(\w+)\s*\)\s+for\s+\2\s+in\s+part\s*\)/m) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
--fcc-editable-region--
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
--fcc-editable-region--
```

View File

@@ -1,41 +0,0 @@
---
id: 656899c0478950a7e5db2cc0
title: Step 15
challengeType: 20
dashedName: step-15
---
# --description--
Assign the joined string to the variable `row_square`.
# --hints--
You should assign the value of `'|'.join(str(item) for item in part)` to a variable named `row_square`.
```js
({ test: () => assert.match(code, /row_square\s*=\s*("|')\|\1\.join\s*\(\s*str\s*\(\s*(\w+)\s*\)\s+for\s+\2\s+in\s+part\s*\)/m) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
--fcc-editable-region--
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
'|'.join(str(item) for item in part)
--fcc-editable-region--
```

View File

@@ -1,42 +0,0 @@
---
id: 656899f4214ee6a881bc8649
title: Step 16
challengeType: 20
dashedName: step-16
---
# --description--
Extend the `row_list` with the elements of the `row_square` string.
# --hints--
You should have `row_list.extend(row_square)` within the innermost `for` loop.
```js
({ test: () => assert.match(code, /row_list\.extend\s*\(\s*row_square\s*\)/m) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
--fcc-editable-region--
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
--fcc-editable-region--
```

View File

@@ -1,44 +0,0 @@
---
id: 65689a748de8fbaa00c5617e
title: Step 17
challengeType: 20
dashedName: step-17
---
# --description--
Within the innermost loop, create an `if` statement to check if the current segment (`square_no`) is not the last one (i.e., not equal to `3`)
# --hints--
You should check if the current segment (`square_no`) is not equal to `3`.
```js
assert.match(code, /if\s+square_no\s*!=\s*3/m)
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
--fcc-editable-region--
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
--fcc-editable-region--
```

View File

@@ -1,45 +0,0 @@
---
id: 65689aa3d3f2b6aad204a59e
title: Step 18
challengeType: 20
dashedName: step-18
---
# --description--
Inside the `if` block, append a `║` character at the end of `row_list`.
# --hints--
You should have `row_list.append('║')` within the `if` statement.
```js
({ test: () => assert.match(code, /row_list\.append\s*\(\s*("|')║\1\s*\)/m) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
--fcc-editable-region--
if square_no != 3:
--fcc-editable-region--
```

View File

@@ -1,48 +0,0 @@
---
id: 65689ad61dfa81ab9ffafc86
title: Step 19
challengeType: 20
dashedName: step-19
---
# --description--
Next, you will create a string representation of the row with spaces between each element.
For that, outside the innermost `for` loop body, create a string `row`. Assign the following formatted string `f'║ {" ".join(row_list)} ║\n'` to it to join the elements of `row_list` with a space in between.
# --hints--
Assign the formatted string `f'║ {" ".join(row_list)} ║\n'` to a variable named `row`.
```js
({ test: () => assert.match(code, /row\s*\=\s*f("|')║\s\{(?!\1)("|')\s\2\.join\s*\(\s*row_list\s*\)\s*\}\s║\\n\1/m) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
--fcc-editable-region--
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
--fcc-editable-region--
```

View File

@@ -1,60 +0,0 @@
---
id: 65689b055e6f49ac6f82d3cf
title: Step 20
challengeType: 20
dashedName: step-20
---
# --description--
When you would pass your input puzzle board, `0` would be used for empty cells.
For a better visual representation, replace the empty cells in a row with a space using the `replace` method.
The `replace()` method takes two arguments, the first one is the character to be replaced and the second one is the character to be replaced with.
After replacing, assign the result to a variable `row_empty`.
# --hints--
You should replace each `0` in the row with a space using the `replace` method.
```js
({ test: () => assert.match(code, /row\.replace\s*\(\s*("|')0\1\s*,\s*("|') \2\s*\)/) })
```
You should have `row_empty = row.repalce('0', ' ')` within the outermost `for` loop.
```js
({ test: () => assert.match(code, /row_empty\s*=\s*row\.replace\s*\(\s*("|')0\1\s*,\s*("|') \2\s*\)/m) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
--fcc-editable-region--
row = f'{" ".join(row_list)}\n'
--fcc-editable-region--
```

View File

@@ -1,49 +0,0 @@
---
id: 6568a242a3e1efc22b07274d
title: Step 21
challengeType: 20
dashedName: step-21
---
# --description--
`board_string` is gradually built up as the loop iterates over each row, creating the full ASCII art representation of the sudoku board.
Add the modified `row_empty` string to the `board_string`.
# --hints--
You should have `board_string += row_empty` within the outermost `for` loop.
```js
({ test: () => assert.match(code, /board_string\s*\+=\s*row_empty/m) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
--fcc-editable-region--
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
--fcc-editable-region--
```

View File

@@ -1,48 +0,0 @@
---
id: 6568bb1ffe8462c427c0d386
title: Step 22
challengeType: 20
dashedName: step-22
---
# --description--
Within the outermost `for` loop, create an `if` statement that checks if the current row index is less than `8`. This is because the last row of the sudoku board has an index of `8`, and you want to handle the last row differently.
# --hints--
You should have `if index < 8:` within the outermost `for` loop.
```js
assert.match(code, /if\s+index\s*<\s*8\s*:/m);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
--fcc-editable-region--
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
--fcc-editable-region--
```

View File

@@ -1,51 +0,0 @@
---
id: 6568bb656c67e9c54cced2d7
title: Step 23
challengeType: 20
dashedName: step-23
---
# --description--
Now, you need to verify if the row is the last row inside a 3x3 square. This occurs when `index % 3` is equal to `2`.
Inside your existing `if` block, nest another `if` to check that condition.
# --hints--
You should have `if index % 3 == 2:` within the `if index < 8` statement.
```js
assert.match(code,/if\s+index\s*%\s*3\s*==\s*2\s*:/m)
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
--fcc-editable-region--
if index < 8:
--fcc-editable-region--
```

View File

@@ -1,53 +0,0 @@
---
id: 6568bba429481cc693fc2570
title: Step 24
challengeType: 20
dashedName: step-24
---
# --description--
If the current row is the last row of a 3x3 square, in order to create a visually appealing border you need to append a different border string to `board_string` .
Inside the `if` statement, add the following string to the current value of `board_string`: `f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}╣\n'`.
# --hints--
You should have `board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}╣\n'` within the `if index % 3 == 2` statement.
```js
assert.match(code, /board_string\s*\+=\s*f("|')╠═══\{\s*(?=[^\1])("|')╪═══\2\s*\*\s*2\s*\}\{\s*\2╬═══\2\s*\}\{\s*\2╪═══\2\s*\*\s*2\s*\}\{\s*\2╬═══\2\s*\}\{\s*\2╪═══\2\s*\*\s*2\s*\}╣\\n\1/)
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
--fcc-editable-region--
if index % 3 == 2:
--fcc-editable-region--
```

View File

@@ -1,60 +0,0 @@
---
id: 6568bbc8c3bda1c773e23cf1
title: Step 25
challengeType: 20
dashedName: step-25
---
# --description--
Now, to handle other rows, if the inner condition is `False`, meaning the current row is not the last row of a 3x3 square, append the `middle_lines` string to `board_string`. Include this in an `else` block.
Recall that `middle_lines` represents the middle borders of the sudoku board and includes horizontal separators.
# --hints--
You should add an `else` block to the `if` statement.
```js
({ test: () => assert.match(code, /else\s*:/m) })
```
You should have `board_string += middle_lines` within the `else` block.
```js
({ test: () => assert.match(code, /board_string\s*\+=\s*middle_lines/m) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
--fcc-editable-region--
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
--fcc-editable-region--
```

View File

@@ -1,64 +0,0 @@
---
id: 6568bc19f3418dc8a8821187
title: Step 26
challengeType: 20
dashedName: step-26
---
# --description--
Now, you need to handle the last row of the entire board.
`lower_lines` represents the bottom border of the entire sudoku board.
Create an `else` block to append the `lower_lines` string to `board_string` when the outer `if` condition is false.
# --hints--
You should create an `else` block for the outermost `if` statement. Pay attention to the indentation.
```js
({ test: () => assert.match(code, /else\s*:/m) })
```
You should have `board_string += lower_lines` within the outermost `else` clause.
```js
({ test: () => assert.match(code, /board_string\s*\+=\s*lower_lines/m) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
--fcc-editable-region--
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
--fcc-editable-region--
```

View File

@@ -1,61 +0,0 @@
---
id: 6568bc85c5beadca3e0f6eb1
title: Step 27
challengeType: 20
dashedName: step-27
---
# --description--
After the outer loop completes for all rows, return the final `board_string`. This string contains the complete visual representation of the sudoku board in ASCII art style, including borders and separators.
# --hints--
You should return the `board_string` variable at the end of the outer `for` loop.
```js
const tCode = code.replace(/\r/g, '');
const str = __helpers.python.getDef(tCode, "__str__");
const {function_body} = str;
const indent = function_body.match(/ +/)[0];
const returnStatement = `${indent}return board_string`;
assert.match(code, new RegExp(returnStatement));
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
--fcc-editable-region--
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
--fcc-editable-region--
```

View File

@@ -1,65 +0,0 @@
---
id: 6568bd3741e379ccc220af1b
title: Step 28
challengeType: 20
dashedName: step-28
---
# --description--
Now you will work on a method that finds the empty cells in the sudoku board.
For that, within the `Board` class, create a method named `find_empty_cell`. It takes `self` as a parameter, representing the instance of the class. Include the `pass` keyword inside the function body.
# --hints--
Your method should be named `find_empty_cell`.
```js
assert.match(code, /def\s+find_empty_cell/);
```
You should add the parameter `self` to the method.
```js
assert.match(code, /def\s+find_empty_cell\(\s*self\s*\)/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -1,78 +0,0 @@
---
id: 6568bd85482755cdd26443ae
title: Step 29
challengeType: 20
dashedName: step-29
---
# --description--
Inside the `find_empty_cell` method, create a `for` loop and use the `enumerate()` function to iterate over each row in the sudoku board.
Use `row` for the index of the current row and `contents` for the elements of the current row.
# --hints--
You should create a `for` loop to iterate over `enumerate(self.board)`.
```js
const empty = __helpers.python.getDef(
code,
'find_empty_cell'
);
const { function_body } = empty;
assert(
function_body.match(
/for\s+(\w+)\s*,\s*(?!\1)(\w+)\s+in\s+enumerate\s*\(\s*self\.board\s*\)\s*:/m
)
);
```
You should have `for row, contents in enumerate(self.board):` within the `find_empty_cell` method.
```js
assert.match(
code,
/for\s+row\s*,\s*contents\s+in\s+enumerate\s*\(\s*self\.board\s*\)\s*:/m
);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
--fcc-editable-region--
def find_empty_cell(self):
--fcc-editable-region--
```

View File

@@ -1,61 +0,0 @@
---
id: 6568bdb69e05a9cee01068a8
title: Step 30
challengeType: 20
dashedName: step-30
---
# --description--
In the body of the for loop, add a `try` block.
# --hints--
Add a `try` block.
```js
assert.match(code, /try\s*\:/)
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
--fcc-editable-region--
def find_empty_cell(self):
for row, contents in enumerate(self.board):
--fcc-editable-region--
```

View File

@@ -1,68 +0,0 @@
---
id: 6568beebba98a3d1f26f6bf8
title: Step 31
challengeType: 20
dashedName: step-31
---
# --description--
In the `try` block, attempt to find the index of the first occurrence of `0` in the current row using `contents.index(0)`. Store the results in the variable `col`.
# --hints--
Use the index of the first occurrence of `0` in the current row using `contents.index(0)`.
```js
assert.match(code, /contents\.index\(\s*0\s*\)/)
```
You should have `col = contents.index(0)` within the `try` block.
```js
assert.match(code, /col\s*=\s*contents\.index\(\s*0\s*\)/)
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
--fcc-editable-region--
try:
--fcc-editable-region--
```

View File

@@ -1,65 +0,0 @@
---
id: 6568bf22bb5de0d2e8260cf3
title: Step 32
challengeType: 20
dashedName: step-32
---
# --description--
If `0` is found, the code immediately returns a tuple (row, col) with the row index and column index of the empty cell.
Return the `row` and `col` values
# --hints--
You should have `return row, col` within the `try` block.
```js
assert.match(code, /return\s*row\s*,\s*col/)
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}╗\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}╢\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}╝\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('║')
row = f'║ {" ".join(row_list)} ║\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}╣\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
--fcc-editable-region--
try:
col = contents.index(0)
--fcc-editable-region--
```

View File

@@ -1,64 +0,0 @@
---
id: 6568bf5e5b2f4bd3eb7ef995
title: Step 33
challengeType: 20
dashedName: step-33
---
# --description--
Create an `except` block to handle the `ValueError` exception that is thrown if `0` is not found.
# --hints--
You should have `except ValueError:` within the innermost `for` loop.
```js
assert.match(code, /except\s+ValueError/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
--fcc-editable-region--
try:
col = contents.index(0)
return row, col
--fcc-editable-region--
```

View File

@@ -1,68 +0,0 @@
---
id: 6568bf853bf06dd4ed25d4ca
title: Step 34
challengeType: 20
dashedName: step-34
---
# --description--
If the value `0` is not present in the current row, an exception would be thrown and the `except` block would execute.
The `except` block should pass and continue to the next row.
Achieve this by using `pass`.
# --hints--
You should have `pass` within the `except` block.
```js
assert.match(code, /pass/)
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
--fcc-editable-region--
except ValueError:
--fcc-editable-region--
```

View File

@@ -1,75 +0,0 @@
---
id: 6568bfb601a54ed5b367b44f
title: Step 35
challengeType: 20
dashedName: step-35
---
# --description--
If the loop completes without finding any empty cells, the method should return `None` to indicate that the sudoku board is filled.
Return `None` outside the `for` loop block.
# --hints--
You should have `return None` outwith the `for` loop.
```js
({ test: () =>
{
const empty = __helpers.python.getDef(code, "find_empty_cell");
const {function_body} = empty;
const indent = function_body.match(/ +/)[0];
const re = new RegExp(`^${indent}return\\s+None`, "m");
assert.match(function_body, re);
}
})
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += lower_lines
return board_string
--fcc-editable-region--
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
--fcc-editable-region--
```

View File

@@ -1,86 +0,0 @@
---
id: 6568bfd65322add674039bde
title: Step 36
challengeType: 20
dashedName: step-36
---
# --description--
Next, you will work on a method that checks if a given number can be inserted into a specified row of the sudoku board.
Create a method named `valid_in_row`. It should take three parameters:
- `self`: representing the instance of the class.
- `row`: representing the row index.
- `num`: representing the number to be checked.
Also, don't forget to add the `pass` keyword in the function body.
# --hints--
You should have a `valid_in_row` method.
```js
const tCode = code.replace(/\r/g, '');
const board = __helpers.python.getBlock("\n" + tCode, "class Board");
const valid = __helpers.python.getDef(board.block_body, "valid_in_row");
assert.exists(valid);
```
You should have `def valid_in_row(self, row, num)` within the `Board` class.
```js
const tCode = code.replace(/\r/g, '');
const {function_parameters} = __helpers.python.getDef(tCode, "valid_in_row");
assert.match(function_parameters, /self\s*,\s*row\s*,\s*num/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -1,71 +0,0 @@
---
id: 6568c0013b3b62d7617518c7
title: Step 37
challengeType: 20
dashedName: step-37
---
# --description--
Create an expression that checks if the number is not already present in that row.
You should check if the number(`num`) is not present in `self.board[row]`.
# --hints--
You should have `num not in self.board[row]` within `valid_in_row`.
```js
assert.match(code, /num\s+not\s+in\s+self\.board\s*\[\s*row\s*\]/)
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
--fcc-editable-region--
def valid_in_row(self, row, num):
--fcc-editable-region--
```

View File

@@ -1,76 +0,0 @@
---
id: 6568c024933423d85d5ed93c
title: Step 38
challengeType: 20
dashedName: step-38
---
# --description--
If `num` is not in the row, the expression evaluates to `True` and it means the number is valid for insertion.
If `num` is in the row, the expression evaluates to `False` and insertion would violate the rules.
Return the value from the expression you wrote in the previous step, so that the validity of a number can be checked.
# --hints--
You should have `return num not in self.board[row]` within `valid_in_row`.
```js
const tCode = code.replace(/\r/g, '');
const valid = __helpers.python.getDef(tCode, "valid_in_row");
const {function_body} = valid;
assert.match(function_body, /return\s+num\s+not\s+in\s+self\.board\s*\[\s*row\s*\]/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
--fcc-editable-region--
def valid_in_row(self, row, num):
num not in self.board[row]
--fcc-editable-region--
```

View File

@@ -1,89 +0,0 @@
---
id: 6568c073d5f37fd99ab2ab0c
title: Step 39
challengeType: 20
dashedName: step-39
---
# --description--
Next, you will create a method that checks if a number can be inserted in a specified column of the sudoku board by checking if the number is not already present in that column for any row.
For that, within the `Board` class, create a method named `valid_in_col`.
It should take three parameters:
- `self`: representing the instance of the class.
- `col`: representing the column index.
- `num`: representing the number to be checked.
# --hints--
You should have a `valid_in_col` method.
```js
const tCode = code.replace(/\r/g, '');
const {block_body} = __helpers.python.getBlock("\n" + tCode, "class Board");
const valid = __helpers.python.getDef(block_body, "valid_in_col");
assert.exists(valid);
```
The method should take three parameters: `self`, `col`, and `num`. Order matters
```js
const tCode = code.replace(/\r/g, '');
const {function_parameters} = __helpers.python.getDef(tCode, "valid_in_col");
assert.match(function_parameters, /self\s*,\s*col\s*,\s*num/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -1,77 +0,0 @@
---
id: 6568c0a5edddc3daa65d20b2
title: Step 40
challengeType: 20
dashedName: step-40
---
# --description--
Now, you need to check if a given number is not equal to the number in the specified column of the current row.
For that, first, iterate over the rows of the 2D list `self.board` using a `for` loop in the range `0` to `8`. Use `row` as the iteration variable.
# --hints--
You should have `for row in range(9)` within `valid_in_col`.
```js
const tCode = code.replace(/\r/g, '');
const valid = __helpers.python.getDef(tCode, "valid_in_col");
const {function_body} = valid;
assert.match(function_body, /for\s+row\s+in\s+range\(\s*9\s*\)/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
--fcc-editable-region--
def valid_in_col(self, col, num):
--fcc-editable-region--
```

View File

@@ -1,77 +0,0 @@
---
id: 6569d83fe4dcc614c2ff971d
title: Step 41
challengeType: 20
dashedName: step-41
---
# --description--
For each element in the specified column (`col`) of the current row (`row`), check whether the value at the current position in the 2D list is not equal to the provided `num`.
# --hints--
You should have `self.board[row][col] != num` within `valid_in_col`.
```js
const tCode = code.replace(/\r/g, '');
const valid = __helpers.python.getDef(tCode, "valid_in_col");
const {function_body} = valid;
assert.match(function_body, /self\.board\s*\[\s*row\s*\]\s*\[\s*col\s*\]\s*!=\s*num/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
--fcc-editable-region--
def valid_in_col(self, col, num):
--fcc-editable-region--
for row in range(9)
```

View File

@@ -1,87 +0,0 @@
---
id: 6569d8a4b8d85515cbb1ce72
title: Step 42
challengeType: 20
dashedName: step-42
---
# --description--
This expression generates a list of boolean values representing whether the condition `self.board[row][col] != num` is `True` or `False` for each element in the specified column across all rows.
Pass this generator expression to the `all()` function to check if all the elements in the column are different from `num`.
Recall that the syntax of the `all` function is as follows:
```py
all(
self.board[row][col] != num
for row in range(9)
)
```
# --hints--
You should have `all(self.board[row][col] != num for row in range(9))` within `valid_in_col`.
```js
const tCode = code.replace(/\r/g, '');
const valid = __helpers.python.getDef(tCode, "valid_in_col");
const {function_body} = valid;
assert.match(function_body, /all\s*\(\s*self\.board\s*\[\s*row\s*\]\s*\[\s*col\s*\]\s*!=\s*num\s+for\s+row\s+in\s+range\s*\(\s*9\s*\)\s*\)/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
--fcc-editable-region--
def valid_in_col(self, col, num):
self.board[row][col] != num
for row in range(9)
--fcc-editable-region--
```

View File

@@ -1,78 +0,0 @@
---
id: 6569d946293d4f185e32e2da
title: Step 43
challengeType: 20
dashedName: step-43
---
# --description--
Return the result of the `all()` function call.
# --hints--
You should return the result of the `all()` function call.
```js
const tCode = code.replace(/\r/g, '');
const valid = __helpers.python.getDef(tCode, "valid_in_col");
const {function_body} = valid;
assert.match(function_body, /return\s+all\s*\(\s*self\.board\s*\[\s*row\s*\]\s*\[\s*col\s*\]\s*!=\s*num\s+for\s+row\s+in\s+range\s*\(\s*9\s*\)\s*\)/m);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
--fcc-editable-region--
def valid_in_col(self, col, num):
all(
self.board[row][col] != num
for row in range(9)
)
--fcc-editable-region--
```

View File

@@ -1,96 +0,0 @@
---
id: 6569d98303af38193149b66e
title: Step 44
challengeType: 20
dashedName: step-44
---
# --description--
Next, you will work on a method that checks if a number can be inserted in the 3x3 square.
Inside the `Board` class, create a method named `valid_in_square`.
It should take four parameters:
- `self`: represents the instance of the class.
- `row`: represents the row index.
- `col`: represents the column index.
- `num`: represents the number to be checked.
# --hints--
You should have a `valid_in_square` method.
```js
const tCode = code.replace(/\r/g, '');
const {block_body} = __helpers.python.getBlock("\n" + tCode, "class Board");
const valid = __helpers.python.getDef(block_body, "valid_in_square");
assert.exists(valid);
```
The method should take four parameters: `self`, `row`, `col`, and `num`. Don't forget to add `pass` in the function body. Order matters.
```js
const tCode = code.replace(/\r/g, '');
const {function_parameters} = __helpers.python.getDef(tCode, "valid_in_square");
assert.match(function_parameters, /self\s*,\s*row\s*,\s*col\s*,\s*num/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -1,86 +0,0 @@
---
id: 6569d9dfd53db11b176d2963
title: Step 45
challengeType: 20
dashedName: step-45
---
# --description--
Now you need to calculate the starting row index for the 3x3 block in the board grid.
For that, ensure that the starting row index for each 3x3 block is a multiple of 3.
This can be achieved by this mathematical operation: `(row // 3) * 3`.
Assign the result of this calculation to `row_start`.
# --hints--
You should assign the result of `(row // 3) * 3` to `row_start`.
```js
const tCode = code.replace(/\r/g, '');
const valid = __helpers.python.getDef(tCode, "valid_in_square");
const {function_body} = valid;
assert.match(function_body, /row_start\s*=\s*\(\s*row\s*\/\/\s*3\s*\)\s*\*\s*3/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
--fcc-editable-region--
def valid_in_square(self, row, col, num):
--fcc-editable-region--
```

View File

@@ -1,87 +0,0 @@
---
id: 6569da02e7e2641be14ff922
title: Step 46
challengeType: 20
dashedName: step-46
---
# --description--
Next, you need to calculate the starting column index for the 3x3 block in the board grid.
For that, ensure that the starting row index for each 3x3 block is a multiple of 3.
Similar to the previous step, this can be achieved by this mathematical operation: `(col // 3) * 3`.
Assign the result of this calculation to `col_start`.
# --hints--
You should assign the result of `(col // 3) * 3` to `col_start`.
```js
const tCode = code.replace(/\r/g, '');
const valid = __helpers.python.getDef(tCode, "valid_in_square");
const {function_body} = valid;
assert.match(function_body, /col_start\s*=\s*\(\s*col\s*\/\/\s*3\s*\)\s*\*\s*3/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
--fcc-editable-region--
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
--fcc-editable-region--
```

View File

@@ -1,83 +0,0 @@
---
id: 6569de93a5340b202667deda
title: Step 47
challengeType: 20
dashedName: step-47
---
# --description--
Create a `for` loop that starts at `row_start` and ends just before `row_start + 3`. You can use the `range()` function to generate the sequence. As an example, if `row_start` is `3`, the loop will iterate over the numbers `3`, `4`, and `5`.
# --hints--
You should have `for row_no in range(row_start, row_start + 3):` within `valid_in_square`.
```js
const tCode = code.replace(/\r/g, '');
const valid = __helpers.python.getDef(tCode, "valid_in_square");
const {function_body} = valid;
assert.match(function_body, /for\s+(\w+)\s+in\s+range\s*\(\s*row_start\s*,\s*row_start\s*\+\s*3\s*\)\s*:/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
--fcc-editable-region--
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
--fcc-editable-region--
```

View File

@@ -1,84 +0,0 @@
---
id: 6569def38470282151f873ce
title: Step 48
challengeType: 20
dashedName: step-48
---
# --description--
Inside the loop created in the previous step, nest another `for` loop to iterate over a sequence of three elements starting at `col_start`. Again, use the `range()` function to generate the sequence.
# --hints--
You should have `for col_no in range(col_start, col_start + 3):` within `valid_in_square`.
```js
const tCode = code.replace(/\r/g, '');
const valid = __helpers.python.getDef(tCode, "valid_in_square");
const {function_body} = valid;
assert.match(function_body, /for\s+(\w+)\s+in\s+range\s*\(\s*col_start\s*,\s*col_start\s*\+\s*3\s*\)\s*:/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
--fcc-editable-region--
for row_no in range(row_start, row_start + 3):
--fcc-editable-region--
```

View File

@@ -1,87 +0,0 @@
---
id: 6569df1d6fb83d22623b38c5
title: Step 49
challengeType: 20
dashedName: step-49
---
# --description--
The next step is to check if the specified number (`num`) is already present in the current cell of the 3x3 square.
Inside the inner `for` loop, create an `if` statement that checks if the current cell in `self.board` is equal to `num`.
# --hints--
You should have `if self.board[row_no][col_no] == num` within `valid_in_square`.
```js
const tCode = code.replace(/\r/g, '');
const innerFor = __helpers.python.getBlock(tCode, "for col_no in range(col_start, col_start + 3)");
const {block_body} = innerFor;
assert.match(block_body, /if\s+self\.board\s*\[\s*row_no\s*\]\s*\[\s*col_no\s*\]\s*==\s*num\s*\:/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
--fcc-editable-region--
for col_no in range(col_start, col_start + 3):
--fcc-editable-region--
```

View File

@@ -1,86 +0,0 @@
---
id: 6569df6916294723e01f0035
title: Step 50
challengeType: 20
dashedName: step-50
---
# --description--
Inside the `if` block, return `False` to indicate that the number cannot be inserted into the square.
# --hints--
You should return `False` inside the `if` block.
```js
const tCode = code.replace(/\r/g, '');
const innerIf = __helpers.python.getBlock(tCode, "if self.board[row_no][col_no] == num");
const {block_body} = innerIf;
assert.match(block_body, /return\s+False/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
--fcc-editable-region--
if self.board[row_no][col_no] == num:
--fcc-editable-region--
```

View File

@@ -1,91 +0,0 @@
---
id: 6569df9e20f74a251d482c5d
title: Step 51
challengeType: 20
dashedName: step-51
---
# --description--
If the number is not present, it can be inserted into the square without violating the rules of sudoku.
Return `True` in that case, and pay attention to the indentation.
# --hints--
You should have `return True` outwith the outermost `for` loop.
```js
const tCode = code.replace(/\r/g, '');
const valid = __helpers.python.getDef(tCode, "valid_in_square");
const {function_body} = valid;
const indent = function_body.match(/ +/)[0];
const re = new RegExp(`^${indent}return\\s+True`, "m");
assert.match(function_body, re);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
--fcc-editable-region--
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
--fcc-editable-region--
```

View File

@@ -1,104 +0,0 @@
---
id: 6569dffeee007f26d2b56d46
title: Step 52
challengeType: 20
dashedName: step-52
---
# --description--
Within the `Board` class, create another method `is_valid`.
It would take three parameters:
- `self` (representing the instance of the class),
- `empty` (a tuple representing the row and column indices of an empty cell)
- `num` (representing the number to be checked).
This method checks if a given number is a valid choice for an empty cell in the sudoku board by validating its compatibility with the row, column, and 3x3 square of the specified empty cell.
# --hints--
The method name should be `is_valid`.
```js
const tCode = code.replace(/\r/g, '');
const board = __helpers.python.getBlock("\n" + tCode, "class Board");
const valid = __helpers.python.getDef(board.block_body, "is_valid");
assert.exists(valid);
```
The method should take three parameters: `self`, `empty`, and `num`. Order matters
```js
const tCode = code.replace(/\r/g, '');
const valid = __helpers.python.getDef(tCode, "is_valid");
const {function_parameters} = valid;
assert.match(function_parameters, /self\s*,\s*empty\s*,\s*num/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
return True
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -1,89 +0,0 @@
---
id: 6569e2a01a97b231862ba2ff
title: Step 53
challengeType: 20
dashedName: step-53
---
# --description--
Inside the method, unpack the `empty` tuple into `row` and `col`.
# --hints--
You should have `row, col = empty` within `is_valid`.
```js
const tCode = code.replace(/\r/g, '');
const {function_body} = __helpers.python.getDef(tCode, "is_valid");
assert.match(function_body, /row\s*,\s*col\s*=\s*empty/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
return True
--fcc-editable-region--
def is_valid(self, empty, num):
--fcc-editable-region--
```

View File

@@ -1,91 +0,0 @@
---
id: 6569e2e1944fe7329ab21c7f
title: Step 54
challengeType: 20
dashedName: step-54
---
# --description--
Check if the number is valid for insertion in the specified row by calling `self.valid_in_row(row, num)`
Assign the result to `valid_in_row`
# --hints--
You should have `valid_in_row = self.valid_in_row(row, num)` within `is_valid`.
```js
const tCode = code.replace(/\r/g, '');
const {function_body} = __helpers.python.getDef(tCode, "is_valid");
assert.match(function_body, /valid_in_row\s*=\s*self\.valid_in_row\s*\(\s*row\s*,\s*num\s*\)/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
return True
--fcc-editable-region--
def is_valid(self, empty, num):
row, col = empty
--fcc-editable-region--
```

View File

@@ -1,93 +0,0 @@
---
id: 6569e309feb5d333867a034a
title: Step 55
challengeType: 20
dashedName: step-55
---
# --description--
Check if the number is valid for insertion in the specified column by calling `self.valid_in_col(col, num)`
Assign the result to `valid_in_col`.
# --hints--
You should have `valid_in_col = self.valid_in_col(col, num)` within `is_valid`.
```js
const tCode = code.replace(/\r/g, '');
const {function_body} = __helpers.python.getDef(tCode, "is_valid");
assert.match(function_body, /valid_in_col\s*=\s*self\.valid_in_col\s*\(\s*col\s*,\s*num\s*\)/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
return True
--fcc-editable-region--
def is_valid(self, empty, num):
row, col = empty
valid_in_row = self.valid_in_row(row, num)
--fcc-editable-region--
```

View File

@@ -1,94 +0,0 @@
---
id: 6569e33a708a3834f6d4879b
title: Step 56
challengeType: 20
dashedName: step-56
---
# --description--
Check if the number is valid for insertion in the 3x3 square that contains the specified cell by calling `self.valid_in_square(row, col, num)`.
Assign the result to `valid_in_square`.
# --hints--
You should have `valid_in_square = self.valid_in_square(row, col, num)` within `is_valid`.
```js
const tCode = code.replace(/\r/g, '');
const {function_body} = __helpers.python.getDef(tCode, "is_valid");
assert.match(function_body, /valid_in_square\s*=\s*self\.valid_in_square\s*\(\s*row\s*,\s*col\s*,\s*num\s*\)/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
return True
--fcc-editable-region--
def is_valid(self, empty, num):
row, col = empty
valid_in_row = self.valid_in_row(row, num)
valid_in_col = self.valid_in_col(col, num)
--fcc-editable-region--
```

View File

@@ -1,93 +0,0 @@
---
id: 6569e37ec28e853628f18a86
title: Step 57
challengeType: 20
dashedName: step-57
---
# --description--
Insert `valid_in_row`, `valid_in_col`, and `valid_in_square` into a list and pass it to the `all()` function. This will verify that all the function calls return `True`.
# --hints--
You should have `all([valid_in_row, valid_in_col, valid_in_square])` within `is_valid`.
```js
const tCode = code.replace(/\r/g, '');
const {function_body} = __helpers.python.getDef(tCode, "is_valid");
assert.match(function_body, /all\s*\(\s*\[\s*valid_in_row\s*,\s*valid_in_col\s*,\s*valid_in_square\s*\]\s*\)/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
return True
--fcc-editable-region--
def is_valid(self, empty, num):
row, col = empty
valid_in_row = self.valid_in_row(row, num)
valid_in_col = self.valid_in_col(col, num)
valid_in_square = self.valid_in_square(row, col, num)
--fcc-editable-region--
```

View File

@@ -1,91 +0,0 @@
---
id: 6569e3a134fea0371fa008de
title: Step 58
challengeType: 20
dashedName: step-58
---
# --description--
Now, return the result of the `all()` call.
# --hints--
You should return the result of the `all()` call.
```js
({ test: () => assert.match(code, /^\s{8}return\s+all\s*\(\s*\[\s*(valid_in_)(row|col|square)\s*,\s*\1(?!\2)(row|col|square)\s*,\s*\1(?!\2|\3)(row|col|square)\s*\]\s*\)/m) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
return True
--fcc-editable-region--
def is_valid(self, empty, num):
row, col = empty
valid_in_row = self.valid_in_row(row, num)
valid_in_col = self.valid_in_col(col, num)
valid_in_square = self.valid_in_square(row, col, num)
all([valid_in_row, valid_in_col, valid_in_square])
--fcc-editable-region--
```

View File

@@ -1,105 +0,0 @@
---
id: 6569e3d1418b373839a0aa7b
title: Step 59
challengeType: 20
dashedName: step-59
---
# --description--
Next, you will work on a method that attempts to solve the sudoku in-place, meaning it would modify the existing sudoku board rather than creating a new one.
Within the board class, create a method `solver` that takes one argument(`self`, representing the instance of the class).
# --hints--
Your method should be named `solver`.
```js
const tCode = code.replace(/\r/g, "");
const board = __helpers.python.getBlock("\n" + tCode, "class Board");
const solver = __helpers.python.getDef(board.block_body, "solver");
assert.exists(solver);
```
You should add the parameter `self` to the method.
```js
const tCode = code.replace(/\r/g, "");
const { function_parameters } = __helpers.python.getDef(tCode, "solver");
assert.match(function_parameters, /self/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
return True
def is_valid(self, empty, num):
row, col = empty
valid_in_row = self.valid_in_row(row, num)
valid_in_col = self.valid_in_col(col, num)
valid_in_square = self.valid_in_square(row, col, num)
return all([valid_in_row, valid_in_col, valid_in_square])
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -1,102 +0,0 @@
---
id: 6569e41657a9923953aa7d3c
title: Step 60
challengeType: 20
dashedName: step-60
---
# --description--
First, check if there are any empty cells left in the sudoku board.
Use the `find_empty_cell` function call on `self`.
Also, use the walrus operator (:=) to assign the result of `self.find_empty_cell()` to the variable `next_empty`.
By using the walrus operator, you can combine the assignment and the conditional check into a single line, making the code more concise and readable.
# --hints--
You should have `next_empty := self.find_empty_cell()` within the `solver` method.
```js
const tCode = code.replace(/\r/g, '');
const {function_body} = __helpers.python.getDef(tCode, "solver");
assert.match(function_body, /next_empty\s*:=\s*self\.find_empty_cell\(\s*\)/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
return True
def is_valid(self, empty, num):
row, col = empty
valid_in_row = self.valid_in_row(row, num)
valid_in_col = self.valid_in_col(col, num)
valid_in_square = self.valid_in_square(row, col, num)
return all([valid_in_row, valid_in_col, valid_in_square])
--fcc-editable-region--
def solver(self):
--fcc-editable-region--
```

View File

@@ -1,96 +0,0 @@
---
id: 6569e481e67f123ad25c5d20
title: Step 61
challengeType: 20
dashedName: step-61
---
# --description--
Place the condition in an `if` statement and check if it is `None`.
# --hints--
You should have `if (next_empty := self.find_empty_cell()) is None:` within `solver`.
```js
const tCode = code.replace(/\r/g, '');
const {function_body} = __helpers.python.getDef(tCode, "solver");
assert.match(function_body, /if\s*\(\s*next_empty\s*:=\s*self\.find_empty_cell\(\s*\)\s*\)\s*is\s*None:/)
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
return True
def is_valid(self, empty, num):
row, col = empty
valid_in_row = self.valid_in_row(row, num)
valid_in_col = self.valid_in_col(col, num)
valid_in_square = self.valid_in_square(row, col, num)
return all([valid_in_row, valid_in_col, valid_in_square])
--fcc-editable-region--
def solver(self):
next_empty := self.find_empty_cell()
--fcc-editable-region--
```

View File

@@ -1,97 +0,0 @@
---
id: 6569f6b48716b5402504e216
title: Step 62
challengeType: 20
dashedName: step-62
---
# --description--
If there are no empty cells (i.e., `next_empty` is `None`), the puzzle is solved. So, return `True`.
# --hints--
You should return `True` within the `if` statement.
```js
const tCode = code.replace(/\r/g, '');
const {function_body} = __helpers.python.getDef(tCode, "solver");
assert.match(function_body, /return\s*True/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
return True
def is_valid(self, empty, num):
row, col = empty
valid_in_row = self.valid_in_row(row, num)
valid_in_col = self.valid_in_col(col, num)
valid_in_square = self.valid_in_square(row, col, num)
return all([valid_in_row, valid_in_col, valid_in_square])
--fcc-editable-region--
def solver(self):
if (next_empty := self.find_empty_cell()) is None:
--fcc-editable-region--
```

View File

@@ -1,98 +0,0 @@
---
id: 6569f6ebe558bd4136da96cc
title: Step 63
challengeType: 20
dashedName: step-63
---
# --description--
Create an `else` block to cater the case where there are empty cells and the puzzle is unsolved.
# --hints--
You should have an `else` clause within `solver`.
```js
const tCode = code.replace(/\r/g, '');
const {function_body} = __helpers.python.getDef(tCode, "solver");
assert.match(function_body, /else:/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
return True
def is_valid(self, empty, num):
row, col = empty
valid_in_row = self.valid_in_row(row, num)
valid_in_col = self.valid_in_col(col, num)
valid_in_square = self.valid_in_square(row, col, num)
return all([valid_in_row, valid_in_col, valid_in_square])
--fcc-editable-region--
def solver(self):
if (next_empty := self.find_empty_cell()) is None:
return True
--fcc-editable-region--
```

View File

@@ -1,100 +0,0 @@
---
id: 6569f70a66ccdc42097ca051
title: Step 64
challengeType: 20
dashedName: step-64
---
# --description--
If there are still empty cells, create a loop in the `else` block that iterates over numbers from `1` to `9` (inclusive). Your loop should use the variable named `guess`.
# --hints--
You should have `for guess in range(1,10):` within the `else` block.
```js
const tCode = code.replace(/\r/g, '');
const {function_body} = __helpers.python.getDef(tCode, "solver");
const {block_body} = __helpers.python.getBlock(function_body, "else");
assert.match(block_body, /for\s+\w+\s+in\s+range\(\s*1\s*,\s*10\s*\)/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
return True
def is_valid(self, empty, num):
row, col = empty
valid_in_row = self.valid_in_row(row, num)
valid_in_col = self.valid_in_col(col, num)
valid_in_square = self.valid_in_square(row, col, num)
return all([valid_in_row, valid_in_col, valid_in_square])
--fcc-editable-region--
def solver(self):
if (next_empty := self.find_empty_cell()) is None:
return True
else:
--fcc-editable-region--
```

View File

@@ -1,101 +0,0 @@
---
id: 6569f770fd7dc443d6293095
title: Step 65
challengeType: 20
dashedName: step-65
---
# --description--
For each number (`guess`), check if the number is a valid choice for the current empty cell using `self.is_valid(next_empty, guess)`.
# --hints--
You should have `self.is_valid(next_empty, guess)` within the `for` loop.
```js
const tCode = code.replace(/\r/g, '');
const {function_body} = __helpers.python.getDef(tCode, "solver");
const {block_body} = __helpers.python.getBlock(function_body, "for guess in range(1, 10)");
assert.match(block_body, /self\.is_valid\(\s*next_empty\s*,\s*guess\s*\)/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
return True
def is_valid(self, empty, num):
row, col = empty
valid_in_row = self.valid_in_row(row, num)
valid_in_col = self.valid_in_col(col, num)
valid_in_square = self.valid_in_square(row, col, num)
return all([valid_in_row, valid_in_col, valid_in_square])
--fcc-editable-region--
def solver(self):
if (next_empty := self.find_empty_cell()) is None:
return True
else:
for guess in range(1, 10):
--fcc-editable-region--
```

View File

@@ -1,104 +0,0 @@
---
id: 6569f7c7f6954944d207775f
title: Step 66
challengeType: 20
dashedName: step-66
---
# --description--
If the guess is valid, the method updates the sudoku board with the guess by assigning `guess` to the cell specified by next_empty.
Unpack the `next_empty` tuple to `row, col`.
# --hints--
You should have `row, col = next_empty` within the innermost `if` statement.
```js
const tCode = code.replace(/\r/g, '');
const {function_body} = __helpers.python.getDef(tCode, "solver");
const {block_body} = __helpers.python.getBlock(function_body, "if self.is_valid(next_empty, guess)");
assert.match(block_body, /row\s*,\s*col\s*=\s*next_empty/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
return True
def is_valid(self, empty, num):
row, col = empty
valid_in_row = self.valid_in_row(row, num)
valid_in_col = self.valid_in_col(col, num)
valid_in_square = self.valid_in_square(row, col, num)
return all([valid_in_row, valid_in_col, valid_in_square])
--fcc-editable-region--
def solver(self):
if (next_empty := self.find_empty_cell()) is None:
return True
else:
for guess in range(1, 10):
if self.is_valid(next_empty, guess):
--fcc-editable-region--
```

View File

@@ -1,103 +0,0 @@
---
id: 6569f7f2fa74c045e95676ac
title: Step 67
challengeType: 20
dashedName: step-67
---
# --description--
Access the cell at the given row and column in the sudoku board, and assign it the value of `guess`.
# --hints--
You should have `self.board[row][col] = guess` within the innermost `if` block.
```js
const tCode = code.replace(/\r/g, '');
const {function_body} = __helpers.python.getDef(tCode, "solver");
const {block_body} = __helpers.python.getBlock(function_body, "if self.is_valid(next_empty, guess)");
assert.match(block_body, /self\.board\s*\[\s*row\s*\]\s*\[\s*col\s*\]\s*=\s*guess/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
return True
def is_valid(self, empty, num):
row, col = empty
valid_in_row = self.valid_in_row(row, num)
valid_in_col = self.valid_in_col(col, num)
valid_in_square = self.valid_in_square(row, col, num)
return all([valid_in_row, valid_in_col, valid_in_square])
def solver(self):
if (next_empty := self.find_empty_cell()) is None:
return True
else:
for guess in range(1, 10):
--fcc-editable-region--
if self.is_valid(next_empty, guess):
row, col = next_empty
--fcc-editable-region--
```

View File

@@ -1,104 +0,0 @@
---
id: 6569fa5b9d507748bf4ec722
title: Step 68
challengeType: 20
dashedName: step-68
---
# --description--
While staying in the `if` block, recursively call `self.solver()` to try to solve the rest of the sudoku.
# --hints--
You should have `self.solver()` within the innermost `if` block.
```js
const tCode = code.replace(/\r/g, '');
const {function_body} = __helpers.python.getDef(tCode, "solver");
const {block_body} = __helpers.python.getBlock(function_body, "if self.is_valid(next_empty, guess)");
assert.match(block_body, /self\.solver\(\s*\)/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
return True
def is_valid(self, empty, num):
row, col = empty
valid_in_row = self.valid_in_row(row, num)
valid_in_col = self.valid_in_col(col, num)
valid_in_square = self.valid_in_square(row, col, num)
return all([valid_in_row, valid_in_col, valid_in_square])
def solver(self):
if (next_empty := self.find_empty_cell()) is None:
return True
else:
for guess in range(1, 10):
--fcc-editable-region--
if self.is_valid(next_empty, guess):
row, col = next_empty
self.board[row][col] = guess
--fcc-editable-region--
```

View File

@@ -1,115 +0,0 @@
---
id: 6569fa85d8f9ed49c8dfb37d
title: Step 69
challengeType: 20
dashedName: step-69
---
# --description--
If the recursive call to `self.solver()` returns `True`, it means the sudoku is solved.
If the recursive call returns `True`, return `True` from the method.
# --hints--
You should have `if self.solver():` within the innermost `if` block.
```js
const tCode = code.replace(/\r/g, '');
const {function_body} = __helpers.python.getDef(tCode, "solver");
const {block_body} = __helpers.python.getBlock(function_body, "if self.is_valid(next_empty, guess)");
assert.match(block_body, /if\s+self\.solver\(\s*\):/);
```
You should have `return True` within `if self.solver():`.
```js
const tCode = code.replace(/\r/g, '');
const {function_body} = __helpers.python.getDef(tCode, "solver");
const {block_body} = __helpers.python.getBlock(function_body, "if self.solver()");
assert.match(block_body, /return\s+True/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
return True
def is_valid(self, empty, num):
row, col = empty
valid_in_row = self.valid_in_row(row, num)
valid_in_col = self.valid_in_col(col, num)
valid_in_square = self.valid_in_square(row, col, num)
return all([valid_in_row, valid_in_col, valid_in_square])
def solver(self):
if (next_empty := self.find_empty_cell()) is None:
return True
else:
for guess in range(1, 10):
--fcc-editable-region--
if self.is_valid(next_empty, guess):
row, col = next_empty
self.board[row][col] = guess
self.solver()
--fcc-editable-region--
```

View File

@@ -1,108 +0,0 @@
---
id: 6569fabbfe1c094ad838ec4c
title: Step 70
challengeType: 20
dashedName: step-70
---
# --description--
If `self.solver()` returns `False`, this means the `guess` led to an unsolvable sudoku.
Outside the innermost `if` block, undo the guess by setting the cell value back to `0`.
# --hints--
You should have `self.board[row][col] = 0` outside the innermost `if` block.
```js
const tCode = code.replace(/\r/g, '');
const {function_body} = __helpers.python.getDef(tCode, "solver");
const {block_body} = __helpers.python.getBlock(function_body, "if self.is_valid(next_empty, guess)");
assert.match(block_body, /self\.board\s*\[\s*row\s*\]\s*\[\s*col\s*\]\s*=\s*0/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
return True
def is_valid(self, empty, num):
row, col = empty
valid_in_row = self.valid_in_row(row, num)
valid_in_col = self.valid_in_col(col, num)
valid_in_square = self.valid_in_square(row, col, num)
return all([valid_in_row, valid_in_col, valid_in_square])
def solver(self):
if (next_empty := self.find_empty_cell()) is None:
return True
else:
for guess in range(1, 10):
--fcc-editable-region--
if self.is_valid(next_empty, guess):
row, col = next_empty
self.board[row][col] = guess
if self.solver():
return True
--fcc-editable-region--
```

View File

@@ -1,106 +0,0 @@
---
id: 6569fbbfee025a4e850b6eaf
title: Step 71
challengeType: 20
dashedName: step-71
---
# --description--
Make your method return `False` when none of the guesses leads to a solution.
# --hints--
You should return `False` within the outermost `else` block.
```js
const tCode = code.replace(/\r/g, '');
const {function_body} = __helpers.python.getDef(tCode, "solver");
assert.match(function_body, /return\s+False/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
return True
def is_valid(self, empty, num):
row, col = empty
valid_in_row = self.valid_in_row(row, num)
valid_in_col = self.valid_in_col(col, num)
valid_in_square = self.valid_in_square(row, col, num)
return all([valid_in_row, valid_in_col, valid_in_square])
--fcc-editable-region--
def solver(self):
if (next_empty := self.find_empty_cell()) is None:
return True
else:
for guess in range(1, 10):
if self.is_valid(next_empty, guess):
row, col = next_empty
self.board[row][col] = guess
if self.solver():
return True
self.board[row][col] = 0
--fcc-editable-region--
```

View File

@@ -1,128 +0,0 @@
---
id: 6569fc21837cab5029d82e26
title: Step 72
challengeType: 20
dashedName: step-72
---
# --description--
Outside the class definition, create a function to print and solve the sudoku board.
Name it `solve_sudoku`. It should take a single parameter `board` that is a 2D list.
# --hints--
You should not have a method `solve_sudoku` within the `Board` class.
```js
const tCode = code.replace(/\r/g, '');
const {block_body} = __helpers.python.getBlock("\n" + tCode, "class Board");
const solve = __helpers.python.getDef(block_body, "solve_sudoku");
assert.notExists(solve);
```
You should have a function named `solve_sudoku`.
```js
const tCode = code.replace(/\r/g, '');
const solve = __helpers.python.getDef(tCode, "solve_sudoku");
assert.exists(solve);
```
The method should take a single `board` parameter.
```js
const tCode = code.replace(/\r/g, '');
const {function_parameters} = __helpers.python.getDef(tCode, "solve_sudoku");
assert.match(function_parameters, /board/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
return True
def is_valid(self, empty, num):
row, col = empty
valid_in_row = self.valid_in_row(row, num)
valid_in_col = self.valid_in_col(col, num)
valid_in_square = self.valid_in_square(row, col, num)
return all([valid_in_row, valid_in_col, valid_in_square])
def solver(self):
if (next_empty := self.find_empty_cell()) is None:
return True
else:
for guess in range(1, 10):
if self.is_valid(next_empty, guess):
row, col = next_empty
self.board[row][col] = guess
if self.solver():
return True
self.board[row][col] = 0
return False
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -1,112 +0,0 @@
---
id: 6569fc63a404c8519d918095
title: Step 73
challengeType: 20
dashedName: step-73
---
# --description--
Inside the `solve_sudoku` function, create a `gameboard` variable and assign it an instance of the `Board` class passing `board` as the argument.
This initializes the sudoku board with the given initial state.
# --hints--
You should have `gameboard = Board(board)` within the `solve_sudoku` function.
```js
const tCode = code.replace(/\r/g, '');
const {function_body} = __helpers.python.getDef(tCode, "solve_sudoku");
assert.match(function_body, /gameboard\s*=\s*Board\(\s*board\s*\)/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
return True
def is_valid(self, empty, num):
row, col = empty
valid_in_row = self.valid_in_row(row, num)
valid_in_col = self.valid_in_col(col, num)
valid_in_square = self.valid_in_square(row, col, num)
return all([valid_in_row, valid_in_col, valid_in_square])
def solver(self):
if (next_empty := self.find_empty_cell()) is None:
return True
else:
for guess in range(1, 10):
if self.is_valid(next_empty, guess):
row, col = next_empty
self.board[row][col] = guess
if self.solver():
return True
self.board[row][col] = 0
return False
--fcc-editable-region--
def solve_sudoku(board):
--fcc-editable-region--
```

View File

@@ -1,113 +0,0 @@
---
id: 6569fca3cd7a9f52f322a298
title: Step 74
challengeType: 20
dashedName: step-74
---
# --description--
Now, add another `print()` call passing `gameboard` as the argument to print the current state of the sudoku board.
Add a `print` call to print the following: `f'\nPuzzle to solve:\n{gameboard}'`.
# --hints--
You should have `print(f'\nPuzzle to solve:\n{gameboard}')` within the `solve_sudoku` function.
```js
const tCode = code.replace(/\r/g, '');
const {function_body} = __helpers.python.getDef(tCode, "solve_sudoku");
assert.match(function_body, /print\(\s*f'\\nPuzzle to solve:\\n\{gameboard\}'\s*\)/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
return True
def is_valid(self, empty, num):
row, col = empty
valid_in_row = self.valid_in_row(row, num)
valid_in_col = self.valid_in_col(col, num)
valid_in_square = self.valid_in_square(row, col, num)
return all([valid_in_row, valid_in_col, valid_in_square])
def solver(self):
if (next_empty := self.find_empty_cell()) is None:
return True
else:
for guess in range(1, 10):
if self.is_valid(next_empty, guess):
row, col = next_empty
self.board[row][col] = guess
if self.solver():
return True
self.board[row][col] = 0
return False
--fcc-editable-region--
def solve_sudoku(board):
gameboard = Board(board)
--fcc-editable-region--
```

View File

@@ -1,124 +0,0 @@
---
id: 6569fd01dab2ea547d98f093
title: Step 75
challengeType: 20
dashedName: step-75
---
# --description--
Create an `if` statement that checks if the `solver()` method call from the `gameboard` object returns `True`.
Then, add a `print()` call inside the `if` block passing the following string: `'\nSolved puzzle:'`.
# --hints--
You should have `if gameboard.solver():` within the `solve_sudoku` function.
```js
const tCode = code.replace(/\r/g, '');
const {function_body} = __helpers.python.getDef(tCode, "solve_sudoku");
const ifBlock = __helpers.python.getBlock(function_body, /if\s+gameboard\.solver\s*\(\s*\)\s*/);
assert.exists(ifBlock);
```
You should have `print('\nSolved puzzle:')` within the `if` block.
```js
const tCode = code.replace(/\r/g, '');
const {function_body} = __helpers.python.getDef(tCode, "solve_sudoku");
const {block_body} = __helpers.python.getBlock(function_body, /if\s+gameboard\.solver\s*\(\s*\)\s*/);
assert.match(block_body, /print\s*\(\s*("|')\\nSolved puzzle:\1\s*\)/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
return True
def is_valid(self, empty, num):
row, col = empty
valid_in_row = self.valid_in_row(row, num)
valid_in_col = self.valid_in_col(col, num)
valid_in_square = self.valid_in_square(row, col, num)
return all([valid_in_row, valid_in_col, valid_in_square])
def solver(self):
if (next_empty := self.find_empty_cell()) is None:
return True
else:
for guess in range(1, 10):
if self.is_valid(next_empty, guess):
row, col = next_empty
self.board[row][col] = guess
if self.solver():
return True
self.board[row][col] = 0
return False
--fcc-editable-region--
def solve_sudoku(board):
gameboard = Board(board)
print(f'\nPuzzle to solve:\n{gameboard}')
--fcc-editable-region--
```

View File

@@ -1,115 +0,0 @@
---
id: 6569fd352879475599d0ec66
title: Step 76
challengeType: 20
dashedName: step-76
---
# --description--
Add another `print` call to print the current state of the board.
# --hints--
You should have `print(gameboard)` within the `if` statement.
```js
const tCode = code.replace(/\r/g, '');
const {function_body} = __helpers.python.getDef(tCode, "solve_sudoku");
const {block_body} = __helpers.python.getBlock(function_body, /if\s+gameboard\.solver\s*\(\s*\)\s*/);
assert.match(block_body, /print\s*\(\s*gameboard\s*\)/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
return True
def is_valid(self, empty, num):
row, col = empty
valid_in_row = self.valid_in_row(row, num)
valid_in_col = self.valid_in_col(col, num)
valid_in_square = self.valid_in_square(row, col, num)
return all([valid_in_row, valid_in_col, valid_in_square])
def solver(self):
if (next_empty := self.find_empty_cell()) is None:
return True
else:
for guess in range(1, 10):
if self.is_valid(next_empty, guess):
row, col = next_empty
self.board[row][col] = guess
if self.solver():
return True
self.board[row][col] = 0
return False
def solve_sudoku(board):
gameboard = Board(board)
print(f'\nPuzzle to solve:\n{gameboard}')
--fcc-editable-region--
if gameboard.solver():
print('\nSolved puzzle:')
--fcc-editable-region--
```

View File

@@ -1,125 +0,0 @@
---
id: 6569fd6d3cb95856c9ed2190
title: Step 77
challengeType: 20
dashedName: step-77
---
# --description--
Create an `else` clause and print the following string inside the new `else` block: `'\nThe provided puzzle is unsolvable.'`.
# --hints--
You should have an `else` clause within `solve_sudoku`.
```js
const tCode = code.replace(/\r/g, '');
const {function_body} = __helpers.python.getDef(tCode, "solve_sudoku");
const elseBlock = __helpers.python.getBlock(function_body, /else\s*/);
assert.exists(elseBlock);
```
You should have `print('\nThe provided puzzle is unsolvable.')` within the `else` block.
```js
const tCode = code.replace(/\r/g, '');
const {function_body} = __helpers.python.getDef(tCode, "solve_sudoku");
const {block_body} = __helpers.python.getBlock(function_body, /else\s*/);
assert.match(block_body, /print\s*\(\s*("|')\\nThe provided puzzle is unsolvable.\1\s*\)/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
return True
def is_valid(self, empty, num):
row, col = empty
valid_in_row = self.valid_in_row(row, num)
valid_in_col = self.valid_in_col(col, num)
valid_in_square = self.valid_in_square(row, col, num)
return all([valid_in_row, valid_in_col, valid_in_square])
def solver(self):
if (next_empty := self.find_empty_cell()) is None:
return True
else:
for guess in range(1, 10):
if self.is_valid(next_empty, guess):
row, col = next_empty
self.board[row][col] = guess
if self.solver():
return True
self.board[row][col] = 0
return False
--fcc-editable-region--
def solve_sudoku(board):
gameboard = Board(board)
print(f'\nPuzzle to solve:\n{gameboard}')
if gameboard.solver():
print('\nSolved puzzle:')
print(gameboard)
--fcc-editable-region--
```

View File

@@ -1,118 +0,0 @@
---
id: 6569fdc59fe1b658bc9e23a4
title: Step 78
challengeType: 20
dashedName: step-78
---
# --description--
In the end, return your instance of the `Board` class, which represents the final state of the sudoku board after attempting to solve it.
# --hints--
You should have `return gameboard` within the `solve_sudoku` function.
```js
const tCode = code.replace(/\r/g, '');
const {function_body} = __helpers.python.getDef(tCode, "solve_sudoku");
assert.match(function_body, /return\s+gameboard/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
return True
def is_valid(self, empty, num):
row, col = empty
valid_in_row = self.valid_in_row(row, num)
valid_in_col = self.valid_in_col(col, num)
valid_in_square = self.valid_in_square(row, col, num)
return all([valid_in_row, valid_in_col, valid_in_square])
def solver(self):
if (next_empty := self.find_empty_cell()) is None:
return True
else:
for guess in range(1, 10):
if self.is_valid(next_empty, guess):
row, col = next_empty
self.board[row][col] = guess
if self.solver():
return True
self.board[row][col] = 0
return False
--fcc-editable-region--
def solve_sudoku(board):
gameboard = Board(board)
print(f'\nPuzzle to solve:\n{gameboard}')
if gameboard.solver():
print('\nSolved puzzle:')
print(gameboard)
else:
print('\nThe provided puzzle is unsolvable.')
--fcc-editable-region--
```

View File

@@ -1,246 +0,0 @@
---
id: 6569fe0fe5b5425a1bb1f534
title: Step 79
challengeType: 20
dashedName: step-79
---
# --description--
Now it's time to play the game!
A puzzle has been given in the code.
Call the `solve_sudoku` method with `puzzle` as input.
Now, you can see the solved puzzle as the output.
With this, you are finished with building the sudoku solver!
# --hints--
Call the `solve_sudoku` method with `puzzle` as input.
```js
assert.match(code, /solve_sudoku\(\s*puzzle\s*\)/);
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
return True
def is_valid(self, empty, num):
row, col = empty
valid_in_row = self.valid_in_row(row, num)
valid_in_col = self.valid_in_col(col, num)
valid_in_square = self.valid_in_square(row, col, num)
return all([valid_in_row, valid_in_col, valid_in_square])
def solver(self):
if (next_empty := self.find_empty_cell()) is None:
return True
else:
for guess in range(1, 10):
if self.is_valid(next_empty, guess):
row, col = next_empty
self.board[row][col] = guess
if self.solver():
return True
self.board[row][col] = 0
return False
def solve_sudoku(board):
gameboard = Board(board)
print(f'\nPuzzle to solve:\n{gameboard}')
if gameboard.solver():
print('\nSolved puzzle:')
print(gameboard)
else:
print('\nThe provided puzzle is unsolvable.')
return gameboard
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
--fcc-editable-region--
```
# --solutions--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
upper_lines = f'\n╔═══{"╤═══"*2}{"╦═══"}{"╤═══"*2}{"╦═══"}{"╤═══"*2}\n'
middle_lines = f'╟───{"┼───"*2}{"╫───"}{"┼───"*2}{"╫───"}{"┼───"*2}\n'
lower_lines = f'╚═══{"╧═══"*2}{"╩═══"}{"╧═══"*2}{"╩═══"}{"╧═══"*2}\n'
board_string = upper_lines
for index, line in enumerate(self.board):
row_list = []
for square_no, part in enumerate([line[:3], line[3:6], line[6:]], start=1):
row_square = '|'.join(str(item) for item in part)
row_list.extend(row_square)
if square_no != 3:
row_list.append('')
row = f'{" ".join(row_list)}\n'
row_empty = row.replace('0', ' ')
board_string += row_empty
if index < 8:
if index % 3 == 2:
board_string += f'╠═══{"╪═══"*2}{"╬═══"}{"╪═══"*2}{"╬═══"}{"╪═══"*2}\n'
else:
board_string += middle_lines
else:
board_string += lower_lines
return board_string
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
def valid_in_col(self, col, num):
return all(
self.board[row][col] != num
for row in range(9)
)
def valid_in_square(self, row, col, num):
row_start = (row // 3) * 3
col_start=(col // 3) * 3
for row_no in range(row_start, row_start + 3):
for col_no in range(col_start, col_start + 3):
if self.board[row_no][col_no] == num:
return False
return True
def is_valid(self, empty, num):
row, col = empty
valid_in_row = self.valid_in_row(row, num)
valid_in_col = self.valid_in_col(col, num)
valid_in_square = self.valid_in_square(row, col, num)
return all([valid_in_row, valid_in_col, valid_in_square])
def solver(self):
if (next_empty := self.find_empty_cell()) is None:
return True
else:
for guess in range(1, 10):
if self.is_valid(next_empty, guess):
row, col = next_empty
self.board[row][col] = guess
if self.solver():
return True
self.board[row][col] = 0
return False
def solve_sudoku(board):
gameboard = Board(board)
print('\nPuzzle to solve:')
print(gameboard)
if gameboard.solver():
print('\nSolved puzzle:')
print(gameboard)
else:
print('\nThe provided puzzle is unsolvable.')
return gameboard
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
solve_sudoku(puzzle)
```

View File

@@ -1,5 +1,5 @@
---
id: 656873ffdc638f7e290f60de
id: 66068fb0bfddba2b7977eb60
title: Step 1
challengeType: 20
dashedName: step-1
@@ -11,20 +11,21 @@ In this project, you will learn about classes and objects by building a sudoku p
In Python, a class is a blueprint for creating objects. Objects created from a class are instances of that class. You can create a class using this syntax:
```js
```py
class ClassName:
pass
```
First, you will create a 9x9 board by using classes and then populate it with the puzzle values.
Where `class` is the keyword required to define the class and `ClassName` is the name of the class, written by convention in *PascalCase*.
Begin by creating a `Board` class.
# --hints--
Your class should be named `Board`.
You should create a class named `Board`.
```js
assert.match(code, /class\s+Board\s*\:/);
({ test: () => assert(runPython(`_Node(_code).has_class("Board")`)) })
```
# --seed--

View File

@@ -0,0 +1,37 @@
---
id: 66069167b3307b2f4067b22b
title: Step 2
challengeType: 20
dashedName: step-2
---
# --description--
A new instance of a class is created by using the function notation, which involves appending a pair of parentheses to the class name.
Outside the class definition, create an instance of the `Board` class and assign it to a variable named `gameboard`.
# --hints--
You should declare a variable `gameboard` outside the `Board` class.
```js
({ test: () => assert(runPython(`_Node(_code).has_variable("gameboard")`)) })
```
Your `gameboard` variable should have the value of `Board()`.
```js
({ test: () => assert(runPython(`_Node(_code).find_variable("gameboard").is_equivalent("gameboard = Board()")`)) })
```
# --seed--
## --seed-contents--
```py
--fcc-editable-region--
class Board:
pass
--fcc-editable-region--
```

View File

@@ -0,0 +1,39 @@
---
id: 6606927d010be4300a4e5330
title: Step 3
challengeType: 20
dashedName: step-3
---
# --description--
The instantiation creates an empty object. But classes can have methods, which are like local functions for each instance. Within a class, methods are declared as follows:
```py
class ClassName:
def method_name():
pass
```
Inside the `Board` class, replace `pass` with an empty method `spam`.
# --hints--
You should define a method named `spam` inside the `Board` class.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").has_function("spam")`)) })
```
# --seed--
## --seed-contents--
```py
--fcc-editable-region--
class Board:
pass
gameboard = Board()
--fcc-editable-region--
```

View File

@@ -0,0 +1,34 @@
---
id: 6606933d6813a8308c962dd1
title: Step 4
challengeType: 20
dashedName: step-4
---
# --description--
In order to be an instance method, a method requires a special parameter, named `self` by convention. This parameter is a reference to the instance of the class and must always be the first parameter.
Add a `self` parameter to your `spam` method.
# --hints--
Your `spam` method should have a `self` parameter.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("spam").has_args("self")`)) })
```
# --seed--
## --seed-contents--
```py
--fcc-editable-region--
class Board:
def spam():
pass
gameboard = Board()
--fcc-editable-region--
```

View File

@@ -0,0 +1,32 @@
---
id: 660699119472f332798860ad
title: Step 5
challengeType: 20
dashedName: step-5
---
# --description--
Now, replace `pass` with a `print` call and pass it the string `'Spam!'`.
# --hints--
You should delete `pass` and print the string `'Spam!'` within the `spam` method.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("spam").find_body().is_equivalent("print('Spam!')")`)) })
```
# --seed--
## --seed-contents--
```py
--fcc-editable-region--
class Board:
def spam(self):
pass
gameboard = Board()
--fcc-editable-region--
```

View File

@@ -0,0 +1,40 @@
---
id: 660699aabc59c532f2d556e5
title: Step 6
challengeType: 20
dashedName: step-6
---
# --description--
To call an instance method, you need to use dot notation:
```py
instance_name.method_name()
```
Where `instance_name` is the instance or object, and `method_name` is the method you want to call.
Call the `spam` method of the `gameboard` object.
# --hints--
You should call the `spam` method of the `gameboard` object with `gameboard.spam()`.
```js
({ test: () => assert(runPython(`_Node(_code).has_call("gameboard.spam()")`)) })
```
# --seed--
## --seed-contents--
```py
--fcc-editable-region--
class Board:
def spam(self):
print('Spam!')
gameboard = Board()
--fcc-editable-region--
```

View File

@@ -0,0 +1,33 @@
---
id: 66069b0b36053733a2f012fe
title: Step 7
challengeType: 20
dashedName: step-7
---
# --description--
Now, delete your `spam` call.
# --hints--
You should not have `gameboard.spam()` in your code.
```js
({ test: () => assert.isFalse(runPython(`_Node(_code).has_call("gameboard.spam()")`)) })
```
# --seed--
## --seed-contents--
```py
--fcc-editable-region--
class Board:
def spam(self):
print('Spam!')
gameboard = Board()
gameboard.spam()
--fcc-editable-region--
```

View File

@@ -0,0 +1,46 @@
---
id: 66069b992c1c5e3451f3deb0
title: Step 8
challengeType: 20
dashedName: step-8
---
# --description--
The instantiation creates an empty object. The `__init__` method is a special method that allows you to instantiate an object to a customized state. When a class implements an `__init__` method, `__init__` is automatically called upon instantiation.
Inside your `Board` class, delete the `spam` method and replace it with an `__init__` method that includes a `self` parameter.
# --hints--
You should not have a `spam` method in your `Board` class.
```js
({ test: () => assert.isFalse(runPython(`_Node(_code).find_class("Board").has_function("spam")`)) })
```
You should define an `__init__` method in your `Board` class.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").has_function("__init__")`)) })
```
Your `__init__` method should have a `self` parameter.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("__init__").has_args("self")`)) })
```
# --seed--
## --seed-contents--
```py
--fcc-editable-region--
class Board:
def spam(self):
print('Spam!')
gameboard = Board()
--fcc-editable-region--
```

View File

@@ -0,0 +1,51 @@
---
id: 66069d65162e61357c793e0c
title: Step 9
challengeType: 20
dashedName: step-9
---
# --description--
The sudoku puzzle to solve will be a list of lists, as the following:
```py
[
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
```
Note that the empty cells are filled with a zero.
Declare a `puzzle` variable and assign it the list of lists in the example above.
# --hints--
You should declare a variable `puzzle` and assign it the provided 2D-list.
```js
({ test: () => assert(runPython(`_Node(_code).find_variable("puzzle").is_equivalent("puzzle = [[0, 0, 2, 0, 0, 8, 0, 0, 0], [0, 0, 0, 0, 0, 3, 7, 6, 2], [4, 3, 0, 0, 0, 0, 8, 0, 0], [0, 5, 0, 0, 3, 0, 0, 9, 0], [0, 4, 0, 0, 0, 0, 0, 2, 6], [0, 0, 0, 4, 6, 7, 0, 0, 0], [0, 8, 6, 7, 0, 4, 0, 0, 0], [0, 0, 0, 5, 1, 9, 0, 0, 8], [1, 7, 0, 0, 0, 6, 0, 0, 5]]")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self):
pass
--fcc-editable-region--
--fcc-editable-region--
gameboard = Board()
```

View File

@@ -0,0 +1,53 @@
---
id: 66069e5759b800364707988e
title: Step 10
challengeType: 20
dashedName: step-10
---
# --description--
Going back to the `__init__` method, it requires an additional parameter representing the puzzle to solve.
Add a second parameter named `board` to the `__init__` method and fix the instantiation of `gameboard` by passing it the `puzzle` list as you would pass an argument to a function call.
# --hints--
Your `__init__` method should have two parameters in the order: `self`, and `board`.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("__init__").has_args("self, board")`)) })
```
Your `gameboard` variable should have the value of `Board(puzzle)`.
```js
({ test: () => assert(runPython(`_Node(_code).find_variable("gameboard").is_equivalent("gameboard = Board(puzzle)")`)) })
```
# --seed--
## --seed-contents--
```py
--fcc-editable-region--
class Board:
def __init__(self):
pass
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board()
--fcc-editable-region--
```

View File

@@ -0,0 +1,48 @@
---
id: 66069f86f58f85371d47123e
title: Step 11
challengeType: 20
dashedName: step-11
---
# --description--
An attribute is a variable associated with an object, which is used to store data as regular variables.
Inside the `__init__` method, assign the `board` parameter (which is passed when creating an instance of the `Board` class) to an instance attribute `board` using `self.board`.
`self.board` refers to the `board` attribute of the instance of the class. It's a variable that belongs to the object created from the `Board` class.
# --hints--
You should delete `pass` and assign the `board` parameter to `self.board` inside the `__init__` method.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("__init__").find_body().is_equivalent("self.board = board")`)) })
```
# --seed--
## --seed-contents--
```py
--fcc-editable-region--
class Board:
def __init__(self, board):
pass
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
--fcc-editable-region--
```

View File

@@ -0,0 +1,46 @@
---
id: 6606a219f9efbf38ad496f67
title: Step 12
challengeType: 20
dashedName: step-12
---
# --description--
You can also use dot notation to access an instance attribute.
Outside the `Board` class, after initializing the `gameboard` object, use `gameboard.board` to access the `board` attribute of your `gameboard` object and print the result to the screen.
# --hints--
You should print `gameboard.board`.
```js
({ test: () => assert(runPython(`_Node(_code).has_call("print(gameboard.board)")`)) })
```
# --seed--
## --seed-contents--
```py
--fcc-editable-region--
class Board:
def __init__(self, board):
self.board = board
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
--fcc-editable-region--
```

View File

@@ -0,0 +1,45 @@
---
id: 6606a2f8a6a36f39518e0439
title: Step 13
challengeType: 20
dashedName: step-13
---
# --description--
As you can see, the board is printed on the screen. Now, delete your `print` call.
# --hints--
You should not have `print(gameboard.board)` in your code.
```js
({ test: () => assert.isFalse(runPython(`_Node(_code).has_call("print(gameboard.board)")`)) })
```
# --seed--
## --seed-contents--
```py
--fcc-editable-region--
class Board:
def __init__(self, board):
self.board = board
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
print(gameboard.board)
--fcc-editable-region--
```

View File

@@ -0,0 +1,52 @@
---
id: 6606a3ccb1eea93a23c066bf
title: Step 14
challengeType: 20
dashedName: step-14
---
# --description--
Now you'll work on a method that finds the empty cells in the sudoku board.
Within the `Board` class, create an empty method named `find_empty_cell` and give it a `self` parameter.
# --hints--
You should define a method named `find_empty_cell` inside your `Board` class.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").has_function("find_empty_cell")`)) })
```
Your `find_empty_cell` method should have a parameter `self`.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("find_empty_cell").has_args("self")`)) })
```
# --seed--
## --seed-contents--
```py
--fcc-editable-region--
class Board:
def __init__(self, board):
self.board = board
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```

View File

@@ -0,0 +1,57 @@
---
id: 6606a4641ec48b3a9fe8c2fc
title: Step 15
challengeType: 20
dashedName: step-15
---
# --description--
The `enumerate` built-in function takes an iterable as its argument and returns an enumerate object you can iterate over.
It provides the count (which by default starts at zero) and the value from the iterable.
```py
iterable = ['a', 'b', 'c']
for i, j in enumerate(iterable):
print(i, j)
```
The loop from the example above would output the tuples `0, a`, `1, b`, and `2, c`.
Inside the `find_empty_cell` method, replace `pass` with a `for` loop that uses the `enumerate()` function to iterate over each row in the sudoku board. Use `row` as the index of the current row and `contents` for the elements of the current row.
# --hints--
You should replace `pass` with a `for` loop that iterates over `enumerate(self.board)`. Use `row` and `contents` as the loop variables.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("find_empty_cell").find_body().is_equivalent("for row, contents in enumerate(self.board):\\n pass")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
--fcc-editable-region--
def find_empty_cell(self):
pass
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```

View File

@@ -0,0 +1,48 @@
---
id: 6606b0d602d1e33e81bcef0d
title: Step 16
challengeType: 20
dashedName: step-16
---
# --description--
You need to locate the empty cell, which is filled with the number zero.
Replace `pass` with a variable `col` and assign it a call to `.index()` on `contents`, passing `0` as the argument.
# --hints--
You should replace `pass` with a variable `col` and assign it `contents.index(0)`.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("find_empty_cell").find_for_loops()[0].find_bodies()[0].is_equivalent("col = contents.index(0)")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
--fcc-editable-region--
def find_empty_cell(self):
for row, contents in enumerate(self.board):
pass
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```

View File

@@ -0,0 +1,55 @@
---
id: 6606b224a69a293f98f8db8f
title: Step 17
challengeType: 20
dashedName: step-17
---
# --description--
The `.index()` method raises a `ValueError` exception when the value is not found. To prevent the program from halting execution, you'll nest this line of code inside a `try` block. The `try` statement is used to encapsulate code that might raise an exception. The `except` clause, on the other hand, offers alternative code to execute if an exception occurs:
```py
try:
<code>
except:
<code>
```
Put the assignment of `col` inside a `try` block. Then, create an `except` clause and fill its body with `pass`.
# --hints--
You should put the assignment of `col` inside a `try` block and create an `except` clause.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("find_empty_cell").find_for_loops()[0].find_bodies()[0].is_equivalent("try:\\n col = contents.index(0)\\nexcept:\\n pass")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
--fcc-editable-region--
def find_empty_cell(self):
for row, contents in enumerate(self.board):
col = contents.index(0)
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```

View File

@@ -0,0 +1,51 @@
---
id: 6606b63c0fd55e4314d2ec85
title: Step 18
challengeType: 20
dashedName: step-18
---
# --description--
If `0` is found, the function should immediately return a tuple containing the row index and column index of the empty cell.
Inside the `try` block, after the assignment of `col`, return `row, col`.
# --hints--
You should return `row, col` from the `try` block.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("find_empty_cell").find_for_loops()[0].find_bodies()[0].is_equivalent("try:\\n col = contents.index(0)\\n return row, col\\nexcept:\\n pass")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
--fcc-editable-region--
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
except:
pass
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```

View File

@@ -0,0 +1,54 @@
---
id: 6606b6b7760d0643c3b4eb29
title: Step 19
challengeType: 20
dashedName: step-19
---
# --description--
If the code inside the `try` block raises an exception, you want the program to continue running, and the `pass` statement accomplishes this.
Although this code works, specifying the exception type after the `except` keyword is considered good practice.
Since you know that a `ValueError` might be raised, leave a space after the `except` keyword and add `ValueError` after that.
# --hints--
You should have `except ValueError:` in your code.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("find_empty_cell").find_for_loops()[0].find_bodies()[0].is_equivalent("try:\\n col = contents.index(0)\\n return row, col\\nexcept ValueError:\\n pass")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
--fcc-editable-region--
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except:
pass
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```

View File

@@ -0,0 +1,50 @@
---
id: 6606b8d31356fe4563f0e99c
title: Step 20
challengeType: 20
dashedName: step-20
---
# --description--
Outside the `for` loop, return `None`. This handles the case in which no empty cell is found, indicating that the sudoku board is completely filled.
# --hints--
You should return `None` after the `for` loop.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("find_empty_cell").has_return("None")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
--fcc-editable-region--
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```

View File

@@ -0,0 +1,56 @@
---
id: 6606b961ebcf04460f8af76e
title: Step 21
challengeType: 20
dashedName: step-21
---
# --description--
Test that the `find_empty_cell` method works properly by calling it on `gameboard` and printing the result.
Note that, although `find_empty_cell` is defined with one parameter, you must not give it a value by passing an argument to the function call, since `self` is automatically passed in as the object you are calling the method on.
# --hints--
You should print `gameboard.find_empty_cell()`.
```js
({ test: () => assert(runPython(`_Node(_code).has_call("print(gameboard.find_empty_cell())")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
--fcc-editable-region--
--fcc-editable-region--
```

Some files were not shown because too many files have changed in this diff Show More