mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-09-24 23:01:18 +08:00
chore(i18n,learn): processed translations (#54699)
This commit is contained in:
+39
@@ -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--
|
||||
```
|
||||
+37
@@ -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--
|
||||
```
|
||||
+39
@@ -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--
|
||||
```
|
||||
+34
@@ -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--
|
||||
```
|
||||
+32
@@ -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--
|
||||
```
|
||||
+40
@@ -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--
|
||||
```
|
||||
+33
@@ -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--
|
||||
```
|
||||
+46
@@ -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--
|
||||
```
|
||||
+51
@@ -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()
|
||||
```
|
||||
+53
@@ -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--
|
||||
```
|
||||
+48
@@ -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--
|
||||
```
|
||||
+46
@@ -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--
|
||||
```
|
||||
+45
@@ -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--
|
||||
```
|
||||
+52
@@ -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)
|
||||
```
|
||||
+56
@@ -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)
|
||||
```
|
||||
+48
@@ -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)
|
||||
```
|
||||
+55
@@ -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)
|
||||
```
|
||||
+51
@@ -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)
|
||||
```
|
||||
+54
@@ -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)
|
||||
```
|
||||
+50
@@ -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)
|
||||
```
|
||||
+56
@@ -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--
|
||||
```
|
||||
+54
@@ -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())
|
||||
```
|
||||
+59
@@ -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--
|
||||
```
|
||||
+62
@@ -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)
|
||||
```
|
||||
+54
@@ -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)
|
||||
```
|
||||
+58
@@ -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)
|
||||
```
|
||||
+59
@@ -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--
|
||||
```
|
||||
+57
@@ -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--
|
||||
```
|
||||
+59
@@ -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--
|
||||
```
|
||||
+64
@@ -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)
|
||||
```
|
||||
+59
@@ -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)
|
||||
```
|
||||
+59
@@ -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)
|
||||
```
|
||||
+60
@@ -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--
|
||||
```
|
||||
+60
@@ -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--
|
||||
```
|
||||
+60
@@ -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--
|
||||
```
|
||||
+67
@@ -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)
|
||||
```
|
||||
+63
@@ -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)
|
||||
```
|
||||
+62
@@ -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)
|
||||
```
|
||||
+67
@@ -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)
|
||||
```
|
||||
+69
@@ -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)
|
||||
```
|
||||
+72
@@ -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)
|
||||
```
|
||||
+68
@@ -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)
|
||||
```
|
||||
+69
@@ -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--
|
||||
```
|
||||
+69
@@ -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--
|
||||
```
|
||||
+69
@@ -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--
|
||||
```
|
||||
+76
@@ -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)
|
||||
```
|
||||
+78
@@ -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)
|
||||
```
|
||||
+69
@@ -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)
|
||||
```
|
||||
+70
@@ -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)
|
||||
```
|
||||
+71
@@ -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)
|
||||
```
|
||||
+78
@@ -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)
|
||||
```
|
||||
+83
@@ -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)
|
||||
```
|
||||
+82
@@ -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)
|
||||
```
|
||||
+83
@@ -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)
|
||||
```
|
||||
+85
@@ -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)
|
||||
```
|
||||
+81
@@ -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)
|
||||
```
|
||||
+80
@@ -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)
|
||||
```
|
||||
+80
@@ -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)
|
||||
```
|
||||
+87
@@ -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)
|
||||
```
|
||||
+85
@@ -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)
|
||||
```
|
||||
+84
@@ -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)
|
||||
```
|
||||
+96
@@ -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)
|
||||
```
|
||||
+88
@@ -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)
|
||||
```
|
||||
+88
@@ -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)
|
||||
```
|
||||
+101
@@ -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)
|
||||
```
|
||||
+91
@@ -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)
|
||||
```
|
||||
+93
@@ -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)
|
||||
```
|
||||
+96
@@ -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--
|
||||
```
|
||||
+104
@@ -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--
|
||||
```
|
||||
+102
@@ -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]
|
||||
]
|
||||
```
|
||||
+95
@@ -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]
|
||||
]
|
||||
```
|
||||
+101
@@ -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]
|
||||
]
|
||||
```
|
||||
+115
@@ -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]
|
||||
]
|
||||
```
|
||||
+97
@@ -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]
|
||||
]
|
||||
```
|
||||
+97
@@ -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]
|
||||
]
|
||||
```
|
||||
+98
@@ -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]
|
||||
]
|
||||
```
|
||||
+99
@@ -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]
|
||||
]
|
||||
```
|
||||
+187
@@ -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)
|
||||
```
|
||||
+30
-4
@@ -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)
|
||||
`))
|
||||
})
|
||||
```
|
||||
|
||||
+7
-1
@@ -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
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+1
-1
@@ -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--
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+1
-1
@@ -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
Reference in New Issue
Block a user