chore(i18n,learn): processed translations (#54988)

Co-authored-by: Naomi <commits@nhcarrigan.com>
This commit is contained in:
freeCodeCamp's Camper Bot
2024-05-28 16:57:56 +09:00
committed by GitHub
co-authored by Naomi
parent 984d6419d9
commit 64697d4ca7
12651 changed files with 214325 additions and 270774 deletions
@@ -2,7 +2,6 @@
id: 587d781b367417b2b2512aba
title: Use the s Tag to Strikethrough Text
challengeType: 0
videoUrl: ''
forumTopicId: 301079
dashedName: use-the-s-tag-to-strikethrough-text
---
@@ -2,7 +2,6 @@
id: 5b7d72c338cd7e35b63f3e14
title: Improve Compatibility with Browser Fallbacks
challengeType: 0
videoUrl: ''
forumTopicId: 301087
dashedName: improve-compatibility-with-browser-fallbacks
---
@@ -2,7 +2,6 @@
id: 5ee127a03c3b35dd45426493
title: تعيين قيمة متغير إلى متغير آخر
challengeType: 1
videoUrl: ''
forumTopicId: 418265
dashedName: assigning-the-value-of-one-variable-to-another
---
@@ -1,38 +0,0 @@
---
id: 656873ffdc638f7e290f60de
title: الخطوة 1
challengeType: 20
dashedName: step-1
---
# --description--
In this project, you will learn about classes and objects by building a sudoku puzzle solver.
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
class ClassName:
```
First, you will create a 9x9 board by using classes and then populate it with the puzzle values.
Begin by creating a `Board` class.
# --hints--
Your class should be named `Board`.
```js
assert.match(code, /class\s+Board\s*\:/);
```
# --seed--
## --seed-contents--
```py
--fcc-editable-region--
--fcc-editable-region--
```
@@ -1,39 +0,0 @@
---
id: 656874efd5102b81815c8ef7
title: الخطوة 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--
```
@@ -1,33 +0,0 @@
---
id: 65688efcc78c9495e73acfc9
title: الخطوة 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--
```
@@ -1,32 +0,0 @@
---
id: 65688f22703200963a85dfb7
title: الخطوة 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--
```
@@ -1,60 +0,0 @@
---
id: 65688f737b0ef396bf0c22d6
title: الخطوة 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--
```
@@ -1,35 +0,0 @@
---
id: 65688f93a1b6e9970f710f62
title: الخطوة 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--
```
@@ -1,34 +0,0 @@
---
id: 65688fc27e8dda9760c45d7d
title: الخطوة 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--
```
@@ -1,35 +0,0 @@
---
id: 65689020cfd5279803976b25
title: الخطوة 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--
```
@@ -1,42 +0,0 @@
---
id: 6568904b83a2f29878578146
title: الخطوة 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--
```
@@ -1,52 +0,0 @@
---
id: 6568917528820d99236ad811
title: الخطوة 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--
```
@@ -1,57 +0,0 @@
---
id: 656896ffecbf07a2d3402a93
title: الخطوة 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--
```
@@ -1,48 +0,0 @@
---
id: 6568991b4d4874a4d5271337
title: الخطوة 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--
```
@@ -1,42 +0,0 @@
---
id: 6568994faf481da5d37bfa40
title: الخطوة 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--
```
@@ -1,59 +0,0 @@
---
id: 6568997f94c673a68b035b60
title: الخطوة 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--
```
@@ -1,41 +0,0 @@
---
id: 656899c0478950a7e5db2cc0
title: الخطوة 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--
```
@@ -1,42 +0,0 @@
---
id: 656899f4214ee6a881bc8649
title: الخطوة 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--
```
@@ -1,44 +0,0 @@
---
id: 65689a748de8fbaa00c5617e
title: الخطوة 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--
```
@@ -1,45 +0,0 @@
---
id: 65689aa3d3f2b6aad204a59e
title: الخطوة 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--
```
@@ -1,48 +0,0 @@
---
id: 65689ad61dfa81ab9ffafc86
title: الخطوة 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--
```
@@ -1,60 +0,0 @@
---
id: 65689b055e6f49ac6f82d3cf
title: الخطوة 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--
```
@@ -1,49 +0,0 @@
---
id: 6568a242a3e1efc22b07274d
title: الخطوة 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--
```
@@ -1,48 +0,0 @@
---
id: 6568bb1ffe8462c427c0d386
title: الخطوة 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--
```
@@ -1,51 +0,0 @@
---
id: 6568bb656c67e9c54cced2d7
title: الخطوة 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--
```
@@ -1,53 +0,0 @@
---
id: 6568bba429481cc693fc2570
title: الخطوة 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--
```
@@ -1,60 +0,0 @@
---
id: 6568bbc8c3bda1c773e23cf1
title: الخطوة 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--
```
@@ -1,64 +0,0 @@
---
id: 6568bc19f3418dc8a8821187
title: الخطوة 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--
```
@@ -1,61 +0,0 @@
---
id: 6568bc85c5beadca3e0f6eb1
title: الخطوة 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--
```
@@ -1,64 +0,0 @@
---
id: 6568bd3741e379ccc220af1b
title: الخطوة 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--
```
@@ -1,78 +0,0 @@
---
id: 6568bd85482755cdd26443ae
title: الخطوة 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--
```
@@ -1,61 +0,0 @@
---
id: 6568bdb69e05a9cee01068a8
title: الخطوة 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--
```
@@ -1,68 +0,0 @@
---
id: 6568beebba98a3d1f26f6bf8
title: الخطوة 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--
```
@@ -1,65 +0,0 @@
---
id: 6568bf22bb5de0d2e8260cf3
title: الخطوة 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--
```
@@ -1,64 +0,0 @@
---
id: 6568bf5e5b2f4bd3eb7ef995
title: الخطوة 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--
```
@@ -1,67 +0,0 @@
---
id: 6568bf853bf06dd4ed25d4ca
title: الخطوة 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--
```
@@ -1,75 +0,0 @@
---
id: 6568bfb601a54ed5b367b44f
title: الخطوة 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--
```
@@ -1,86 +0,0 @@
---
id: 6568bfd65322add674039bde
title: الخطوة 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--
```
@@ -1,71 +0,0 @@
---
id: 6568c0013b3b62d7617518c7
title: الخطوة 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--
```
@@ -1,76 +0,0 @@
---
id: 6568c024933423d85d5ed93c
title: الخطوة 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--
```
@@ -1,89 +0,0 @@
---
id: 6568c073d5f37fd99ab2ab0c
title: الخطوة 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--
```
@@ -1,77 +0,0 @@
---
id: 6568c0a5edddc3daa65d20b2
title: الخطوة 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--
```
@@ -1,77 +0,0 @@
---
id: 6569d83fe4dcc614c2ff971d
title: الخطوة 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)
```
@@ -1,87 +0,0 @@
---
id: 6569d8a4b8d85515cbb1ce72
title: الخطوة 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--
```
@@ -1,78 +0,0 @@
---
id: 6569d946293d4f185e32e2da
title: الخطوة 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--
```
@@ -1,96 +0,0 @@
---
id: 6569d98303af38193149b66e
title: الخطوة 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--
```
@@ -1,85 +0,0 @@
---
id: 6569d9dfd53db11b176d2963
title: الخطوة 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--
```
@@ -1,86 +0,0 @@
---
id: 6569da02e7e2641be14ff922
title: الخطوة 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--
```
@@ -1,83 +0,0 @@
---
id: 6569de93a5340b202667deda
title: الخطوة 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--
```
@@ -1,84 +0,0 @@
---
id: 6569def38470282151f873ce
title: الخطوة 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--
```
@@ -1,87 +0,0 @@
---
id: 6569df1d6fb83d22623b38c5
title: الخطوة 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--
```
@@ -1,86 +0,0 @@
---
id: 6569df6916294723e01f0035
title: الخطوة 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--
```
@@ -1,91 +0,0 @@
---
id: 6569df9e20f74a251d482c5d
title: الخطوة 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--
```
@@ -1,103 +0,0 @@
---
id: 6569dffeee007f26d2b56d46
title: الخطوة 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--
```
@@ -1,89 +0,0 @@
---
id: 6569e2a01a97b231862ba2ff
title: الخطوة 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--
```
@@ -1,90 +0,0 @@
---
id: 6569e2e1944fe7329ab21c7f
title: الخطوة 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--
```
@@ -1,93 +0,0 @@
---
id: 6569e309feb5d333867a034a
title: الخطوة 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--
```
@@ -1,94 +0,0 @@
---
id: 6569e33a708a3834f6d4879b
title: الخطوة 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--
```
@@ -1,93 +0,0 @@
---
id: 6569e37ec28e853628f18a86
title: الخطوة 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--
```
@@ -1,91 +0,0 @@
---
id: 6569e3a134fea0371fa008de
title: الخطوة 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--
```
@@ -1,105 +0,0 @@
---
id: 6569e3d1418b373839a0aa7b
title: الخطوة 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--
```
@@ -1,102 +0,0 @@
---
id: 6569e41657a9923953aa7d3c
title: الخطوة 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--
```
@@ -1,96 +0,0 @@
---
id: 6569e481e67f123ad25c5d20
title: الخطوة 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--
```
@@ -1,97 +0,0 @@
---
id: 6569f6b48716b5402504e216
title: الخطوة 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--
```
@@ -1,98 +0,0 @@
---
id: 6569f6ebe558bd4136da96cc
title: الخطوة 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--
```
@@ -1,100 +0,0 @@
---
id: 6569f70a66ccdc42097ca051
title: الخطوة 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--
```
@@ -1,101 +0,0 @@
---
id: 6569f770fd7dc443d6293095
title: الخطوة 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--
```
@@ -1,104 +0,0 @@
---
id: 6569f7c7f6954944d207775f
title: الخطوة 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--
```
@@ -1,103 +0,0 @@
---
id: 6569f7f2fa74c045e95676ac
title: الخطوة 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--
```
@@ -1,104 +0,0 @@
---
id: 6569fa5b9d507748bf4ec722
title: الخطوة 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--
```
@@ -1,115 +0,0 @@
---
id: 6569fa85d8f9ed49c8dfb37d
title: الخطوة 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--
```
@@ -1,108 +0,0 @@
---
id: 6569fabbfe1c094ad838ec4c
title: الخطوة 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--
```
@@ -1,106 +0,0 @@
---
id: 6569fbbfee025a4e850b6eaf
title: الخطوة 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--
```
@@ -1,128 +0,0 @@
---
id: 6569fc21837cab5029d82e26
title: الخطوة 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--
```
@@ -1,112 +0,0 @@
---
id: 6569fc63a404c8519d918095
title: الخطوة 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--
```
@@ -1,113 +0,0 @@
---
id: 6569fca3cd7a9f52f322a298
title: الخطوة 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--
```
@@ -1,124 +0,0 @@
---
id: 6569fd01dab2ea547d98f093
title: الخطوة 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--
```
@@ -1,115 +0,0 @@
---
id: 6569fd352879475599d0ec66
title: الخطوة 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--
```
@@ -1,125 +0,0 @@
---
id: 6569fd6d3cb95856c9ed2190
title: الخطوة 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--
```
@@ -1,118 +0,0 @@
---
id: 6569fdc59fe1b658bc9e23a4
title: الخطوة 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--
```
@@ -1,246 +0,0 @@
---
id: 6569fe0fe5b5425a1bb1f534
title: الخطوة 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)
```
@@ -20,7 +20,12 @@ You should declare a variable `row_str`.
You should assign a list comprehension that iterates over `row` to the `row_str` variable.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("__str__").find_for_loops()[0].find_bodies()[0].find_variable("row_str").find_comp_iters()[0].is_equivalent("row")`)) })
({ test: () => (runPython(`
import ast
var = _Node(_code).find_class("Board").find_function("__str__").find_for_loops()[0].find_bodies()[0].find_variable("row_str")
assert var.find_comp_iters()[0].is_equivalent("row"), "You should iterate over row"
assert isinstance(var.tree.value, ast.ListComp), "It's not a list comprehension"
`)) })
```
The list comprehension assigned to the `row_str` variable should use `i` as iteration variable.
@@ -13,7 +13,7 @@ Start by defining a function named `add_expense` that takes three parameters: `e
# --hints--
You should declare a function named `add_expense`.
You should use the `def` keyword to declare a function named `add_expense`.
```js
({ test: () => assert(runPython(`
@@ -7,13 +7,13 @@ dashedName: step-2
# --description--
A list in Python is a built-in data type that allows you to store many items in a single data structure. In Python, you create a list by putting items inside square brackets `[]`, with each item separated from the following one by a comma.
A list in Python is a built-in data type that allows you to store many items in a single data structure. In Python, you create a list by putting items inside square brackets (`[]`), with each item separated from the following one by a comma.
```py
numbers = [1, 2, 3, 4]
```
Create an empty list named `expenses`. You will use it to store each of your expenses.
Use a pair of square brackets to create an empty list named `expenses`. You will use it to store each of your expenses.
# --hints--
@@ -7,21 +7,29 @@ dashedName: step-3
# --description--
The `expenses` parameter of your `add_expense` function will be a list of expenses. You want to be able to add items at the end of your list. For that you can use the `.append()` list method:
The `expenses` parameter of your `add_expense` function will be a list of expenses. You want to be able to add items at the end of your list. For that you'll use the `.append()` list method:
```py
my_list = [2, 4, 7]
my_list.append(3)
```
In the example above, after appending `3`, `my_list` would be `[2, 4, 7, 3]`. Replace `pass` with a call to the `.append()` method on the `expenses` list. Don't pass any arguments to `.append()` for now.
In the example above, after appending `3`, `my_list` would be `[2, 4, 7, 3]`.
Replace `pass` with a call to the `.append()` method on the `expenses` list. Don't pass any arguments to `.append()` for now.
# --hints--
You should have `expenses.append()` in your function.
```js
assert.match(code, /^\s+expenses\.append\s*\(\s*\)/m)
({ test: () => assert(runPython(`_Node(_code).find_function("add_expense").has_stmt("expenses.append()")`)) })
```
You should not have `pass` in your function.
```js
({ test: () => assert.isFalse(runPython(`_Node(_code).find_function("add_expense").has_pass()`)) })
```
# --seed--
@@ -7,7 +7,7 @@ dashedName: step-4
# --description--
A dictionary is another built-in data type in Python. A dictionary is a collection of data in the form of *key*-*value* pairs. Dictionaries are defined with curly braces `{}` and they contain key-value pairs separated by commas. Each key is followed by a colon `:` and the value:
A dictionary is another built-in data type in Python. A dictionary is a collection of data in the form of *key*-*value* pairs. Dictionaries are defined with curly braces (`{}`) and they contain key-value pairs separated by commas. Each key is followed by a colon (`:`) and the value:
```py
{'amount': 50.0, 'category': 'Food'}
@@ -19,10 +19,20 @@ Create a dictionary with a key `'amount'` and value of the `amount` parameter an
# --hints--
You should have `expenses.append({'amount': amount})` in your function.
You should pass a dictionary as the argument to the `.append()` method.
```js
assert.match(code, /^\s+expenses\.append\s*\(\s*\{\s*("|')amount\1\s*:\s*amount\s*\}\s*\)/m)
({ test: () => assert(runPython(`
import ast
node = _Node(_code).find_function("add_expense").find_calls("append")[0].find_call_args()
len(node) == 1 and isinstance(node[0].tree, ast.Dict)
`)) })
```
You should pass `{'amount': amount}` as the argument to the `.append()` method.
```js
({ test: () => assert(runPython(`_Node(_code).find_function("add_expense").has_stmt("expenses.append({'amount': amount})")`)) })
```
# --seed--
@@ -11,10 +11,20 @@ Add another key-value pair to the dictionary you are appending to the `expense`
# --hints--
You should have `expenses.append({'amount': amount, 'category': category})` in your code.
You should add a second key-value pair to the dictionary you are passing as the argument to the `.append()` method.
```js
assert.match(code, /^\s+expenses\.append\s*\(\s*\{\s*("|')amount\1\s*:\s*amount\s*,\s*("|')category\2\s*:\s*category\s*\}\s*\)/m)
({ test: () => assert(runPython(`
import ast
node = _Node(_code).find_function("add_expense").find_calls("append")[0].find_call_args()
len(node) == 1 and isinstance(node[0].tree, ast.Dict) and len(node[0].tree.keys) == 2
`)) })
```
You should pass `{'amount': amount, 'category': category}` as the argument to the `.append()` method.
```js
({ test: () => assert(runPython(`_Node(_code).find_function("add_expense").has_stmt("expenses.append({'amount': amount, 'category': category})")`)) })
```
# --seed--
@@ -7,7 +7,7 @@ dashedName: step-6
# --description--
Start by defining a function named `print_expenses` that takes one parameter `expenses`. This function will later be used to display each expense in your list.
Next, define a function named `print_expenses` that takes one parameter `expenses`. This function will later be used to display each expense in your list.
Fill the body of your new function with a `pass` statement.
@@ -11,10 +11,22 @@ Inside the `print_expenses` function, create a `for` loop that iterates over eac
# --hints--
You should have `for expense in expenses:` in your `print_expenses` function. Remember to use `pass` within the loop body.
You should create a `for` loop that iterates over `expenses` in your `print_expenses` function. Remember to use `pass` within the loop body.
```js
({ test: () => assert.match(code, /for\s+expense\s+in\s+expenses\s*:/ ) })
({ test: () => assert(runPython(`_Node(_code).find_function("print_expenses").find_for_loops()[0].find_for_iter().is_equivalent("expenses")`)) })
```
You should use `expense` as the loop variable.
```js
({ test: () => assert(runPython(`_Node(_code).find_function("print_expenses").find_for_loops()[0].find_for_vars().is_equivalent("expense")`)) })
```
You should have `pass` only inside your loop body.
```js
({ test: () => assert.isFalse(runPython(`_Node(_code).find_function("print_expenses").has_pass()`)) })
```
# --seed--
@@ -9,14 +9,20 @@ dashedName: step-8
Next, you are going to display the details for each expense.
Inside the `for` loop, replace `pass` with a `print()` call and pass it the following f-string: `f'Amount: {expense}, Category: {expense}'`. Leave the placeholders empty for now.
Inside the `for` loop, replace `pass` with a `print()` call and pass it the following f-string: `f'Amount: {expense}, Category: {expense}'`.
# --hints--
You should have `print(f'Amount: {expense}, Category: {expense}')` in your `for` loop.
You should print `f'Amount: {expense}, Category: {expense}'` in your `for` loop.
```js
({ test: () => assert.match(code, /^\s+print\s*\(\s*f("|')Amount: \{\s*expense\s*\}, Category: \{\s*expense\s*\}\1\s*\)/m) })
({ test: () => assert(runPython(`_Node(_code).find_function("print_expenses").find_for_loops()[0].has_call("print(f'Amount: {expense}, Category: {expense}')")`)) })
```
You should not have `pass` inside your loop body.
```js
({ test: () => assert.isFalse(runPython(`_Node(_code).find_function("print_expenses").find_for_loops()[0].find_bodies()[0].has_pass()`)) })
```
# --seed--
@@ -7,7 +7,12 @@ dashedName: step-9
# --description--
You can access values in a dictionary through its keys. You need to use the bracket notation and include the key between the square brackets:
In Python, an important thing to know is that the same type of quote used to define a string cannot be used inside it. For example, the string `'I'm a string!'` is not valid. To use the single quote inside that string you should either:
- Escape the quote by prepending a backlash to it: `'I\'m a string!'`
- Or use double quotes to define the string: `"I'm a string!"` (preferred).
You can access values in a dictionary through its keys. You need to use bracket notation and include the key between the square brackets:
```py
my_dict = {'amount': 50.0, 'category': 'Food'}
@@ -7,7 +7,9 @@ dashedName: step-10
# --description--
You will need a function to calculate the total amount of expenses. Define a function named `total_expenses` that takes one parameter `expenses`. Fill the function body with a `pass` statement for now.
You will need a function to calculate the total amount of expenses.
Define a function named `total_expenses` that takes one parameter `expenses`. Fill the function body with a `pass` statement for now.
# --hints--
@@ -21,7 +23,7 @@ You should define a function named `total_expenses`.
})
```
Your`total_expenses` function should take a single `expenses` parameter.
Your `total_expenses` function should take a single `expenses` parameter.
```js
({ test: () => assert(runPython(`
@@ -13,14 +13,22 @@ Lambda functions are brief, anonymous functions in Python, ideal for simple, one
lambda x: expr
```
In the example above, `x` is a parameter to be used in the expression `expr`. Create a `test` variable and assign it a lambda function that takes an `x` parameter and returns `x * 2`.
In the example above, `x` represents a parameter to be used in the expression `expr`, and it acts just like any parameter in a traditional function. `expr` is the expression that gets evaluated and returned when the lambda function is called.
Create a variable named `test` and assign it a lambda function that takes an `x` parameter and returns `x * 2`.
# --hints--
You should have `test = lambda x: x * 2` in your code.
You should declare a variable named `test`.
```js
({ test: () => assert.match(code,/^test\s*=\s*lambda\s+x\s*:\s*x\s*\*\s*2/m)})
({ test: () => assert(runPython(`_Node(_code).has_variable("test")`))})
```
You should assign `lambda x: x * 2` to your `test` variable.
```js
({ test: () => assert(runPython(`_Node(_code).find_variable("test").is_equivalent("test = lambda x: x * 2")`))})
```
# --seed--
@@ -13,9 +13,11 @@ Lambda functions can be valuably combined with the `map()` function, which execu
map(lambda x: x * 2, [1, 2, 3])
```
The function to execute is passed as the first argument, and the iterable is passed as the second argument.
The result of the example above would be `[2, 4, 6]`, where each item in the list passed to `map()` has been doubled by the action of the lambda function.
Modify your `print()` call to print the result of calling `map()` with `test` as the first argument, and `[2, 3, 5, 8]` as the second argument.
Modify your `print()` call to print the result of calling `map()` with `test` as the first argument, and `[2, 3, 5, 8]` as the second argument. You won't be able to see a readable output yet.
# --hints--
@@ -1,6 +1,6 @@
---
id: 658238f7604f154ea9a23e1e
title: الخطوة 14
title: Step 15
challengeType: 20
dashedName: step-15
---
@@ -9,7 +9,7 @@ dashedName: step-15
The `sum()` function returns the sum of the items in the iterable which is passed as its argument. You are going to use `sum()` together with `map()` and `lambda` functions to get the total amount of expenses.
For now, make a little test and modify your current `print()` call by passing `sum(map(test, [2, 3, 5, 8]))` as the argument.
For now, make a little test and modify your current `print()` call replacing the `list()` call with a call to the `sum()` function passing it the current `map()` call as the argument.
# --hints--
@@ -36,7 +36,7 @@ def total_expenses(expenses):
--fcc-editable-region--
test = lambda x: x * 2
print(map(test, [2, 3, 5, 8]))
print(list(map(test, [2,3,5,8])))
--fcc-editable-region--
expenses = []
@@ -1,28 +1,22 @@
---
id: 65823b0167fd894f4a7ea60a
title: الخطوة 15
title: Step 16
challengeType: 20
dashedName: step-16
---
# --description--
Next, you are going to implement the same logic to the `total_expenses` function.
Next, you are going to implement the same logic within the `total_expenses` function.
For now, delete both the `test` function and the `print()` call.
# --hints--
You should delete your `test` variable.
You should delete your `test` variable and the related `print()` call.
```js
({ test: () => assert.notMatch(code, /test\s*=/) })
```
You should delete your `print(sum(map(test, [2, 3, 5, 8])))` call.
```js
({ test: () => assert.notMatch(code, /print\s*\(\s*sum/) })
({ test: () => assert.isFalse(runPython(`_Node(_code).has_variable("test")`)) })
```
# --seed--
@@ -1,27 +1,28 @@
---
id: 65823bbbdb4eaa4f9d20a0fb
title: الخطوة 16
title: Step 17
challengeType: 20
dashedName: step-17
---
# --description--
Within your `total_expenses` function, replace `pass` with a `lambda` function. Use `expense` as the parameter and return the value of the `'amount'` key in the `expense` dictionary.
In the `total_expenses` function, you'll now integrate a lambda function. Replace `pass` with a lambda function that has `expense` as its parameter.
`expense` is expected to be a dictionary, and your lambda function should return the value of the `'amount'` key in the `expense` dictionary.
# --hints--
You should have `lambda expense: expense['amount']` in your `total_expenses` function.
You should create a `lambda` function that uses the parameter `expense` and returns `expense['amount']` in your `total_expenses` function.
```js
({ test: () =>
{
const transformedCode = code.replace(/\r/g, "");
const foo = __helpers.python.getDef("\n"+transformedCode, "total_expenses");
const {function_body} = foo;
assert(function_body.match(/^\s+lambda\s+expense\s*:\s*expense\s*\[\s*("|')amount\1\s*\]/m));
}
})
({ test: () => assert(runPython(`_Node(_code).find_function("total_expenses").has_stmt("lambda expense: expense['amount']")`)) })
```
You should not have `pass` in your `total_expenses` function.
```js
({ test: () => assert.isFalse(runPython(`_Node(_code).find_function("total_expenses").has_pass()`)) })
```
# --seed--
@@ -1,6 +1,6 @@
---
id: 65823cfc74aa564ffc460489
title: الخطوة 17
title: Step 18
challengeType: 20
dashedName: step-18
---
@@ -11,17 +11,22 @@ Now, call `map()` passing your `lambda` function as the first argument and the `
# --hints--
You should have `map(lambda expense: expense['amount'], expenses)` in your code.
You should call the `map()` function inside the `total_expenses` function.
```js
({ test: () =>
{
const transformedCode = code.replace(/\r/g, "");
const foo = __helpers.python.getDef("\n"+transformedCode, "total_expenses");
const {function_body} = foo;
assert(function_body.match(/^\s+map\s*\(\s*lambda\s+expense\s*:\s*expense\s*\[\s*("|')amount\1\s*\]\s*,\s*expenses\s*\)/m));
}
})
({ test: () => assert(runPython(`len(_Node(_code).find_function("total_expenses").find_calls("map")) == 1`)) })
```
You should pass your `lambda` function as the first argument to the `map()` call.
```js
({ test: () => assert(runPython(`_Node(_code).find_function("total_expenses").find_calls("map")[0].find_call_args()[0].is_equivalent("lambda expense: expense['amount']")`)) })
```
You should pass the `expenses` list as the second argument to the `map()` call.
```js
({ test: () => assert(runPython(`_Node(_code).find_function("total_expenses").find_calls("map")[0].find_call_args()[1].is_equivalent("expenses")`)) })
```
# --seed--
@@ -1,6 +1,6 @@
---
id: 65823dde36392f505a39f7c7
title: الخطوة 18
title: Step 19
challengeType: 20
dashedName: step-19
---
@@ -11,17 +11,10 @@ Finally, pass your `map()` call to the `sum()` function to obtain the total expe
# --hints--
You should return `sum(map(lambda expense: expense['amount'], expenses))` from your `total_expenses` function.
You should call the `sum()` function passing it your current `map()` call as the argument and return the result from your `total_expenses` function.
```js
({ test: () =>
{
const transformedCode = code.replace(/\r/g, "");
const foo = __helpers.python.getDef("\n"+transformedCode, "total_expenses");
const {function_body} = foo;
assert(function_body.match(/^\s+return\s+sum\s*\(\s*map\s*\(\s*lambda\s+expense\s*:\s*expense\s*\[\s*("|')amount\1\s*\]\s*,\s*expenses\s*\)\s*\)/m));
}
})
({ test: () => assert(runPython(`_Node(_code).find_function("total_expenses").has_return("sum(map(lambda expense: expense['amount'], expenses))")`)) })
```
# --seed--

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