mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-09-24 23:01:18 +08:00
feat(curriculum): add bfs workshop (#62517)
Co-authored-by: Ilenia <26656284+ilenia-magoni@users.noreply.github.com>
This commit is contained in:
@@ -4732,8 +4732,10 @@
|
||||
]
|
||||
},
|
||||
"workshop-breadth-first-search": {
|
||||
"title": "Build a Breadth First Search",
|
||||
"intro": [""]
|
||||
"title": "Implement the Breadth-First Search Algorithm",
|
||||
"intro": [
|
||||
"In this workshop, you will use the bread-first search algorithm to generate all valid combinations of parentheses."
|
||||
]
|
||||
},
|
||||
"lab-depth-first-search": {
|
||||
"title": "Implement the Depth-First Search Algorithm",
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Introduction to the Implement the Breadth-First Search Algorithm
|
||||
block: workshop-breadth-first-search
|
||||
superBlock: full-stack-developer
|
||||
---
|
||||
|
||||
## Introduction to the Implement the Breadth-First Search Algorithm
|
||||
|
||||
In this workshop, you will use the bread-first search algorithm to generate all valid combinations of parentheses.
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
---
|
||||
id: 68da604b8b6012a33e2344fb
|
||||
title: Step 1
|
||||
challengeType: 20
|
||||
dashedName: step-1
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this workshop, you'll implement a function that generates all valid combinations of parentheses using a breadth-first search (BFS) approach. For example, the valid combinations of two pairs of parentheses are `(())` and `()()`.
|
||||
|
||||
Start by creating a function named `gen_parentheses` with a single parameter `pairs`. For now, return an empty list from the function.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should define a function named `gen_parentheses`.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
assert _Node(_code).has_function("gen_parentheses")
|
||||
`) })
|
||||
```
|
||||
|
||||
Your `gen_parentheses` function should have a single parameter named `pairs`.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
assert _Node(_code).find_function("gen_parentheses").has_args("pairs")
|
||||
`) })
|
||||
```
|
||||
|
||||
Your function should return an empty list.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
foo = _Node(_code).find_function("gen_parentheses")
|
||||
assert foo.has_return("[]") or foo.has_return("list()")
|
||||
`) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
---
|
||||
id: 68da6138d70960c197ec5eec
|
||||
title: Step 2
|
||||
challengeType: 20
|
||||
dashedName: step-2
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Before implementing the core algorithm, you need to validate the input. The `pairs` parameter should be an integer, as it represents the number of parentheses pairs to generate.
|
||||
|
||||
Add an `if` statement at the beginning of your function to check if `pairs` is not an integer. Use the `isinstance()` function for that.
|
||||
|
||||
If the condition is true, return the string `The number of pairs should be an integer`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have an `if` statement in your `gen_parentheses` function.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
assert _Node(_code).find_function("gen_parentheses").find_ifs()[0]
|
||||
`) })
|
||||
```
|
||||
|
||||
Your `if` statement should check if `pairs` is not an integer using `not isinstance(pairs, int)`.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
assert _Node(_code).find_function("gen_parentheses").find_ifs()[0].find_conditions()[0].is_equivalent("not isinstance(pairs, int)")
|
||||
`) })
|
||||
```
|
||||
|
||||
You should return the string `The number of pairs should be an integer` when the input is not an integer.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
msg = 'The number of pairs should be an integer'
|
||||
args = [1.1, "1", [1, 2], {}]
|
||||
assert all(gen_parentheses(arg) == msg for arg in args)
|
||||
`) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
--fcc-editable-region--
|
||||
def gen_parentheses(pairs):
|
||||
|
||||
return []
|
||||
--fcc-editable-region--
|
||||
```
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
---
|
||||
id: 68da6138d70960c197ec5eed
|
||||
title: Step 3
|
||||
challengeType: 20
|
||||
dashedName: step-3
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Next, you need to validate that the number of pairs is at least one, since you can't generate parentheses combinations with zero or negative pairs.
|
||||
|
||||
Add another `if` statement to check if `pairs` is less than `1`. If this condition is true, return the string `The number of pairs should be at least 1`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a second `if` statement in your `gen_parentheses` function.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
assert _Node(_code).find_function("gen_parentheses").find_ifs()[1]
|
||||
`) })
|
||||
```
|
||||
|
||||
Your second `if` statement should check if `pairs` is less than `1`.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
cond = _Node(_code).find_function("gen_parentheses").find_ifs()[1].find_conditions()[0]
|
||||
assert cond.is_equivalent("pairs < 1") or cond.is_equivalent("1 > pairs")
|
||||
`) })
|
||||
```
|
||||
|
||||
You should return the string `The number of pairs should be at least 1` when `pairs` is less than `1`.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
msg = 'The number of pairs should be at least 1'
|
||||
assert gen_parentheses(0) == msg and gen_parentheses(-1) == msg
|
||||
`) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
--fcc-editable-region--
|
||||
def gen_parentheses(pairs):
|
||||
if not isinstance(pairs, int):
|
||||
return 'The number of pairs should be an integer'
|
||||
|
||||
return []
|
||||
--fcc-editable-region--
|
||||
```
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
---
|
||||
id: 68da6138d70960c197ec5eee
|
||||
title: Step 4
|
||||
challengeType: 20
|
||||
dashedName: step-4
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now you'll set up the data structure to store your results. Create a variable named `result` and initialize it as an empty list. This list will store all the valid parentheses combinations you generate.
|
||||
|
||||
Update your return statement to return `result` instead of an empty list.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should declare a variable named `result` in your `gen_parentheses` function.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
assert _Node(_code).find_function("gen_parentheses").has_variable("result")
|
||||
`) })
|
||||
```
|
||||
|
||||
You should initialize `result` as an empty list.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
assert _Node(_code).find_function("gen_parentheses").find_variable("result").is_equivalent("result = []")
|
||||
`) })
|
||||
```
|
||||
|
||||
You should return `result` at the end of your function.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
assert _Node(_code).find_function("gen_parentheses").has_return("result")
|
||||
`) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
--fcc-editable-region--
|
||||
def gen_parentheses(pairs):
|
||||
if not isinstance(pairs, int):
|
||||
return 'The number of pairs should be an integer'
|
||||
if pairs < 1:
|
||||
return 'The number of pairs should be at least 1'
|
||||
|
||||
return []
|
||||
--fcc-editable-region--
|
||||
```
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
---
|
||||
id: 68da6138d70960c197ec5eef
|
||||
title: Step 5
|
||||
challengeType: 20
|
||||
dashedName: step-5
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
For the breadth-first search approach, you'll use a queue to track different states as you build the parentheses combinations. Each state will be represented as a tuple containing three elements:
|
||||
|
||||
- The current string being built
|
||||
- The number of opening parentheses used so far
|
||||
- The number of closing parentheses used so far
|
||||
|
||||
Create a variable named `queue` and initialize it with a list containing one tuple: `('', 0, 0)`. This represents the starting state with an empty string and zero parentheses used.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should declare a variable named `queue` in your `gen_parentheses` function.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
assert _Node(_code).find_function("gen_parentheses").has_variable("queue")
|
||||
`) })
|
||||
```
|
||||
|
||||
You should initialize `queue` with a list containing the tuple `('', 0, 0)`.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
assert _Node(_code).find_function("gen_parentheses").find_variable("queue").is_equivalent("queue = [('', 0, 0)]")
|
||||
`) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
--fcc-editable-region--
|
||||
def gen_parentheses(pairs):
|
||||
if not isinstance(pairs, int):
|
||||
return 'The number of pairs should be an integer'
|
||||
if pairs < 1:
|
||||
return 'The number of pairs should be at least 1'
|
||||
|
||||
result = []
|
||||
return result
|
||||
--fcc-editable-region--
|
||||
```
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
---
|
||||
id: 68da6138d70960c197ec5ef0
|
||||
title: Step 6
|
||||
challengeType: 20
|
||||
dashedName: step-6
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now you'll implement the main BFS loop. Create a `while` loop that continues as long as the `queue` is not empty (while `queue` evaluates to `True`).
|
||||
|
||||
Inside the loop, print `queue`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a `while` loop in your `gen_parentheses` function.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
assert _Node(_code).find_function("gen_parentheses").find_whiles()[0]
|
||||
`) })
|
||||
```
|
||||
|
||||
Your `while` loop should have the condition `queue`.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
assert _Node(_code).find_function("gen_parentheses").find_whiles()[0].find_conditions()[0].is_equivalent("queue")
|
||||
`) })
|
||||
```
|
||||
|
||||
You should print `queue` inside your `while` loop.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
assert _Node(_code).find_function("gen_parentheses").find_whiles()[0].find_bodies()[0].has_call("print(queue)")
|
||||
`) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
--fcc-editable-region--
|
||||
def gen_parentheses(pairs):
|
||||
if not isinstance(pairs, int):
|
||||
return 'The number of pairs should be an integer'
|
||||
if pairs < 1:
|
||||
return 'The number of pairs should be at least 1'
|
||||
queue = [('', 0, 0)]
|
||||
result = []
|
||||
|
||||
|
||||
return result
|
||||
--fcc-editable-region--
|
||||
```
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
---
|
||||
id: 68da6138d70960c197ec5ef1
|
||||
title: Step 9
|
||||
challengeType: 20
|
||||
dashedName: step-9
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now you need to identify when you've built a complete parentheses combination. A complete combination has a length equal to twice the number of pairs (since each pair contributes one opening and one closing parenthesis).
|
||||
|
||||
Inside your `while` loop, add an `if` statement to check if `len(current) == 2 * pairs`. When this condition is true, append `current` to the `result` list.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have an `if` statement inside your `while` loop.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
assert _Node(_code).find_function("gen_parentheses").find_whiles()[0].find_bodies()[0].find_ifs()[0]
|
||||
`) })
|
||||
```
|
||||
|
||||
Your `if` statement should check if `len(current) == 2 * pairs`.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
assert _Node(_code).find_function("gen_parentheses").find_whiles()[0].find_bodies()[0].find_ifs()[0].find_conditions()[0].is_equivalent("len(current) == 2 * pairs")
|
||||
`) })
|
||||
```
|
||||
|
||||
You should append `current` to the `result` list inside your new `if` statement.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
assert _Node(_code).find_function("gen_parentheses").find_whiles()[0].find_bodies()[0].find_ifs()[0].find_bodies()[0].has_call("result.append(current)")
|
||||
`) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def gen_parentheses(pairs):
|
||||
if not isinstance(pairs, int):
|
||||
return 'The number of pairs should be an integer'
|
||||
if pairs < 1:
|
||||
return 'The number of pairs should be at least 1'
|
||||
|
||||
queue = [('', 0, 0)]
|
||||
result = []
|
||||
--fcc-editable-region--
|
||||
while queue:
|
||||
print(queue)
|
||||
current, opens_used, closes_used = queue.pop(0)
|
||||
|
||||
--fcc-editable-region--
|
||||
return result
|
||||
|
||||
print(gen_parentheses(1))
|
||||
```
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
---
|
||||
id: 68da6138d70960c197ec5ef2
|
||||
title: Step 10
|
||||
challengeType: 20
|
||||
dashedName: step-10
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
If the current string isn't complete yet, you need to explore the next possible states. Add an `else` clause to your `if` statement.
|
||||
|
||||
Inside the `else` block, you'll handle adding opening parentheses. Add an `if` statement to check if `opens_used < pairs`. This ensures you don't use more opening parentheses than allowed.
|
||||
|
||||
If this condition is true, append a new tuple to the `queue`: `(current + '(', opens_used + 1, closes_used)`. This represents the state after adding an opening parenthesis.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have an `else` clause for your `if` statement inside the `while` loop.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
assert _Node(_code).find_function("gen_parentheses").find_whiles()[0].find_bodies()[0].find_ifs()[0].tree.orelse
|
||||
`) })
|
||||
```
|
||||
|
||||
You should have an `if` statement inside the `else` block checking if `opens_used < pairs`.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
assert _Node(_code).find_function("gen_parentheses").find_whiles()[0].find_bodies()[0].find_ifs()[0].find_conditions()[1].is_equivalent("opens_used < pairs")
|
||||
`) })
|
||||
```
|
||||
|
||||
You should append `(current + '(', opens_used + 1, closes_used)` to the queue when the condition is true.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
assert _Node(_code).find_function("gen_parentheses").find_whiles()[0].find_bodies()[0].find_ifs()[0].find_bodies()[1].has_call("queue.append((current + '(', opens_used + 1, closes_used))")
|
||||
`) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def gen_parentheses(pairs):
|
||||
if not isinstance(pairs, int):
|
||||
return 'The number of pairs should be an integer'
|
||||
if pairs < 1:
|
||||
return 'The number of pairs should be at least 1'
|
||||
|
||||
queue = [('', 0, 0)]
|
||||
result = []
|
||||
--fcc-editable-region--
|
||||
while queue:
|
||||
print(queue)
|
||||
current, opens_used, closes_used = queue.pop(0)
|
||||
if len(current) == 2 * pairs:
|
||||
result.append(current)
|
||||
|
||||
--fcc-editable-region--
|
||||
return result
|
||||
|
||||
print(gen_parentheses(1))
|
||||
```
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
---
|
||||
id: 68da6138d70960c197ec5ef3
|
||||
title: Step 11
|
||||
challengeType: 20
|
||||
dashedName: step-11
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now you need to handle adding closing parentheses. The key rule is that you can only add a closing parenthesis if it maintains balance, meaning there must be more opening parentheses used than closing parentheses.
|
||||
|
||||
Still within the `else` block, add second `if` statement to check if `closes_used < opens_used`.
|
||||
|
||||
If this condition is true, append another new tuple to the `queue`: `(current + ')', opens_used, closes_used + 1)`. This represents the state after adding a closing parenthesis.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a second `if` statement inside your `else` block.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
import ast
|
||||
assert isinstance(_Node(_code).find_function("gen_parentheses").find_whiles()[0].find_bodies()[0].find_ifs()[0].tree.orelse[1], ast.If)
|
||||
`) })
|
||||
```
|
||||
|
||||
Your second nested `if` statement should check if `closes_used < opens_used`.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
assert _Node(_Node(_code).find_function("gen_parentheses").find_whiles()[0].find_bodies()[0].find_ifs()[0].tree.orelse[1].test).is_equivalent("closes_used < opens_used")
|
||||
`) })
|
||||
```
|
||||
|
||||
You should append `(current + ')', opens_used, closes_used + 1)` to the queue when the condition is true.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
assert _Node(_Node(_code).find_function("gen_parentheses").find_whiles()[0].find_bodies()[0].find_ifs()[0].tree.orelse[1]).has_call("queue.append((current + ')', opens_used, closes_used + 1))")
|
||||
`) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def gen_parentheses(pairs):
|
||||
if not isinstance(pairs, int):
|
||||
return 'The number of pairs should be an integer'
|
||||
if pairs < 1:
|
||||
return 'The number of pairs should be at least 1'
|
||||
|
||||
queue = [('', 0, 0)]
|
||||
result = []
|
||||
|
||||
while queue:
|
||||
print(queue)
|
||||
current, opens_used, closes_used = queue.pop(0)
|
||||
|
||||
if len(current) == 2 * pairs:
|
||||
result.append(current)
|
||||
--fcc-editable-region--
|
||||
else:
|
||||
if opens_used < pairs:
|
||||
queue.append((current + '(', opens_used + 1, closes_used))
|
||||
|
||||
--fcc-editable-region--
|
||||
return result
|
||||
|
||||
print(gen_parentheses(1))
|
||||
```
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
---
|
||||
id: 68da6138d70960c197ec5ef4
|
||||
title: Step 12
|
||||
challengeType: 20
|
||||
dashedName: step-12
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Your function is now complete. Test it again by printing `gen_parentheses(2)` instead of `gen_parentheses(1)`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should print `gen_parentheses(2)`.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
assert _Node(_code).has_call("print(gen_parentheses(2))")
|
||||
`) })
|
||||
```
|
||||
|
||||
You should not have `print(gen_parentheses(1))` in your code
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
assert not _Node(_code).has_call("print(gen_parentheses(1))")
|
||||
`) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def gen_parentheses(pairs):
|
||||
if not isinstance(pairs, int):
|
||||
return 'The number of pairs should be an integer'
|
||||
if pairs < 1:
|
||||
return 'The number of pairs should be at least 1'
|
||||
|
||||
queue = [('', 0, 0)]
|
||||
result = []
|
||||
|
||||
while queue:
|
||||
print(queue)
|
||||
current, opens_used, closes_used = queue.pop(0)
|
||||
|
||||
if len(current) == 2 * pairs:
|
||||
result.append(current)
|
||||
else:
|
||||
if opens_used < pairs:
|
||||
queue.append((current + '(', opens_used + 1, closes_used))
|
||||
if closes_used < opens_used:
|
||||
queue.append((current + ')', opens_used, closes_used + 1))
|
||||
|
||||
return result
|
||||
--fcc-editable-region--
|
||||
print(gen_parentheses(1))
|
||||
--fcc-editable-region--
|
||||
```
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
---
|
||||
id: 68da6138d70960c197ec5ef5
|
||||
title: Step 13
|
||||
challengeType: 20
|
||||
dashedName: step-13
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now you don't need to print the queue anymore. So remove `print(queue)` from your `while` loop.
|
||||
# --hints--
|
||||
|
||||
You should not have `print(queue)` in your `while` loop.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
assert not _Node(_code).find_function("gen_parentheses").find_whiles()[0].find_bodies()[0].has_call("print(queue)")
|
||||
`) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def gen_parentheses(pairs):
|
||||
if not isinstance(pairs, int):
|
||||
return 'The number of pairs should be an integer'
|
||||
if pairs < 1:
|
||||
return 'The number of pairs should be at least 1'
|
||||
|
||||
queue = [('', 0, 0)]
|
||||
result = []
|
||||
--fcc-editable-region--
|
||||
while queue:
|
||||
print(queue)
|
||||
current, opens_used, closes_used = queue.pop(0)
|
||||
--fcc-editable-region--
|
||||
if len(current) == 2 * pairs:
|
||||
result.append(current)
|
||||
else:
|
||||
if opens_used < pairs:
|
||||
queue.append((current + '(', opens_used + 1, closes_used))
|
||||
if closes_used < opens_used:
|
||||
queue.append((current + ')', opens_used, closes_used + 1))
|
||||
|
||||
return result
|
||||
|
||||
print(gen_parentheses(2))
|
||||
```
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
---
|
||||
id: 68e00c5349cbddfef6dbc053
|
||||
title: Step 7
|
||||
challengeType: 20
|
||||
dashedName: step-7
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Inside your `while` loop, use `queue.pop(0)` to remove and get the first element from the queue. This implements the first-in-first-out (FIFO) behavior characteristic of BFS.
|
||||
|
||||
Unpack this tuple into three variables: `current`, `opens_used`, and `closes_used`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use `queue.pop(0)` to get the first element from the queue.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
assert "queue.pop(0)" in str(_Node(_code).find_function("gen_parentheses").find_whiles()[0].find_bodies()[0])
|
||||
`) })
|
||||
```
|
||||
|
||||
You should unpack the result into three variables: `current`, `opens_used`, and `closes_used`.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
assert _Node(_code).find_function("gen_parentheses").find_whiles()[0].find_bodies()[0].has_stmt("current, opens_used, closes_used = queue.pop(0)")
|
||||
`) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def gen_parentheses(pairs):
|
||||
if not isinstance(pairs, int):
|
||||
return 'The number of pairs should be an integer'
|
||||
if pairs < 1:
|
||||
return 'The number of pairs should be at least 1'
|
||||
|
||||
queue = [('', 0, 0)]
|
||||
result = []
|
||||
--fcc-editable-region--
|
||||
while queue:
|
||||
print(queue)
|
||||
|
||||
--fcc-editable-region--
|
||||
return result
|
||||
```
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
---
|
||||
id: 68e00f88cf82083df8e0497b
|
||||
title: Step 8
|
||||
challengeType: 20
|
||||
dashedName: step-8
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Before you keep working on the BFS logic, call `gen_parentheses(1)` and print the result to the console.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should print `gen_parentheses(1)` to the console.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
assert _Node(_code).has_call('print(gen_parentheses(1))')
|
||||
`) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def gen_parentheses(pairs):
|
||||
if not isinstance(pairs, int):
|
||||
return 'The number of pairs should be an integer'
|
||||
if pairs < 1:
|
||||
return 'The number of pairs should be at least 1'
|
||||
|
||||
queue = [('', 0, 0)]
|
||||
result = []
|
||||
|
||||
while queue:
|
||||
print(queue)
|
||||
current, opens_used, closes_used = queue.pop(0)
|
||||
|
||||
return result
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
---
|
||||
id: 68e03c0b7327c7012f12e333
|
||||
title: Step 14
|
||||
challengeType: 20
|
||||
dashedName: step-14
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Finally, call `gen_parentheses` with `3` as its argument to generate all five valid combinations of three pairs of parentheses and print the result to the console. With that the workshop is complete.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should print `gen_parentheses(3)`.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
assert _Node(_code).has_call("print(gen_parentheses(3))")
|
||||
`) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def gen_parentheses(pairs):
|
||||
if not isinstance(pairs, int):
|
||||
return 'The number of pairs should be an integer'
|
||||
if pairs < 1:
|
||||
return 'The number of pairs should be at least 1'
|
||||
|
||||
queue = [('', 0, 0)]
|
||||
result = []
|
||||
while queue:
|
||||
current, opens_used, closes_used = queue.pop(0)
|
||||
if len(current) == 2 * pairs:
|
||||
result.append(current)
|
||||
else:
|
||||
if opens_used < pairs:
|
||||
queue.append((current + '(', opens_used + 1, closes_used))
|
||||
if closes_used < opens_used:
|
||||
queue.append((current + ')', opens_used, closes_used + 1))
|
||||
|
||||
return result
|
||||
--fcc-editable-region--
|
||||
print(gen_parentheses(2))
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
def gen_parentheses(pairs):
|
||||
if not isinstance(pairs, int):
|
||||
return 'The number of pairs should be an integer'
|
||||
if pairs < 1:
|
||||
return 'The number of pairs should be at least 1'
|
||||
|
||||
queue = [('', 0, 0)]
|
||||
result = []
|
||||
while queue:
|
||||
current, opens_used, closes_used = queue.pop(0)
|
||||
if len(current) == 2 * pairs:
|
||||
result.append(current)
|
||||
else:
|
||||
if opens_used < pairs:
|
||||
queue.append((current + '(', opens_used + 1, closes_used))
|
||||
if closes_used < opens_used:
|
||||
queue.append((current + ')', opens_used, closes_used + 1))
|
||||
|
||||
return result
|
||||
|
||||
print(gen_parentheses(2))
|
||||
print(gen_parentheses(3))
|
||||
```
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "Implement the Breadth-First Search Algorithm",
|
||||
"isUpcomingChange": true,
|
||||
"dashedName": "workshop-breadth-first-search",
|
||||
"helpCategory": "Python",
|
||||
"blockLayout": "challenge-grid",
|
||||
"hasEditableBoundaries": true,
|
||||
"challengeOrder": [
|
||||
{ "id": "68da604b8b6012a33e2344fb", "title": "Step 1" },
|
||||
{ "id": "68da6138d70960c197ec5eec", "title": "Step 2" },
|
||||
{ "id": "68da6138d70960c197ec5eed", "title": "Step 3" },
|
||||
{ "id": "68da6138d70960c197ec5eee", "title": "Step 4" },
|
||||
{ "id": "68da6138d70960c197ec5eef", "title": "Step 5" },
|
||||
{ "id": "68da6138d70960c197ec5ef0", "title": "Step 6" },
|
||||
{ "id": "68e00c5349cbddfef6dbc053", "title": "Step 7" },
|
||||
{ "id": "68e00f88cf82083df8e0497b", "title": "Step 8" },
|
||||
{ "id": "68da6138d70960c197ec5ef1", "title": "Step 9" },
|
||||
{ "id": "68da6138d70960c197ec5ef2", "title": "Step 10" },
|
||||
{ "id": "68da6138d70960c197ec5ef3", "title": "Step 11" },
|
||||
{ "id": "68da6138d70960c197ec5ef4", "title": "Step 12" },
|
||||
{ "id": "68da6138d70960c197ec5ef5", "title": "Step 13" },
|
||||
{ "id": "68e03c0b7327c7012f12e333", "title": "Step 14" }
|
||||
],
|
||||
"blockType": "workshop",
|
||||
"usesMultifileEditor": true
|
||||
}
|
||||
@@ -773,6 +773,7 @@
|
||||
"blocks": [
|
||||
"lecture-understanding-graphs-and-trees",
|
||||
"lab-adjacency-list-to-matrix-converter",
|
||||
"workshop-breadth-first-search",
|
||||
"lab-depth-first-search",
|
||||
"review-graphs-and-trees",
|
||||
"quiz-graphs-and-trees"
|
||||
|
||||
Reference in New Issue
Block a user