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

This commit is contained in:
freeCodeCamp's Camper Bot
2024-05-07 17:04:55 -05:00
committed by GitHub
parent bd1e5b5403
commit 7af1afe283
2604 changed files with 108912 additions and 929 deletions
@@ -0,0 +1,39 @@
---
id: 66068fb0bfddba2b7977eb60
title: Step 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:
```py
class ClassName:
pass
```
Where `class` is the keyword required to define the class and `ClassName` is the name of the class, written by convention in *PascalCase*.
Begin by creating a `Board` class.
# --hints--
You should create a class named `Board`.
```js
({ test: () => assert(runPython(`_Node(_code).has_class("Board")`)) })
```
# --seed--
## --seed-contents--
```py
--fcc-editable-region--
--fcc-editable-region--
```
@@ -0,0 +1,37 @@
---
id: 66069167b3307b2f4067b22b
title: Step 2
challengeType: 20
dashedName: step-2
---
# --description--
A new instance of a class is created by using the function notation, which involves appending a pair of parentheses to the class name.
Outside the class definition, create an instance of the `Board` class and assign it to a variable named `gameboard`.
# --hints--
You should declare a variable `gameboard` outside the `Board` class.
```js
({ test: () => assert(runPython(`_Node(_code).has_variable("gameboard")`)) })
```
Your `gameboard` variable should have the value of `Board()`.
```js
({ test: () => assert(runPython(`_Node(_code).find_variable("gameboard").is_equivalent("gameboard = Board()")`)) })
```
# --seed--
## --seed-contents--
```py
--fcc-editable-region--
class Board:
pass
--fcc-editable-region--
```
@@ -0,0 +1,39 @@
---
id: 6606927d010be4300a4e5330
title: Step 3
challengeType: 20
dashedName: step-3
---
# --description--
The instantiation creates an empty object. But classes can have methods, which are like local functions for each instance. Within a class, methods are declared as follows:
```py
class ClassName:
def method_name():
pass
```
Inside the `Board` class, replace `pass` with an empty method `spam`.
# --hints--
You should define a method named `spam` inside the `Board` class.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").has_function("spam")`)) })
```
# --seed--
## --seed-contents--
```py
--fcc-editable-region--
class Board:
pass
gameboard = Board()
--fcc-editable-region--
```
@@ -0,0 +1,34 @@
---
id: 6606933d6813a8308c962dd1
title: Step 4
challengeType: 20
dashedName: step-4
---
# --description--
In order to be an instance method, a method requires a special parameter, named `self` by convention. This parameter is a reference to the instance of the class and must always be the first parameter.
Add a `self` parameter to your `spam` method.
# --hints--
Your `spam` method should have a `self` parameter.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("spam").has_args("self")`)) })
```
# --seed--
## --seed-contents--
```py
--fcc-editable-region--
class Board:
def spam():
pass
gameboard = Board()
--fcc-editable-region--
```
@@ -0,0 +1,32 @@
---
id: 660699119472f332798860ad
title: Step 5
challengeType: 20
dashedName: step-5
---
# --description--
Now, replace `pass` with a `print` call and pass it the string `'Spam!'`.
# --hints--
You should delete `pass` and print the string `'Spam!'` within the `spam` method.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("spam").find_body().is_equivalent("print('Spam!')")`)) })
```
# --seed--
## --seed-contents--
```py
--fcc-editable-region--
class Board:
def spam(self):
pass
gameboard = Board()
--fcc-editable-region--
```
@@ -0,0 +1,40 @@
---
id: 660699aabc59c532f2d556e5
title: Step 6
challengeType: 20
dashedName: step-6
---
# --description--
To call an instance method, you need to use dot notation:
```py
instance_name.method_name()
```
Where `instance_name` is the instance or object, and `method_name` is the method you want to call.
Call the `spam` method of the `gameboard` object.
# --hints--
You should call the `spam` method of the `gameboard` object with `gameboard.spam()`.
```js
({ test: () => assert(runPython(`_Node(_code).has_call("gameboard.spam()")`)) })
```
# --seed--
## --seed-contents--
```py
--fcc-editable-region--
class Board:
def spam(self):
print('Spam!')
gameboard = Board()
--fcc-editable-region--
```
@@ -0,0 +1,33 @@
---
id: 66069b0b36053733a2f012fe
title: Step 7
challengeType: 20
dashedName: step-7
---
# --description--
Now, delete your `spam` call.
# --hints--
You should not have `gameboard.spam()` in your code.
```js
({ test: () => assert.isFalse(runPython(`_Node(_code).has_call("gameboard.spam()")`)) })
```
# --seed--
## --seed-contents--
```py
--fcc-editable-region--
class Board:
def spam(self):
print('Spam!')
gameboard = Board()
gameboard.spam()
--fcc-editable-region--
```
@@ -0,0 +1,46 @@
---
id: 66069b992c1c5e3451f3deb0
title: Step 8
challengeType: 20
dashedName: step-8
---
# --description--
The instantiation creates an empty object. The `__init__` method is a special method that allows you to instantiate an object to a customized state. When a class implements an `__init__` method, `__init__` is automatically called upon instantiation.
Inside your `Board` class, delete the `spam` method and replace it with an `__init__` method that includes a `self` parameter.
# --hints--
You should not have a `spam` method in your `Board` class.
```js
({ test: () => assert.isFalse(runPython(`_Node(_code).find_class("Board").has_function("spam")`)) })
```
You should define an `__init__` method in your `Board` class.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").has_function("__init__")`)) })
```
Your `__init__` method should have a `self` parameter.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("__init__").has_args("self")`)) })
```
# --seed--
## --seed-contents--
```py
--fcc-editable-region--
class Board:
def spam(self):
print('Spam!')
gameboard = Board()
--fcc-editable-region--
```
@@ -0,0 +1,51 @@
---
id: 66069d65162e61357c793e0c
title: Step 9
challengeType: 20
dashedName: step-9
---
# --description--
The sudoku puzzle to solve will be a list of lists, as the following:
```py
[
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
```
Note that the empty cells are filled with a zero.
Declare a `puzzle` variable and assign it the list of lists in the example above.
# --hints--
You should declare a variable `puzzle` and assign it the provided 2D-list.
```js
({ test: () => assert(runPython(`_Node(_code).find_variable("puzzle").is_equivalent("puzzle = [[0, 0, 2, 0, 0, 8, 0, 0, 0], [0, 0, 0, 0, 0, 3, 7, 6, 2], [4, 3, 0, 0, 0, 0, 8, 0, 0], [0, 5, 0, 0, 3, 0, 0, 9, 0], [0, 4, 0, 0, 0, 0, 0, 2, 6], [0, 0, 0, 4, 6, 7, 0, 0, 0], [0, 8, 6, 7, 0, 4, 0, 0, 0], [0, 0, 0, 5, 1, 9, 0, 0, 8], [1, 7, 0, 0, 0, 6, 0, 0, 5]]")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self):
pass
--fcc-editable-region--
--fcc-editable-region--
gameboard = Board()
```
@@ -0,0 +1,53 @@
---
id: 66069e5759b800364707988e
title: Step 10
challengeType: 20
dashedName: step-10
---
# --description--
Going back to the `__init__` method, it requires an additional parameter representing the puzzle to solve.
Add a second parameter named `board` to the `__init__` method and fix the instantiation of `gameboard` by passing it the `puzzle` list as you would pass an argument to a function call.
# --hints--
Your `__init__` method should have two parameters in the order: `self`, and `board`.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("__init__").has_args("self, board")`)) })
```
Your `gameboard` variable should have the value of `Board(puzzle)`.
```js
({ test: () => assert(runPython(`_Node(_code).find_variable("gameboard").is_equivalent("gameboard = Board(puzzle)")`)) })
```
# --seed--
## --seed-contents--
```py
--fcc-editable-region--
class Board:
def __init__(self):
pass
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board()
--fcc-editable-region--
```
@@ -0,0 +1,48 @@
---
id: 66069f86f58f85371d47123e
title: Step 11
challengeType: 20
dashedName: step-11
---
# --description--
An attribute is a variable associated with an object, which is used to store data as regular variables.
Inside the `__init__` method, assign the `board` parameter (which is passed when creating an instance of the `Board` class) to an instance attribute `board` using `self.board`.
`self.board` refers to the `board` attribute of the instance of the class. It's a variable that belongs to the object created from the `Board` class.
# --hints--
You should delete `pass` and assign the `board` parameter to `self.board` inside the `__init__` method.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("__init__").find_body().is_equivalent("self.board = board")`)) })
```
# --seed--
## --seed-contents--
```py
--fcc-editable-region--
class Board:
def __init__(self, board):
pass
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
--fcc-editable-region--
```
@@ -0,0 +1,46 @@
---
id: 6606a219f9efbf38ad496f67
title: Step 12
challengeType: 20
dashedName: step-12
---
# --description--
You can also use dot notation to access an instance attribute.
Outside the `Board` class, after initializing the `gameboard` object, use `gameboard.board` to access the `board` attribute of your `gameboard` object and print the result to the screen.
# --hints--
You should print `gameboard.board`.
```js
({ test: () => assert(runPython(`_Node(_code).has_call("print(gameboard.board)")`)) })
```
# --seed--
## --seed-contents--
```py
--fcc-editable-region--
class Board:
def __init__(self, board):
self.board = board
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
--fcc-editable-region--
```
@@ -0,0 +1,45 @@
---
id: 6606a2f8a6a36f39518e0439
title: Step 13
challengeType: 20
dashedName: step-13
---
# --description--
As you can see, the board is printed on the screen. Now, delete your `print` call.
# --hints--
You should not have `print(gameboard.board)` in your code.
```js
({ test: () => assert.isFalse(runPython(`_Node(_code).has_call("print(gameboard.board)")`)) })
```
# --seed--
## --seed-contents--
```py
--fcc-editable-region--
class Board:
def __init__(self, board):
self.board = board
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
print(gameboard.board)
--fcc-editable-region--
```
@@ -0,0 +1,52 @@
---
id: 6606a3ccb1eea93a23c066bf
title: Step 14
challengeType: 20
dashedName: step-14
---
# --description--
Now you'll work on a method that finds the empty cells in the sudoku board.
Within the `Board` class, create an empty method named `find_empty_cell` and give it a `self` parameter.
# --hints--
You should define a method named `find_empty_cell` inside your `Board` class.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").has_function("find_empty_cell")`)) })
```
Your `find_empty_cell` method should have a parameter `self`.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("find_empty_cell").has_args("self")`)) })
```
# --seed--
## --seed-contents--
```py
--fcc-editable-region--
class Board:
def __init__(self, board):
self.board = board
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,56 @@
---
id: 6606a4641ec48b3a9fe8c2fc
title: Step 15
challengeType: 20
dashedName: step-15
---
# --description--
The `enumerate` built-in function takes an iterable as its argument and returns an enumerate object you can iterate over. It provides the count (which by default starts at zero) and the value from the iterable.
```py
iterable = ['a', 'b', 'c']
for i, j in enumerate(iterable):
print(i, j)
```
The loop from the example above would output the tuples `0, a`, `1, b`, and `2, c`.
Inside the `find_empty_cell` method, replace `pass` with a `for` loop that uses the `enumerate()` function to iterate over each row in the sudoku board. Use `row` as the index of the current row and `contents` for the elements of the current row.
# --hints--
You should replace `pass` with a `for` loop that iterates over `enumerate(self.board)`. Use `row` and `contents` as the loop variables.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("find_empty_cell").find_body().is_equivalent("for row, contents in enumerate(self.board):\\n pass")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
--fcc-editable-region--
def find_empty_cell(self):
pass
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,48 @@
---
id: 6606b0d602d1e33e81bcef0d
title: Step 16
challengeType: 20
dashedName: step-16
---
# --description--
You need to locate the empty cell, which is filled with the number zero.
Replace `pass` with a variable `col` and assign it a call to `.index()` on `contents`, passing `0` as the argument.
# --hints--
You should replace `pass` with a variable `col` and assign it `contents.index(0)`.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("find_empty_cell").find_for_loops()[0].find_bodies()[0].is_equivalent("col = contents.index(0)")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
--fcc-editable-region--
def find_empty_cell(self):
for row, contents in enumerate(self.board):
pass
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,55 @@
---
id: 6606b224a69a293f98f8db8f
title: Step 17
challengeType: 20
dashedName: step-17
---
# --description--
The `.index()` method raises a `ValueError` exception when the value is not found. To prevent the program from halting execution, you'll nest this line of code inside a `try` block. The `try` statement is used to encapsulate code that might raise an exception. The `except` clause, on the other hand, offers alternative code to execute if an exception occurs:
```py
try:
<code>
except:
<code>
```
Put the assignment of `col` inside a `try` block. Then, create an `except` clause and fill its body with `pass`.
# --hints--
You should put the assignment of `col` inside a `try` block and create an `except` clause.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("find_empty_cell").find_for_loops()[0].find_bodies()[0].is_equivalent("try:\\n col = contents.index(0)\\nexcept:\\n pass")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
--fcc-editable-region--
def find_empty_cell(self):
for row, contents in enumerate(self.board):
col = contents.index(0)
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,51 @@
---
id: 6606b63c0fd55e4314d2ec85
title: Step 18
challengeType: 20
dashedName: step-18
---
# --description--
If `0` is found, the function should immediately return a tuple containing the row index and column index of the empty cell.
Inside the `try` block, after the assignment of `col`, return `row, col`.
# --hints--
You should return `row, col` from the `try` block.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("find_empty_cell").find_for_loops()[0].find_bodies()[0].is_equivalent("try:\\n col = contents.index(0)\\n return row, col\\nexcept:\\n pass")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
--fcc-editable-region--
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
except:
pass
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,54 @@
---
id: 6606b6b7760d0643c3b4eb29
title: Step 19
challengeType: 20
dashedName: step-19
---
# --description--
If the code inside the `try` block raises an exception, you want the program to continue running, and the `pass` statement accomplishes this.
Although this code works, specifying the exception type after the `except` keyword is considered good practice.
Since you know that a `ValueError` might be raised, leave a space after the `except` keyword and add `ValueError` after that.
# --hints--
You should have `except ValueError:` in your code.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("find_empty_cell").find_for_loops()[0].find_bodies()[0].is_equivalent("try:\\n col = contents.index(0)\\n return row, col\\nexcept ValueError:\\n pass")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
--fcc-editable-region--
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except:
pass
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,50 @@
---
id: 6606b8d31356fe4563f0e99c
title: Step 20
challengeType: 20
dashedName: step-20
---
# --description--
Outside the `for` loop, return `None`. This handles the case in which no empty cell is found, indicating that the sudoku board is completely filled.
# --hints--
You should return `None` after the `for` loop.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("find_empty_cell").has_return("None")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
--fcc-editable-region--
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,56 @@
---
id: 6606b961ebcf04460f8af76e
title: Step 21
challengeType: 20
dashedName: step-21
---
# --description--
Test that the `find_empty_cell` method works properly by calling it on `gameboard` and printing the result.
Note that, although `find_empty_cell` is defined with one parameter, you must not give it a value by passing an argument to the function call, since `self` is automatically passed in as the object you are calling the method on.
# --hints--
You should print `gameboard.find_empty_cell()`.
```js
({ test: () => assert(runPython(`_Node(_code).has_call("print(gameboard.find_empty_cell())")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
--fcc-editable-region--
--fcc-editable-region--
```
@@ -0,0 +1,54 @@
---
id: 6606baaf1828ff46ebcc008c
title: Step 22
challengeType: 20
dashedName: step-22
---
# --description--
`find_empty_cell` is returning `(0, 0)`, which is the position of the first empty cell in the sudoku board.
Turn the first `0` inside `puzzle` into a `1`. You will see in the output that the next empty cell will be found.
# --hints--
You should modify the first item of the first list in `puzzle` into a `1`.
```js
({ test: () => assert(runPython(`_Node(_code).find_variable("puzzle").is_equivalent("puzzle = [[1, 0, 2, 0, 0, 8, 0, 0, 0], [0, 0, 0, 0, 0, 3, 7, 6, 2], [4, 3, 0, 0, 0, 0, 8, 0, 0], [0, 5, 0, 0, 3, 0, 0, 9, 0], [0, 4, 0, 0, 0, 0, 0, 2, 6], [0, 0, 0, 4, 6, 7, 0, 0, 0], [0, 8, 6, 7, 0, 4, 0, 0, 0], [0, 0, 0, 5, 1, 9, 0, 0, 8], [1, 7, 0, 0, 0, 6, 0, 0, 5]]")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
--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--
gameboard = Board(puzzle)
print(gameboard.find_empty_cell())
```
@@ -0,0 +1,59 @@
---
id: 6606bbd52233b247cf0a56e4
title: Step 23
challengeType: 20
dashedName: step-23
---
# --description--
Now, turn the `1` you modified earlier back into a `0` to restore the original board configuration. Then, delete your `print` call.
# --hints--
You should turn the first item of the first list of `puzzle` back into a zero.
```js
({ test: () => assert(runPython(`_Node(_code).find_variable("puzzle").is_equivalent("puzzle = [[0, 0, 2, 0, 0, 8, 0, 0, 0], [0, 0, 0, 0, 0, 3, 7, 6, 2], [4, 3, 0, 0, 0, 0, 8, 0, 0], [0, 5, 0, 0, 3, 0, 0, 9, 0], [0, 4, 0, 0, 0, 0, 0, 2, 6], [0, 0, 0, 4, 6, 7, 0, 0, 0], [0, 8, 6, 7, 0, 4, 0, 0, 0], [0, 0, 0, 5, 1, 9, 0, 0, 8], [1, 7, 0, 0, 0, 6, 0, 0, 5]]")`)) })
```
You should not have `print(gameboard.find_empty_cell())` in your code.
```js
({ test: () => assert.isFalse(runPython(`_Node(_code).has_call("print(gameboard.find_empty_cell())")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
--fcc-editable-region--
puzzle = [
[1, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
print(gameboard.find_empty_cell())
--fcc-editable-region--
```
@@ -0,0 +1,62 @@
---
id: 6606bc4e5535c0484990ccd5
title: Step 24
challengeType: 20
dashedName: step-24
---
# --description--
Next, you're going to work on a method that checks if a given number can be inserted into a specified row of the sudoku board.
Within the `Board` class, create a method named `valid_in_row` and give it three parameters: `self`, `row`, and `num`. Where `self` represents the instance of the class, and `row` and `num` are the row index and the number to be checked, respectively.
# --hints--
You should create a new method named `valid_in_row` within the `Board` class.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").has_function("valid_in_row")`)) })
```
Your `valid_in_row` method should have three parameters: `self`, `row`, and `num`, in this order.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("valid_in_row").has_args("self, row, num")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
--fcc-editable-region--
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,54 @@
---
id: 6606bd3d02e86548d3ce1a0a
title: Step 25
challengeType: 20
dashedName: step-25
---
# --description--
Replace `pass` with an expression that checks if the number `num` is not already present in that row.
# --hints--
You should replace `pass` with the expression `num not in self.board[row]`.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("valid_in_row").find_body().is_equivalent("num not in self.board[row]")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
--fcc-editable-region--
def valid_in_row(self, row, num):
pass
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,58 @@
---
id: 6606beade9200b49aaeecd94
title: Step 26
challengeType: 20
dashedName: step-26
---
# --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.
Prepend a `return` keyword to the expression inside the `valid_in_row` method body, so that the validity of the number can be checked.
# --hints--
You should return `num not in self.board[row]`.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("valid_in_row").find_body().is_equivalent("return num not in self.board[row]")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
--fcc-editable-region--
def valid_in_row(self, row, num):
num not in self.board[row]
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,59 @@
---
id: 6606bf4561f8794a0d345919
title: Step 27
challengeType: 20
dashedName: step-27
---
# --description--
It's time to test the `valid_in_row` method. Call `valid_in_row` on `gameboard`. Pass it `0` and `8` as the arguments and print the result.
Again, note how the method is defined with three parameters, yet it is called with only two arguments because `self` is automatically passed as the object on which the method is called.
# --hints--
You should print the result of calling `valid_in_row(0, 8)` on `gameboard`.
```js
({ test: () => assert(runPython(`_Node(_code).has_call("print(gameboard.valid_in_row(0, 8))")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
--fcc-editable-region--
--fcc-editable-region--
```
@@ -0,0 +1,57 @@
---
id: 6606c05b5624a54ab85808fa
title: Step 28
challengeType: 20
dashedName: step-28
---
# --description--
As you can see, the output is `False` because `8` is already present in the first row of the board. Now change the `8` into a `7`.
# --hints--
You modify your `print` call to print the result of calling `valid_in_row(0, 7)` on `gameboard`.
```js
({ test: () => assert(runPython(`_Node(_code).has_call("print(gameboard.valid_in_row(0, 7))")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
--fcc-editable-region--
print(gameboard.valid_in_row(0, 8))
--fcc-editable-region--
```
@@ -0,0 +1,59 @@
---
id: 6606c0dd3293064b30d17a72
title: Step 29
challengeType: 20
dashedName: step-29
---
# --description--
Great! `7` is not present in the first row of the sudoku board and the method is telling that `7` is a valid choice for that row.
Now delete the `print` call.
# --hints--
You should not have `print(gameboard.valid_in_row(0, 7))` in your code.
```js
({ test: () => assert.isFalse(runPython(`_Node(_code).has_call("print(gameboard.valid_in_row(0, 7))")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
--fcc-editable-region--
print(gameboard.valid_in_row(0, 7))
--fcc-editable-region--
```
@@ -0,0 +1,64 @@
---
id: 6606c14182435d4bab0de2ee
title: Step 30
challengeType: 20
dashedName: step-30
---
# --description--
Next, you're going to 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.
Within the `Board` class, create a method named `valid_in_col` and give it three parameters: `self`, `col` and `num`. Where `col` and `num` are the column index and the number to be checked, respectively.
# --hints--
You should create a new method named `valid_in_col` within the `Board` class.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").has_function("valid_in_col")`)) })
```
Your `valid_in_col` method should have three parameters: `self`, `col`, and `num`, in this order.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("valid_in_col").has_args("self, col, num")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
--fcc-editable-region--
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,59 @@
---
id: 6606c2d203a8124c83b2234b
title: Step 31
challengeType: 20
dashedName: step-31
---
# --description--
You need to check if a given number is not equal to the number in the specified column of the current row.
For this, replace `pass` with a generator expression that iterates over the range from `0` to `8` (inclusive), and for each `row`, evaluates whether the number at the specified `row` and column `col` on the board is different from `num`.
# --hints--
You should delete `pass` and create a generator expression `(self.board[row][col] != num for row in range(9))`.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("valid_in_col").find_body().is_equivalent("(self.board[row][col] != num for row in range(9))")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
def valid_in_row(self, row, num):
return num not in self.board[row]
--fcc-editable-region--
def valid_in_col(self, col, num):
pass
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,59 @@
---
id: 6606c3fd5634684d48a7887b
title: Step 32
challengeType: 20
dashedName: step-32
---
# --description--
The generator expression you just wrote in the previous step 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 that generator expression to the `all()` function to check if all the elements in the column are different from `num` and return the result.
# --hints--
You should pass the generator expression as the argument to an `all()` call and return the result.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("valid_in_col").find_body().is_equivalent("return all(self.board[row][col] != num for row in range(9))")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,60 @@
---
id: 6606cb019db4f74f224856f4
title: Step 33
challengeType: 20
dashedName: step-33
---
# --description--
Call `valid_in_col` on `gameboard`. Pass it `0` and `7` as the arguments to see if the number `7` is allowed in the first column of the board and print the result.
# --hints--
You should print the result of calling `valid_in_col(0, 7)` on `gameboard`.
```js
({ test: () => assert(runPython(`_Node(_code).has_call("print(gameboard.valid_in_col(0, 7))")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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))
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
--fcc-editable-region--
--fcc-editable-region--
```
@@ -0,0 +1,60 @@
---
id: 6606cc088fd3574fa9010a4f
title: Step 34
challengeType: 20
dashedName: step-34
---
# --description--
Now change the `7` into a `1`.
# --hints--
You should modify your `print` call to print the result of calling `valid_in_col(0, 1)` on `gameboard`.
```js
({ test: () => assert(runPython(`_Node(_code).has_call("print(gameboard.valid_in_col(0, 1))")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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))
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
--fcc-editable-region--
print(gameboard.valid_in_col(0, 7))
--fcc-editable-region--
```
@@ -0,0 +1,60 @@
---
id: 6606cc473675e85017b0c53d
title: Step 35
challengeType: 20
dashedName: step-35
---
# --description--
The `1` is already present in the first column. So, everything seems to work fine. Now delete your `print` call.
# --hints--
You should not have `print(gameboard.valid_in_col(0, 1))` in your code.
```js
({ test: () => assert.isFalse(runPython(`_Node(_code).has_call("print(gameboard.valid_in_col(0, 1))")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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))
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
--fcc-editable-region--
print(gameboard.valid_in_col(0, 1))
--fcc-editable-region--
```
@@ -0,0 +1,67 @@
---
id: 6606cc754a8834509cd0afb6
title: Step 36
challengeType: 20
dashedName: step-36
---
# --description--
Another thing to check is if a number can be inserted in a 3x3 square.
Inside the `Board` class, create a method named `valid_in_square` with four parameters: `self`, `row`, `col`, and `num`. Where `row`, `col`, and `num` represent the row index, the column index, and the number to be checked, respectively.
# --hints--
You should create a new method named `valid_in_square` within the `Board` class.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").has_function("valid_in_square")`)) })
```
Your `valid_in_square` method should have four parameters: `self`, `row`, `col`, and `num`, in this order.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("valid_in_square").has_args("self, row, col, num")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,63 @@
---
id: 6606cd69f56e27516583b0cc
title: Step 37
challengeType: 20
dashedName: step-37
---
# --description--
Now you need to calculate the starting row index for the 3x3 square within the board grid and ensure that the starting row index for each 3x3 square is a multiple of 3.
This can be achieved by taking the result of the integer division `row // 3` multiplied by `3`. Replace `pass` with a variable `row_start` and assign it `(row // 3) * 3`.
# --hints--
You should delete `pass` and declare a variable `row_start` with the value of `(row // 3) * 3`.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("valid_in_square").find_body().is_equivalent("row_start = (row//3)*3")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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):
pass
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,62 @@
---
id: 6606cf1b2b9f65529c161098
title: Step 38
challengeType: 20
dashedName: step-38
---
# --description--
Similarly to the previous step, you need to ensure that the starting column index for each 3x3 square is a multiple of 3.
Declare a variable `col_start` and assign it `(col // 3) * 3`.
# --hints--
You should declare a variable `col_start` with the value of `(col // 3) * 3`.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("valid_in_square").find_variable("col_start").is_equivalent("col_start = (col//3)*3")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,67 @@
---
id: 6606d03ff198245383e61d90
title: Step 39
challengeType: 20
dashedName: step-39
---
# --description--
Now, iterate only over the rows inside the 3x3 square by creating a `for` loop. Use the `range()` function to generate a sequence starting at `row_start`, and use `row_no` as the loop variable.
# --hints--
You should create a `for` loop that iterates over `range(row_start, row_start + 3)`.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("valid_in_square").find_for_loops()[0].find_for_iter().is_equivalent("range(row_start, row_start + 3)")`)) })
```
Your `for` loop should use `row_no` as the loop variable.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("valid_in_square").find_for_loops()[0].find_for_vars().is_equivalent("row_no")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,69 @@
---
id: 6606d32096165654b8e73f21
title: Step 40
challengeType: 20
dashedName: step-40
---
# --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`. Use the `range()` function to generate this sequence and `col_no` as the loop variable.
# --hints--
You should create a `for` loop that iterates over `range(col_start, col_start + 3)` inside the existing loop body.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("valid_in_square").find_for_loops()[0].find_for_loops()[0].find_for_iter().is_equivalent("range(col_start, col_start + 3)")`)) })
```
Your `for` loop should use `col_no` as the loop variable.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("valid_in_square").find_for_loops()[0].find_for_loops()[0].find_for_vars().is_equivalent("col_no")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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):
pass
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,72 @@
---
id: 6606d378de78d55523f08298
title: Step 41
challengeType: 20
dashedName: step-41
---
# --description--
Now, check if the given number `num` is already present in the current cell of the 3x3 square.
Replace `pass` with an `if` statement that checks if the number in the current cell of the sudoku board is equal to `num`. If so, return `False` from the `if` body, indicating that the number is not a valid choice.
# --hints--
You should delete `pass` and create an `if` statement that checks if the current cell of the sudoku board is equal to `num`.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("valid_in_square").find_for_loops()[0].find_for_loops()[0].find_ifs()[0].find_conditions()[0].is_equivalent("self.board[row_no][col_no] == num")`)) })
```
You should return `False` from your new `if` statement body.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("valid_in_square").find_for_loops()[0].find_for_loops()[0].find_ifs()[0].find_bodies()[0].is_equivalent("return False")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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):
pass
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,68 @@
---
id: 6606d589750ad655fa0df168
title: Step 42
challengeType: 20
dashedName: step-42
---
# --description--
If the number is not present, it can be inserted into the square without violating the rules of sudoku.
After the outer `for` loop, return `True`.
# --hints--
You should return `True` after the outer `for` loop.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("valid_in_square").has_return("True")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,69 @@
---
id: 6606d6138c49e456920fa818
title: Step 43
challengeType: 20
dashedName: step-43
---
# --description--
Test the method to ensure it works properly by calling `valid_in_square` on `gameboard`. Pass it `1`, `0`, and `3` as the arguments and print the result.
# --hints--
You should print the result of calling `valid_in_square(1, 0, 3)` on `gameboard`.
```js
({ test: () => assert(runPython(`_Node(_code).has_call("print(gameboard.valid_in_square(1, 0, 3))")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
--fcc-editable-region--
--fcc-editable-region--
```
@@ -0,0 +1,69 @@
---
id: 6606d7bb9e4c6b574235159a
title: Step 44
challengeType: 20
dashedName: step-44
---
# --description--
The method returns `False` because `3` is already present in that square. Try another square by changing the column index to `6`.
# --hints--
You should print the result of calling `valid_in_square(1, 6, 3)` on `gameboard`.
```js
({ test: () => assert(runPython(`_Node(_code).has_call("print(gameboard.valid_in_square(1, 6, 3))")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
--fcc-editable-region--
print(gameboard.valid_in_square(1, 0, 3))
--fcc-editable-region--
```
@@ -0,0 +1,69 @@
---
id: 6606d8795bd533582425a363
title: Step 45
challengeType: 20
dashedName: step-45
---
# --description--
Everything works fine. Now delete your `print` call.
# --hints--
You should not have `print(gameboard.valid_in_square(1, 6, 3))` in your code.
```js
({ test: () => assert.isFalse(runPython(`_Node(_code).has_call("print(gameboard.valid_in_square(1, 6, 3))")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
--fcc-editable-region--
print(gameboard.valid_in_square(1, 6, 3))
--fcc-editable-region--
```
@@ -0,0 +1,76 @@
---
id: 6606d8c323d6205890fbbd54
title: Step 46
challengeType: 20
dashedName: step-46
---
# --description--
Within the `Board` class, create another method `is_valid` and give it three parameters: `self`, `empty`, and `num`. Where `empty` is a tuple representing the row and column indices of an empty cell and `num` is the number to be checked.
This method will check 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--
You should create a new method named `is_valid` within the `Board` class.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").has_function("is_valid")`)) })
```
Your `is_valid` method should have three parameters: `self`, `empty`, and `num`, in this order.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("is_valid").has_args("self, empty, num")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,78 @@
---
id: 6606d9d92fcf78598b3b5184
title: Step 47
challengeType: 20
dashedName: step-47
---
# --description--
A tuple can be unpacked, meaning that the elements contained in the tuple can be assigned to variables, like this:
```py
spam = ('lemon', 'curry')
item1, item2 = spam
```
In the example above, `item1` would have the value `'lemon'` and `item2` would have the value `'curry'`.
Inside the method, delete `pass` and unpack the `empty` tuple into `row` and `col`.
# --hints--
You should delete `pass` and unpack the `empty` tuple into `row` and `col`.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("is_valid").find_body().is_equivalent("row, col = empty")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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):
pass
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,69 @@
---
id: 6606db6a23a1455a402f91ae
title: Step 48
challengeType: 20
dashedName: step-48
---
# --description--
Within the `is_valid` method, check if the number is valid for insertion in the specified row by calling the `valid_in_row()` method with `row` and `num` as arguments, and assign the result to a variable `valid_in_row`. Remember to use `self` to reference the methods of the current instance.
# --hints--
You should declare a variable `valid_in_row` and assign it `self.valid_in_row(row, num)`.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("is_valid").find_variable("valid_in_row").is_equivalent("valid_in_row = self.valid_in_row(row, num)")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,70 @@
---
id: 6606dcf5a31e4e5b43737417
title: Step 49
challengeType: 20
dashedName: step-49
---
# --description--
Check if the number is valid for insertion in the specified column by calling the `valid_in_col()` method with `col` and `num` as the arguments and assign the result to a variable `valid_in_col`.
# --hints--
You should declare a variable `valid_in_col` and assign it `self.valid_in_col(col, num)`.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("is_valid").find_variable("valid_in_col").is_equivalent("valid_in_col = self.valid_in_col(col, num)")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,71 @@
---
id: 6606dd63109f9f5c2195e30c
title: Step 50
challengeType: 20
dashedName: step-50
---
# --description--
Check if the number is valid for insertion in the specified 3x3 square by calling the `valid_in_square()` method with `row`, `col` and `num` as the arguments and assign the result to a variable `valid_in_square`.
# --hints--
You should declare a variable `valid_in_square` and assign it `self.valid_in_square(row, col, num)`.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("is_valid").find_variable("valid_in_square").is_equivalent("valid_in_square = self.valid_in_square(row, col, num)")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,78 @@
---
id: 6606de006a82e05c9a65cebe
title: Step 51
challengeType: 20
dashedName: step-51
---
# --description--
To verify that the number is valid after all those checks, call the `all()` function and pass it a list containing `valid_in_row`, `valid_in_col`, and `valid_in_square`. Also, return the result of the `all()` call.
# --hints--
You should return a call to the `all()` function passing it a list containing `valid_in_row`, `valid_in_col`, and `valid_in_square`.
```js
({ test: () => assert(runPython(`
import itertools
p = list(itertools.permutations(["valid_in_row", "valid_in_col", "valid_in_square"]))
l = [", ".join(i) for i in p]
node = _Node(_code).find_class("Board").find_function("is_valid")
any([node.has_return(f"all([{i}])") for i in l])
`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,83 @@
---
id: 6606e2f27f19ca5f398c6aed
title: Step 52
challengeType: 20
dashedName: step-52
---
# --description--
Next, you'll work on a method that attempts to solve the sudoku in-place, meaning it will modify the existing sudoku board rather than creating a new one.
Within the `Board` class, create a method named`solver` and give it a single parameter, `self`.
# --hints--
You should create a new method named `solver` within the `Board` class.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").has_function("solver")`)) })
```
Your `solver` method should have a single parameter `self`.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("solver").has_args("self")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,82 @@
---
id: 6606e3e6231702600bd5860c
title: Step 53
challengeType: 20
dashedName: step-53
---
# --description--
Delete `pass` and create an `if` statement that checks if the value returned by `find_empty_cell` is `None`. In that case, the puzzle is solved. Therefore, return `True` from the `if` body.
# --hints--
You should delete `pass` and create an `if` statement that checks if the value returned by `self.find_empty_cell` is `None`.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("solver").find_ifs()[0].find_conditions()[0].is_equivalent("self.find_empty_cell() is None")`)) })
```
You should return `True` from your new `if` statement body.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("solver").find_ifs()[0].find_bodies()[0].is_equivalent("return True")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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):
pass
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,83 @@
---
id: 660a737f0f72b51de361051c
title: Step 54
challengeType: 20
dashedName: step-54
---
# --description--
The `:=` operator gives you the ability to assign variables in the middle of an expression. The syntax is: `name := val`, where `name` is the variable name and `val` is the variable value.
This construct is formally named *assignment expressions*, while the `:=` operator is commonly referred to as the *walrus* operator.
Since you are going to need the `self.find_empty_cell()` call more than once, assign it to a variable `next_empty` by using the walrus operator. Then, enclose the assignment between a pair of parentheses.
In this way, you'll combine the assignment and the conditional check into a single line, making the code more concise.
# --hints--
You should modify the `if` condition into `(next_empty := self.find_empty_cell()) is None`.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("solver").find_ifs()[0].find_conditions()[0].is_equivalent("(next_empty := self.find_empty_cell()) is None")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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 self.find_empty_cell() is None:
return True
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,85 @@
---
id: 660a7a1cac69b7217cbae22d
title: Step 55
challengeType: 20
dashedName: step-55
---
# --description--
After the `if` statement, create a `for` loop to iterate over the range from `1` to `9` inclusive. Use `guess` as the loop variable.
This loop will enable you to systematically check if any cipher from `1` to `9` is suitable to fill an empty cell.
# --hints--
You should create a `for` loop that iterates over `range(1, 10)`.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("solver").find_for_loops()[0].find_for_iter().is_equivalent("range(1, 10)")`)) })
```
Your `for` loop should have `guess` as the loop variable.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("solver").find_for_loops()[0].find_for_vars().is_equivalent("guess")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,81 @@
---
id: 660a7cb75dce3d22ab562c0d
title: Step 56
challengeType: 20
dashedName: step-56
---
# --description--
Inside the loop body, replace `pass` with an `if` statement that checks if the number is a valid choice for the current cell.
Build the `if` condition with an `is_valid` call, passing `next_empty` and `guess` as the arguments.
# --hints--
You should delete `pass` and create an `if` statement that checks if `self.is_valid(next_empty, guess)` is `True`.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("solver").find_for_loops()[0].find_bodies()[0].is_equivalent("if self.is_valid(next_empty, guess):\\n pass")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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
for guess in range(1, 10):
pass
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,80 @@
---
id: 660a7ea6e3a21a243d6aa288
title: Step 57
challengeType: 20
dashedName: step-57
---
# --description--
Inside the `if` body, delete `pass` and unpack the tuple `next_empty` into `row, col`.
# --hints--
You should delete `pass` and unpack the tuple `next_empty` into `row, col`.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("solver").find_for_loops()[0].find_ifs()[0].find_bodies()[0].is_equivalent("row, col = next_empty")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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
for guess in range(1, 10):
if self.is_valid(next_empty, guess):
pass
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,80 @@
---
id: 660a7f28d5ce6a24ef856a50
title: Step 58
challengeType: 20
dashedName: step-58
---
# --description--
Now, modify the board in place by accessing the cell at the given row and column and assigning it the value of `guess`.
# --hints--
You should assign `guess` to `self.board[row][col]`.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("solver").find_for_loops()[0].find_ifs()[0].find_bodies()[0].is_equivalent("row, col = next_empty\\nself.board[row][col] = guess")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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
for guess in range(1, 10):
if self.is_valid(next_empty, guess):
row, col = next_empty
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,87 @@
---
id: 660a8b6cd8de406ae82ce910
title: Step 59
challengeType: 20
dashedName: step-59
---
# --description--
Nest an `if` statement inside the current `if`. For the `if` condition, use a recursive call to `solver()` and return `True` from the new `if` body.
# --hints--
You should nest an `if` statement inside the current `if` statement and use `self.solver()` as the condition.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("solver").find_for_loops()[0].find_ifs()[0].find_ifs()[0].find_conditions()[0].is_equivalent("self.solver()")`)) })
```
You should return `True` from your new `if` statement.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("solver").find_for_loops()[0].find_ifs()[0].find_ifs()[0].find_bodies()[0].is_equivalent("return True")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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
for guess in range(1, 10):
if self.is_valid(next_empty, guess):
row, col = next_empty
self.board[row][col] = guess
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,85 @@
---
id: 660a8c3b21100c6b83e57cb0
title: Step 60
challengeType: 20
dashedName: step-60
---
# --description--
If the recursive call returns `False`, it means the guess led to an unsolvable sudoku. So you'll need to restore the cell to be empty and explore another guess.
After the innermost `if` statement, set the current cell value back to `0`.
# --hints--
You should set the current cell value back to `0` after the innermost `if` statement.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("solver").find_for_loops()[0].find_ifs()[0].find_bodies()[0].is_equivalent("row, col = next_empty\\nself.board[row][col] = guess\\nif self.solver():\\n return True\\nself.board[row][col] = 0")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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
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
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,84 @@
---
id: 660a8d7c5f33c16c67e58b37
title: Step 61
challengeType: 20
dashedName: step-61
---
# --description--
Finally, make the `solver` method return `False` if none of the guesses leads to a solution. Pay attention to the indentation.
# --hints--
You should return `False` after the `for` loop.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("solver").has_return("False")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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
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--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,96 @@
---
id: 660a8ef6b7571f6dddc3553b
title: Step 62
challengeType: 20
dashedName: step-62
---
# --description--
Outside the class definition, create a function `solve_sudoku` to print and solve the sudoku board.
Give it a single parameter `board` that will be your 2D list.
# --hints--
You should define a new function named `solve_sudoku` outside the `Board` class.
```js
({ test: () => assert(runPython(`_Node(_code).has_function("solve_sudoku")`)) })
```
Your `solve_sudoku` function should have a single parameter `board`.
```js
({ test: () => assert(runPython(`_Node(_code).find_function("solve_sudoku").has_args("board")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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
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--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,88 @@
---
id: 660a92e93854486efa68fe6f
title: Step 63
challengeType: 20
dashedName: step-63
---
# --description--
Inside the `solve_sudoku` function, delete `pass` and create a `gameboard` variable and assign it an instance of the `Board` class, passing `board` as the argument.
# --hints--
You should replace `pass` with a variable `gameboard` and assign it `Board(board)`.
```js
({ test: () => assert(runPython(`_Node(_code).find_function("solve_sudoku").find_body().is_equivalent("gameboard = Board(board)")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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
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):
pass
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,88 @@
---
id: 660a937220bf966fd844f1ee
title: Step 64
challengeType: 20
dashedName: step-64
---
# --description--
Now, add a `print()` call to print the following f-string: `f'Puzzle to solve:\n{gameboard}'`.
# --hints--
You should print the provided string inside the `solve_sudoku` function.
```js
({ test: () => assert(runPython(`_Node(_code).find_function("solve_sudoku").has_call("print(f'Puzzle to solve:\\\\n{gameboard}')")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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
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--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,101 @@
---
id: 660a940b3379fb708a83593a
title: Step 65
challengeType: 20
dashedName: step-65
---
# --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` body passing the following f-string: `f'Solved puzzle:\n{gameboard}'`.
# --hints--
You should create an `if` statement that checks if the `solver()` method call from the `gameboard` object returns `True`.
```js
({ test: () => assert(runPython(`
conditions = ["gameboard.solver()", "gameboard.solver() == True", "True == gameboard.solver()"]
node = _Node(_code).find_function("solve_sudoku").find_ifs()[0].find_conditions()[0]
any(node.is_equivalent(condition) for condition in conditions)`)) })
```
You should print `f'Solved puzzle:\n{gameboard}'` inside the new `if` body.
```js
({ test: () => assert(runPython(`_Node(_code).find_function("solve_sudoku").find_ifs()[0].find_bodies()[0].has_call("print(f'Solved puzzle:\\\\n{gameboard}')")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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
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'Puzzle to solve:\n{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]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,91 @@
---
id: 660a94f55c3c9b71a37e1c8b
title: Step 66
challengeType: 20
dashedName: step-66
---
# --description--
Create an `else` clause for when the sudoku puzzle is not solvable and print the following string inside the new `else` block: `'The provided puzzle is unsolvable.'`.
# --hints--
You should create an `else` clause and print `'The provided puzzle is unsolvable.'`.
```js
({ test: () => assert(runPython(`_Node(_code).find_function("solve_sudoku").find_ifs()[0].find_bodies()[1].has_call("print('The provided puzzle is unsolvable.')")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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
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'Puzzle to solve:\n{gameboard}')
if gameboard.solver():
print(f'Solved puzzle:\n{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]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,93 @@
---
id: 660a957f44c096728ba9c41f
title: Step 67
challengeType: 20
dashedName: step-67
---
# --description--
After the conditional statements, return your instance of the `Board` class, which represents the final state of the sudoku board after attempting to solve it.
# --hints--
You should return `gameboard` after the `else` clause.
```js
({ test: () => assert(runPython(`_Node(_code).find_function("solve_sudoku").has_return("gameboard")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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
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'Puzzle to solve:\n{gameboard}')
if gameboard.solver():
print(f'Solved puzzle:\n{gameboard}')
else:
print('The provided puzzle is unsolvable.')
--fcc-editable-region--
puzzle = [
[0, 0, 2, 0, 0, 8, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 7, 6, 2],
[4, 3, 0, 0, 0, 0, 8, 0, 0],
[0, 5, 0, 0, 3, 0, 0, 9, 0],
[0, 4, 0, 0, 0, 0, 0, 2, 6],
[0, 0, 0, 4, 6, 7, 0, 0, 0],
[0, 8, 6, 7, 0, 4, 0, 0, 0],
[0, 0, 0, 5, 1, 9, 0, 0, 8],
[1, 7, 0, 0, 0, 6, 0, 0, 5]
]
gameboard = Board(puzzle)
```
@@ -0,0 +1,96 @@
---
id: 660a95c3da857673124ed698
title: Step 68
challengeType: 20
dashedName: step-68
---
# --description--
There's still something to fix. Try to print your `gameboard` object.
# --hints--
You should print `gameboard`.
```js
({ test: () => assert(runPython(`_Node(_code).has_call("print(gameboard)")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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
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'Puzzle to solve:\n{gameboard}')
if gameboard.solver():
print(f'Solved puzzle:\n{gameboard}')
else:
print('The 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]
]
--fcc-editable-region--
gameboard = Board(puzzle)
--fcc-editable-region--
```
@@ -0,0 +1,104 @@
---
id: 660a968ca0838773c9bbfc85
title: Step 69
challengeType: 20
dashedName: step-69
---
# --description--
When you print your `gameboard` object, you get something like `<__main__.Board object at 0xf3c1c8>`, which is the default representation of an object. This means that the `solve_sudoku` function will also give you an output different from what you expect.
Delete both the `print()` call and the `gameboard` object.
# --hints--
You should not have `print(gameboard)` in your code.
```js
({ test: () => assert.isFalse(runPython(`_Node(_code).has_call("print(gameboard)")`)) })
```
You should not have `gameboard = Board(puzzle)` in your code.
```js
({ test: () => assert.isFalse(runPython(`_Node(_code).has_variable("gameboard")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def find_empty_cell(self):
for row, contents in enumerate(self.board):
try:
col = contents.index(0)
return row, col
except ValueError:
pass
return None
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
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'Puzzle to solve:\n{gameboard}')
if gameboard.solver():
print(f'Solved puzzle:\n{gameboard}')
else:
print('The 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]
]
--fcc-editable-region--
gameboard = Board(puzzle)
print(gameboard)
--fcc-editable-region--
```
@@ -0,0 +1,102 @@
---
id: 660a9819ad113774d65a1e7c
title: Step 70
challengeType: 20
dashedName: step-70
---
# --description--
The `__str__` method is a special method that is called under the hood when the object is printed using the `print()` function, or converted into a string using the `str()` function.
Define an empty `__str__` method within the `Board` class and give it a `self` parameter.
# --hints--
You should create a new method named `__str__` within the `Board` class.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").has_function("__str__")`)) })
```
Your `__str__` method should have a single parameter `self`.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("__str__").has_args("self")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
--fcc-editable-region--
--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
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
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'Puzzle to solve:\n{gameboard}')
if gameboard.solver():
print(f'Solved puzzle:\n{gameboard}')
else:
print('The 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]
]
```
@@ -0,0 +1,95 @@
---
id: 660ac1d158923e805d3c3099
title: Step 71
challengeType: 20
dashedName: step-71
---
# --description--
Replace `pass` with a variable `board_str` and assign it an empty string. You'll use this variable to build the custom string representation to return.
# --hints--
You should replace `pass` with a variable `board_str` and assign it an empty string.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("__str__").find_body().is_equivalent("board_str = ''")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
--fcc-editable-region--
def __str__(self):
pass
--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
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
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'Puzzle to solve:\n{gameboard}')
if gameboard.solver():
print(f'Solved puzzle:\n{gameboard}')
else:
print('The 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]
]
```
@@ -0,0 +1,101 @@
---
id: 660ac2873b090d80d6aa6ce2
title: Step 72
challengeType: 20
dashedName: step-72
---
# --description--
Now, create a `for` loop to iterate over the rows in the board. Use `row` as the loop variable.
# --hints--
You should create a `for` loop that iterates over `self.board`.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("__str__").find_for_loops()[0].find_for_iter().is_equivalent("self.board")`)) })
```
You should use `row` as the loop variable.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("__str__").find_for_loops()[0].find_for_vars().is_equivalent("row")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
--fcc-editable-region--
def __str__(self):
board_str = ''
--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
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
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'Puzzle to solve:\n{gameboard}')
if gameboard.solver():
print(f'Solved puzzle:\n{gameboard}')
else:
print('The 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]
]
```
@@ -0,0 +1,115 @@
---
id: 660ac35d55a15d81afdedd76
title: Step 73
challengeType: 20
dashedName: step-73
---
# --description--
Inside the `for` loop, declare a variable `row_str` and assign it a list comprehension that iterates over `row` and turns each item `i` in `row` into a string. Use the `str()` function for that.
# --hints--
You should declare a variable `row_str`.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("__str__").find_for_loops()[0].find_bodies()[0].has_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")`)) })
```
The list comprehension assigned to the `row_str` variable should use `i` as iteration 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_targets()[0].is_equivalent("i")`)) })
```
The list comprehension assigned to the `row_str` variable should call `str()` on each item `i` in `row`.
```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_expr().is_equivalent("str(i)")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
--fcc-editable-region--
def __str__(self):
board_str = ''
for row in self.board:
pass
--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
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
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'Puzzle to solve:\n{gameboard}')
if gameboard.solver():
print(f'Solved puzzle:\n{gameboard}')
else:
print('The 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]
]
```
@@ -0,0 +1,97 @@
---
id: 660ac44c7eec868220318297
title: Step 74
challengeType: 20
dashedName: step-74
---
# --description--
Modify the `row_str` comprehension to give a string only when the item is not zero, and an asterisk character otherwise.
# --hints--
The list comprehension assigned to the `row_str` variable should call `str()` on each item `i` in `row` if `i` is truthy, and it should evaluate to `'*'` otherwise.
```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_expr().is_equivalent("str(i) if i else '*'")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
--fcc-editable-region--
def __str__(self):
board_str = ''
for row in self.board:
row_str = [str(i) for i in row]
--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
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
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'Puzzle to solve:\n{gameboard}')
if gameboard.solver():
print(f'Solved puzzle:\n{gameboard}')
else:
print('The 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]
]
```
@@ -0,0 +1,97 @@
---
id: 660ac4f4f784b9829e89632a
title: Step 75
challengeType: 20
dashedName: step-75
---
# --description--
Next, join the items in `row_str` with a space and add the result to the current value of `board_str`.
# --hints--
You should use `.join()` to join the items in `row_str` with a space and add the result to the current value of `board_str`.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("__str__").find_for_loops()[0].find_bodies()[0].find_aug_variable("board_str").is_equivalent("board_str += ' '.join(row_str)")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
--fcc-editable-region--
def __str__(self):
board_str = ''
for row in self.board:
row_str = [str(i) if i else '*' for i in row]
--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
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
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'Puzzle to solve:\n{gameboard}')
if gameboard.solver():
print(f'Solved puzzle:\n{gameboard}')
else:
print('The 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]
]
```
@@ -0,0 +1,98 @@
---
id: 660ac56326c2eb831583c0de
title: Step 76
challengeType: 20
dashedName: step-76
---
# --description--
Add a new line character to the current value of `board_str`.
# --hints--
You should add a `'\n'` character to the current value of `board_str`.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("__str__").find_for_loops()[0].find_bodies()[0].has_stmt("board_str += '\\\\n'")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
--fcc-editable-region--
def __str__(self):
board_str = ''
for row in self.board:
row_str = [str(i) if i else '*' for i in row]
board_str += ' '.join(row_str)
--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
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
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'Puzzle to solve:\n{gameboard}')
if gameboard.solver():
print(f'Solved puzzle:\n{gameboard}')
else:
print('The 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]
]
```
@@ -0,0 +1,99 @@
---
id: 660ac59d7ea60083900b83df
title: Step 77
challengeType: 20
dashedName: step-77
---
# --description--
Finally, return `board_str` after the `for` loop.
# --hints--
You should return `board_str` after the `for` loop.
```js
({ test: () => assert(runPython(`_Node(_code).find_class("Board").find_function("__str__").has_return("board_str")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
--fcc-editable-region--
def __str__(self):
board_str = ''
for row in self.board:
row_str = [str(i) if i else '*' for i in row]
board_str += ' '.join(row_str)
board_str += '\n'
--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
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
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'Puzzle to solve:\n{gameboard}')
if gameboard.solver():
print(f'Solved puzzle:\n{gameboard}')
else:
print('The 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]
]
```
@@ -0,0 +1,187 @@
---
id: 660ac60e22aa218400acb4b6
title: Step 78
challengeType: 20
dashedName: step-78
---
# --description--
And now call the `solve_sudoku` method passing `puzzle` as the argument. You should see the partially empty puzzle to solve, and the solved puzzle as the output.
With this, you completed the sudoku solver project!
# --hints--
You should call `solve_sudoku()` and pass it `puzzle` as the argument.
```js
({ test: () => assert(runPython(`_Node(_code).has_call("solve_sudoku(puzzle)")`)) })
```
# --seed--
## --seed-contents--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
board_str = ''
for row in self.board:
row_str = [str(i) if i else '*' for i in row]
board_str += ' '.join(row_str)
board_str += '\n'
return board_str
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
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'Puzzle to solve:\n{gameboard}')
if gameboard.solver():
print(f'Solved puzzle:\n{gameboard}')
else:
print('The 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]
]
--fcc-editable-region--
--fcc-editable-region--
```
# --solutions--
```py
class Board:
def __init__(self, board):
self.board = board
def __str__(self):
board_str = ''
for row in self.board:
row_str = [str(i) if i else '*' for i in row]
board_str += ' '.join(row_str)
board_str += '\n'
return board_str
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
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'Puzzle to solve:\n{gameboard}')
if gameboard.solver():
print(f'Solved puzzle:\n{gameboard}')
else:
print('The 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)
```
@@ -14,10 +14,36 @@ dashedName: step-13
You should declare a function named `generate_password`.
```js
({ test: () => assert(__pyodide.runPython(`
import inspect
generate_psw = __locals.get("generate_password")
inspect.isfunction(generate_psw)
({
test: () => assert(runPython(`
_Node(_code).has_function('generate_password')
`))
})
```
The import statements should still be outside the function.
```js
({
test: () => assert(runPython(`
imports_list = _Node(_code).find_imports()
any([imp.is_equivalent('import secrets') for imp in imports_list]) and any([imp.is_equivalent('import string') for imp in imports_list])
`))
})
```
The four variable declarations should be moved inside the function.
```js
({
test: () => assert(runPython(`
func = _Node(_code).find_function('generate_password')
vars = ['letters', 'digits', 'symbols', 'all_characters']
func.find_variable('letters').is_equivalent('letters = string.ascii_letters') and \\
func.find_variable('digits').is_equivalent('digits = string.digits') and \\
func.find_variable('symbols').is_equivalent('symbols = string.punctuation') and \\
func.find_variable('all_characters').is_equivalent('all_characters = letters + digits + symbols') and \\
all(not _Node(_code).has_variable(var) for var in vars)
`))
})
```
@@ -9,7 +9,7 @@ dashedName: step-7
داخل `header`، قدّم سياق حول الصفحة بواسطة أدخال عنصر `img`, و `h1`, و `nav` واحد.
ينبغي أن يشير `img` إلى `https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg`، ويحتوي على `id` بقيمة `logo`.
The `img` should point to `https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg`, have an `id` of `logo`, and have an `alt` text of `freeCodeCamp`.
يجب أن يحتوي `h1` على النص `HTML/CSS Quiz`.
@@ -51,6 +51,12 @@ assert.equal(document.querySelector('img')?.src, 'https://cdn.freecodecamp.org/p
assert.equal(document.querySelector('img')?.id, 'logo');
```
You should give the `img` element an `alt` attribute of `freeCodeCamp`.
```js
assert.equal(document.querySelector('img')?.alt, 'freeCodeCamp');
```
يجب عليك إعطاء عنصر `h1` النص `HTML/CSS Quiz`.
```js
@@ -51,7 +51,7 @@ assert.equal(new __helpers.CSSHelp(document).getStyle('#logo')?.width, 'max(100p
</head>
<body>
<header>
<img id="logo" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<img id="logo" alt="freeCodeCamp" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<h1>HTML/CSS Quiz</h1>
<nav></nav>
</header>
@@ -65,7 +65,7 @@ assert.equal(new __helpers.CSSHelp(document).getStyle('#logo')?.padding, '0.4rem
</head>
<body>
<header>
<img id="logo" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<img id="logo" alt="freeCodeCamp" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<h1>HTML/CSS Quiz</h1>
<nav></nav>
</header>
@@ -57,7 +57,7 @@ assert.equal(new __helpers.CSSHelp(document).getStyle('header')?.display, 'flex'
</head>
<body>
<header>
<img id="logo" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<img id="logo" alt="freeCodeCamp" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<h1>HTML/CSS Quiz</h1>
<nav></nav>
</header>
@@ -45,7 +45,7 @@ assert.equal(new __helpers.CSSHelp(document).getStyle('h1')?.fontSize, 'min(5vw,
</head>
<body>
<header>
<img id="logo" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<img id="logo" alt="freeCodeCamp" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<h1>HTML/CSS Quiz</h1>
<nav></nav>
</header>
@@ -69,7 +69,7 @@ assert.equal(document.querySelectorAll('nav > ul > li > a')?.[2]?.textContent, '
</head>
<body>
<header>
<img id="logo" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<img id="logo" alt="freeCodeCamp" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<h1>HTML/CSS Quiz</h1>
--fcc-editable-region--
<nav>
@@ -51,7 +51,7 @@ assert.equal(new __helpers.CSSHelp(document).getStyle('nav > ul')?.justifyConten
</head>
<body>
<header>
<img id="logo" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<img id="logo" alt="freeCodeCamp" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<h1>HTML/CSS Quiz</h1>
<nav>
<ul>
@@ -65,7 +65,7 @@ assert.equal(document.querySelector('main > form')?.method?.toLowerCase(), 'post
</head>
<body>
<header>
<img id="logo" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<img id="logo" alt="freeCodeCamp" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<h1>HTML/CSS Quiz</h1>
<nav>
<ul>
@@ -47,7 +47,7 @@ assert.equal(document.querySelectorAll('section')?.[2]?.getAttribute('role'), 'r
</head>
<body>
<header>
<img id="logo" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<img id="logo" alt="freeCodeCamp" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<h1>HTML/CSS Quiz</h1>
<nav>
<ul>
@@ -107,7 +107,7 @@ assert.isAtLeast(document.querySelectorAll('h2')?.[2]?.textContent?.length, 1);
</head>
<body>
<header>
<img id="logo" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<img id="logo" alt="freeCodeCamp" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<h1>HTML/CSS Quiz</h1>
<nav>
<ul>
@@ -67,7 +67,7 @@ assert.equal(new __helpers.CSSHelp(document).getStyle('h2')?.borderBottom, '4px
</head>
<body>
<header>
<img id="logo" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<img id="logo" alt="freeCodeCamp" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<h1>HTML/CSS Quiz</h1>
<nav>
<ul>
@@ -45,7 +45,7 @@ assert.equal(document.querySelectorAll('a')?.[2]?.getAttribute('href'), '#css-qu
</head>
<body>
<header>
<img id="logo" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<img id="logo" alt="freeCodeCamp" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<h1>HTML/CSS Quiz</h1>
<nav>
--fcc-editable-region--
@@ -92,7 +92,7 @@ assert.exists(document.querySelectorAll('h2#student-info ~ div')?.[2]?.querySele
</head>
<body>
<header>
<img id="logo" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<img id="logo" alt="freeCodeCamp" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<h1>HTML/CSS Quiz</h1>
<nav>
<ul>
@@ -103,7 +103,7 @@ assert.notEqual(htmlFor(1), htmlFor(2));
</head>
<body>
<header>
<img id="logo" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<img id="logo" alt="freeCodeCamp" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<h1>HTML/CSS Quiz</h1>
<nav>
<ul>
@@ -69,7 +69,7 @@ assert.notEmpty(document.querySelectorAll('input')?.[0]?.placeholder);
</head>
<body>
<header>
<img id="logo" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<img id="logo" alt="freeCodeCamp" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<h1>HTML/CSS Quiz</h1>
<nav>
<ul>
@@ -35,7 +35,7 @@ assert.isEmpty(document.querySelectorAll('input')?.[0]?.placeholder);
</head>
<body>
<header>
<img id="logo" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<img id="logo" alt="freeCodeCamp" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<h1>HTML/CSS Quiz</h1>
<nav>
<ul>
@@ -47,7 +47,7 @@ assert.match(document.querySelector('.info:nth-of-type(3) > label')?.innerHTML,
</head>
<body>
<header>
<img id="logo" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<img id="logo" alt="freeCodeCamp" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<h1>HTML/CSS Quiz</h1>
<nav>
<ul>
@@ -33,7 +33,7 @@ assert.equal(document.querySelector('.info:nth-of-type(3) > label > span')?.text
</head>
<body>
<header>
<img id="logo" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<img id="logo" alt="freeCodeCamp" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<h1>HTML/CSS Quiz</h1>
<nav>
<ul>
@@ -103,7 +103,7 @@ assert.equal(new __helpers.CSSHelp(document).getStyle('.sr-only')?.borderWidth,
</head>
<body>
<header>
<img id="logo" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<img id="logo" alt="freeCodeCamp" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<h1>HTML/CSS Quiz</h1>
<nav>
<ul>
@@ -95,7 +95,7 @@ assert.equal(document.querySelectorAll('section:nth-of-type(2) > div.question-bl
</head>
<body>
<header>
<img id="logo" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<img id="logo" alt="freeCodeCamp" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<h1>HTML/CSS Quiz</h1>
<nav>
<ul>
@@ -65,7 +65,7 @@ assert.equal(document.querySelectorAll('fieldset > ul')?.[1]?.querySelectorAll('
</head>
<body>
<header>
<img id="logo" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<img id="logo" alt="freeCodeCamp" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg">
<h1>HTML/CSS Quiz</h1>
<nav>
<ul>

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