mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-03-31 18:01:36 -04:00
feat(curriculum): add JS BFS workshop (#65848)
Co-authored-by: Jeevankumar S <110320697+Jeevankumar-s@users.noreply.github.com> Co-authored-by: majestic-owl448 <26656284+majestic-owl448@users.noreply.github.com> Co-authored-by: Kolade <chrisjay967@gmail.com>
This commit is contained in:
@@ -5707,6 +5707,12 @@
|
||||
"In this lab, you will implement a function that converts an adjacency list representation of a graph into an adjacency matrix representation."
|
||||
]
|
||||
},
|
||||
"workshop-breadth-first-search-js": {
|
||||
"title": "Implement the Breadth-First Search Algorithm",
|
||||
"intro": [
|
||||
"In this workshop, you will use the breadth-first search algorithm to generate all valid combinations of parentheses."
|
||||
]
|
||||
},
|
||||
"lab-depth-first-search-js": {
|
||||
"title": "Implement the Depth-First Search Algorithm",
|
||||
"intro": [
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
---
|
||||
id: 6989eb65324d97775c4965fe
|
||||
title: Step 1
|
||||
challengeType: 1
|
||||
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 `genParentheses` with a single parameter `pairs`. For now, return an empty array from the function.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should define a function named `genParentheses`.
|
||||
|
||||
```js
|
||||
assert.isFunction(genParentheses);
|
||||
```
|
||||
|
||||
Your `genParentheses` function should have a single parameter named `pairs`.
|
||||
|
||||
```js
|
||||
const genParenthesesParams = __helpers.getFunctionParams(genParentheses.toString());
|
||||
assert.equal(genParenthesesParams[0].name, 'pairs')
|
||||
```
|
||||
|
||||
Your function should return an empty array.
|
||||
|
||||
```js
|
||||
assert.isArray(genParentheses(1));
|
||||
assert.lengthOf(genParentheses(1), 0);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,50 @@
|
||||
---
|
||||
id: 6989ef885db3a3488a13b426
|
||||
title: Step 2
|
||||
challengeType: 1
|
||||
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 `Number.isInteger()` method 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 with the condition `!Number.isInteger(pairs)` inside the `genParentheses` function.
|
||||
|
||||
```js
|
||||
assert.match(genParentheses.toString(), /if\s*\(\s*!\s*Number\.isInteger\s*\(\s*pairs\s*\)\s*\)/);
|
||||
```
|
||||
|
||||
You should return a string when the input is not an integer.
|
||||
|
||||
```js
|
||||
let result = genParentheses("i");
|
||||
assert.isString(result);
|
||||
```
|
||||
|
||||
You should return the string `The number of pairs should be an integer` when the input is a string.
|
||||
|
||||
```js
|
||||
let result = genParentheses("i");
|
||||
assert.strictEqual(result, 'The number of pairs should be an integer');
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function genParentheses(pairs) {
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
return [];
|
||||
}
|
||||
```
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
---
|
||||
id: 6989f10a72ad424d4ad6d514
|
||||
title: Step 3
|
||||
challengeType: 1
|
||||
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 with the condition `pairs < 1`.
|
||||
|
||||
```js
|
||||
assert.match(genParentheses.toString(), /if\s*\(\s*pairs\s*<\s*1\s*\)/);
|
||||
```
|
||||
|
||||
You should return the string `The number of pairs should be at least 1` when `pairs` is less than `1`.
|
||||
|
||||
```js
|
||||
let result = genParentheses(0);
|
||||
assert.strictEqual(result, 'The number of pairs should be at least 1');
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function genParentheses(pairs) {
|
||||
if (!Number.isInteger(pairs)) {
|
||||
return 'The number of pairs should be an integer';
|
||||
}
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
return [];
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,51 @@
|
||||
---
|
||||
id: 6989f1ba358acba651d5ee6b
|
||||
title: Step 4
|
||||
challengeType: 1
|
||||
dashedName: step-4
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now you'll set up the data structure to store your results. Create a variable named `result` and initialize it to an empty array. This array will store all the valid parentheses combinations you generate.
|
||||
|
||||
Update your return statement to return `result` instead of an empty array.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should declare a variable named `result` in your `genParentheses` function.
|
||||
|
||||
```js
|
||||
assert.match(genParentheses.toString(), /result/);
|
||||
```
|
||||
|
||||
You should initialize `result` to an empty array.
|
||||
|
||||
```js
|
||||
assert.match(genParentheses.toString(), /result\s*=\s*\[\]/);
|
||||
```
|
||||
|
||||
You should return `result` at the end of your function.
|
||||
|
||||
```js
|
||||
assert.match(genParentheses.toString(), /return\s*result/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function genParentheses(pairs) {
|
||||
if (!Number.isInteger(pairs)) {
|
||||
return 'The number of pairs should be an integer';
|
||||
}
|
||||
if (pairs < 1) {
|
||||
return 'The number of pairs should be at least 1';
|
||||
}
|
||||
--fcc-editable-region--
|
||||
|
||||
return [];
|
||||
--fcc-editable-region--
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,50 @@
|
||||
---
|
||||
id: 6989f207306332c06b0add39
|
||||
title: Step 5
|
||||
challengeType: 1
|
||||
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 an array 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 to an array containing one array: `['', 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 `genParentheses` function.
|
||||
|
||||
```js
|
||||
assert.match(genParentheses.toString(), /queue/);
|
||||
```
|
||||
|
||||
You should initialize `queue` with an array containing the array `['', 0, 0]`.
|
||||
|
||||
```js
|
||||
assert.match(genParentheses.toString(), /queue\s*=\s*\[\s*\['',\s*0,\s*0\]\s*\]/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function genParentheses(pairs) {
|
||||
if (!Number.isInteger(pairs)) {
|
||||
return 'The number of pairs should be an integer';
|
||||
}
|
||||
if (pairs < 1) {
|
||||
return 'The number of pairs should be at least 1';
|
||||
}
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
let result = [];
|
||||
return result;
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,49 @@
|
||||
---
|
||||
id: 6989f2e35e6941e13e445156
|
||||
title: Step 6
|
||||
challengeType: 1
|
||||
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, that is, `queue.length` is greater than `0`.
|
||||
|
||||
Inside the loop, log `queue` to the console.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should create a `while` loop with the condition `queue.length > 0`.
|
||||
|
||||
```js
|
||||
assert.match(genParentheses.toString(), /while\s*\(\s*queue\.length\s*>\s*0\s*\)/);
|
||||
```
|
||||
|
||||
You should log `queue` to the console inside your `while` loop.
|
||||
|
||||
```js
|
||||
assert.match(genParentheses.toString(), /while\s*\(\s*queue\.length\s*>\s*0\s*\)/);
|
||||
assert.match(genParentheses.toString(), /console\.log\s*\(\s*queue\s*\)/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function genParentheses(pairs) {
|
||||
if (!Number.isInteger(pairs)) {
|
||||
return 'The number of pairs should be an integer';
|
||||
}
|
||||
if (pairs < 1) {
|
||||
return 'The number of pairs should be at least 1';
|
||||
}
|
||||
let queue = [['', 0, 0]];
|
||||
let result = [];
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
return result;
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,56 @@
|
||||
---
|
||||
id: 6989f3632f8b8bdf168aa321
|
||||
title: Step 7
|
||||
challengeType: 1
|
||||
dashedName: step-7
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Inside your `while` loop, use `queue.shift()` to remove and get the first element from the queue. This implements the first-in-first-out (FIFO) behavior characteristic of BFS.
|
||||
|
||||
Destructure this array into three variables: `current`, `opensUsed`, and `closesUsed`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use `queue.shift()` to get the first element from the queue.
|
||||
|
||||
```js
|
||||
assert.match(genParentheses.toString(), /queue\.shift\s*\(\s*\)/);
|
||||
```
|
||||
|
||||
You should destructure the result into three variables: `current`, `opensUsed`, and `closesUsed`.
|
||||
|
||||
```js
|
||||
assert.match(genParentheses.toString(), /opensUsed/);
|
||||
assert.match(genParentheses.toString(), /closesUsed/);
|
||||
assert.match(genParentheses.toString(), /current/);
|
||||
assert.match(genParentheses.toString(), /queue\.shift\s*\(\s*\)/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function genParentheses(pairs) {
|
||||
if (!Number.isInteger(pairs)) {
|
||||
return 'The number of pairs should be an integer';
|
||||
}
|
||||
if (pairs < 1) {
|
||||
return 'The number of pairs should be at least 1';
|
||||
}
|
||||
|
||||
let queue = [['', 0, 0]];
|
||||
let result = [];
|
||||
|
||||
while (queue.length > 0) {
|
||||
console.log(queue);
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
id: 6989f46b6e9366b0e6ad32fe
|
||||
title: Step 8
|
||||
challengeType: 1
|
||||
dashedName: step-8
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Before you keep working on the BFS logic, call `genParentheses(1)` and log the result to the console.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should log `genParentheses(1)` to the console.
|
||||
|
||||
```js
|
||||
assert.match(__helpers.removeJSComments(code), /console\.log\s*\(\s*genParentheses\s*\(\s*1\s*\)\s*\)/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function genParentheses(pairs) {
|
||||
if (!Number.isInteger(pairs)) {
|
||||
return 'The number of pairs should be an integer';
|
||||
}
|
||||
if (pairs < 1) {
|
||||
return 'The number of pairs should be at least 1';
|
||||
}
|
||||
|
||||
let queue = [['', 0, 0]];
|
||||
let result = [];
|
||||
|
||||
while (queue.length > 0) {
|
||||
console.log(queue);
|
||||
let [current, opensUsed, closesUsed] = queue.shift();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,55 @@
|
||||
---
|
||||
id: 6989f48c3f0292c84f8d8938
|
||||
title: Step 9
|
||||
challengeType: 1
|
||||
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 `current.length === 2 * pairs`. When this condition is true, push `current` to the `result` array.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have an `if` statement with the condition `current.length === 2 * pairs` inside your `while` loop.
|
||||
|
||||
```js
|
||||
assert.match(genParentheses.toString(), /if\s*\(\s*current\.length\s*===?\s*2\s*\*\s*pairs\s*\)/);
|
||||
```
|
||||
|
||||
You should push `current` to the `result` array inside your new `if` statement.
|
||||
|
||||
```js
|
||||
assert.match(genParentheses.toString(), /if\s*\(\s*current\.length\s*===?\s*2\s*\*\s*pairs\s*\)\s*\{[\s\S]*?result\.push\s*\(\s*current\s*\)/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function genParentheses(pairs) {
|
||||
if (!Number.isInteger(pairs)) {
|
||||
return 'The number of pairs should be an integer';
|
||||
}
|
||||
if (pairs < 1) {
|
||||
return 'The number of pairs should be at least 1';
|
||||
}
|
||||
|
||||
let queue = [['', 0, 0]];
|
||||
let result = [];
|
||||
|
||||
while (queue.length > 0) {
|
||||
console.log(queue);
|
||||
let [current, opensUsed, closesUsed] = queue.shift();
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
console.log(genParentheses(1));
|
||||
```
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
id: 6989f555728e63ad8b349d84
|
||||
title: Step 10
|
||||
challengeType: 1
|
||||
dashedName: step-10
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
If the current string isn't complete yet, you need to explore the next possible states. Add an `else` clause for the current `if` statement.
|
||||
|
||||
Inside the `else` block, you'll handle adding opening parentheses. Add an `if` statement to check if `opensUsed` is less than `pairs`. This ensures you don't use more opening parentheses than allowed.
|
||||
|
||||
If this condition is `true`, push a new array to the `queue`: `[current + '(', opensUsed + 1, closesUsed]`. 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
|
||||
assert.match(genParentheses.toString(), /if\s*\(\s*current\.length\s*===?\s*2\s*\*\s*pairs\s*\)\s*\{[\s\S]*?\}\s*else\s*\{/);
|
||||
```
|
||||
|
||||
You should have an `if` statement inside the `else` block with the condition `opensUsed < pairs`.
|
||||
|
||||
```js
|
||||
assert.match(genParentheses.toString(), /else\s*\{[\s\S]*?if\s*\(\s*opensUsed\s*<\s*pairs\s*\)/);
|
||||
```
|
||||
|
||||
You should push `[current + '(', opensUsed + 1, closesUsed]` to the queue when the condition is `true`.
|
||||
|
||||
```js
|
||||
assert.match(genParentheses.toString(), /queue\.push\s*\(\s*\[\s*current\s*\+\s*['"`]\(['"`]/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function genParentheses(pairs) {
|
||||
if (!Number.isInteger(pairs)) {
|
||||
return 'The number of pairs should be an integer';
|
||||
}
|
||||
if (pairs < 1) {
|
||||
return 'The number of pairs should be at least 1';
|
||||
}
|
||||
|
||||
let queue = [['', 0, 0]];
|
||||
let result = [];
|
||||
|
||||
while (queue.length > 0) {
|
||||
console.log(queue);
|
||||
let [current, opensUsed, closesUsed] = queue.shift();
|
||||
if (current.length === 2 * pairs) {
|
||||
result.push(current);
|
||||
--fcc-editable-region--
|
||||
}
|
||||
--fcc-editable-region--
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
console.log(genParentheses(1));
|
||||
```
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
id: 6989f5bf7f1a1d0fc8ebd1e8
|
||||
title: Step 11
|
||||
challengeType: 1
|
||||
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 a second `if` statement to check if `closesUsed` is less than `opensUsed`.
|
||||
|
||||
If this condition is true, push another new array to the `queue`: `[current + ')', opensUsed, closesUsed + 1]`. This represents the state after adding a closing parenthesis.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a second `if` statement with the condition `closesUsed < opensUsed` inside your `else` block.
|
||||
|
||||
```js
|
||||
assert.match(genParentheses.toString(), /if\s*\(\s*closesUsed\s*<\s*opensUsed\s*\)/);
|
||||
```
|
||||
|
||||
You should push `[current + ')', opensUsed, closesUsed + 1]` to the queue when the condition is true.
|
||||
|
||||
```js
|
||||
assert.match(genParentheses.toString(), /queue\.push\s*\(\s*\[\s*current\s*\+\s*['"`]\)['"`]/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function genParentheses(pairs) {
|
||||
if (!Number.isInteger(pairs)) {
|
||||
return 'The number of pairs should be an integer';
|
||||
}
|
||||
if (pairs < 1) {
|
||||
return 'The number of pairs should be at least 1';
|
||||
}
|
||||
|
||||
let queue = [['', 0, 0]];
|
||||
let result = [];
|
||||
|
||||
while (queue.length > 0) {
|
||||
console.log(queue);
|
||||
let [current, opensUsed, closesUsed] = queue.shift();
|
||||
|
||||
if (current.length === 2 * pairs) {
|
||||
result.push(current);
|
||||
} else {
|
||||
if (opensUsed < pairs) {
|
||||
queue.push([current + '(', opensUsed + 1, closesUsed]);
|
||||
}
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
console.log(genParentheses(1));
|
||||
```
|
||||
@@ -0,0 +1,63 @@
|
||||
---
|
||||
id: 6989f711e57008f3a23482f2
|
||||
title: Step 12
|
||||
challengeType: 1
|
||||
dashedName: step-12
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Your function is now complete. Test it again by logging `genParentheses(2)` instead of `genParentheses(1)`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should log `genParentheses(2)`.
|
||||
|
||||
```js
|
||||
assert.match(__helpers.removeJSComments(code), /console\.log\s*\(\s*genParentheses\s*\(\s*2\s*\)\s*\)/);
|
||||
```
|
||||
|
||||
You should not have `console.log(genParentheses(1))` in your code.
|
||||
|
||||
```js
|
||||
assert.notMatch(__helpers.removeJSComments(code), /console\.log\s*\(\s*genParentheses\s*\(\s*1\s*\)\s*\)/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function genParentheses(pairs) {
|
||||
if (!Number.isInteger(pairs)) {
|
||||
return 'The number of pairs should be an integer';
|
||||
}
|
||||
if (pairs < 1) {
|
||||
return 'The number of pairs should be at least 1';
|
||||
}
|
||||
|
||||
let queue = [['', 0, 0]];
|
||||
let result = [];
|
||||
|
||||
while (queue.length > 0) {
|
||||
console.log(queue);
|
||||
let [current, opensUsed, closesUsed] = queue.shift();
|
||||
|
||||
if (current.length === 2 * pairs) {
|
||||
result.push(current);
|
||||
} else {
|
||||
if (opensUsed < pairs) {
|
||||
queue.push([current + '(', opensUsed + 1, closesUsed]);
|
||||
}
|
||||
if (closesUsed < opensUsed) {
|
||||
queue.push([current + ')', opensUsed, closesUsed + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
--fcc-editable-region--
|
||||
console.log(genParentheses(1));
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,58 @@
|
||||
---
|
||||
id: 6989f788362592a7238b1f94
|
||||
title: Step 13
|
||||
challengeType: 1
|
||||
dashedName: step-13
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now you don't need to log the queue anymore. So remove `console.log(queue)` from your `while` loop.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should not have `console.log(queue)` in your `while` loop.
|
||||
|
||||
```js
|
||||
assert.notMatch(__helpers.removeJSComments(code), /console\.log\s*\(\s*queue\s*\)/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function genParentheses(pairs) {
|
||||
if (!Number.isInteger(pairs)) {
|
||||
return 'The number of pairs should be an integer';
|
||||
}
|
||||
if (pairs < 1) {
|
||||
return 'The number of pairs should be at least 1';
|
||||
}
|
||||
|
||||
let queue = [['', 0, 0]];
|
||||
let result = [];
|
||||
|
||||
while (queue.length > 0) {
|
||||
--fcc-editable-region--
|
||||
console.log(queue);
|
||||
--fcc-editable-region--
|
||||
|
||||
let [current, opensUsed, closesUsed] = queue.shift();
|
||||
|
||||
if (current.length === 2 * pairs) {
|
||||
result.push(current);
|
||||
} else {
|
||||
if (opensUsed < pairs) {
|
||||
queue.push([current + '(', opensUsed + 1, closesUsed]);
|
||||
}
|
||||
if (closesUsed < opensUsed) {
|
||||
queue.push([current + ')', opensUsed, closesUsed + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
console.log(genParentheses(2));
|
||||
```
|
||||
@@ -0,0 +1,94 @@
|
||||
---
|
||||
id: 6989f7d2f0bac8cfe05a068d
|
||||
title: Step 14
|
||||
challengeType: 1
|
||||
dashedName: step-14
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Finally, call `genParentheses` with `3` as its argument to generate all five valid combinations of three pairs of parentheses and log the result to the console.
|
||||
|
||||
With that, your breadth-first search workshop is complete.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should log `genParentheses(3)`.
|
||||
|
||||
```js
|
||||
assert.match(__helpers.removeJSComments(code), /console\.log\s*\(\s*genParentheses\s*\(\s*3\s*\)\s*\)/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function genParentheses(pairs) {
|
||||
if (!Number.isInteger(pairs)) {
|
||||
return 'The number of pairs should be an integer';
|
||||
}
|
||||
if (pairs < 1) {
|
||||
return 'The number of pairs should be at least 1';
|
||||
}
|
||||
|
||||
let queue = [['', 0, 0]];
|
||||
let result = [];
|
||||
|
||||
while (queue.length > 0) {
|
||||
let [current, opensUsed, closesUsed] = queue.shift();
|
||||
|
||||
if (current.length === 2 * pairs) {
|
||||
result.push(current);
|
||||
} else {
|
||||
if (opensUsed < pairs) {
|
||||
queue.push([current + '(', opensUsed + 1, closesUsed]);
|
||||
}
|
||||
if (closesUsed < opensUsed) {
|
||||
queue.push([current + ')', opensUsed, closesUsed + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
console.log(genParentheses(2));
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function genParentheses(pairs) {
|
||||
if (!Number.isInteger(pairs)) {
|
||||
return 'The number of pairs should be an integer';
|
||||
}
|
||||
if (pairs < 1) {
|
||||
return 'The number of pairs should be at least 1';
|
||||
}
|
||||
|
||||
let queue = [['', 0, 0]];
|
||||
let result = [];
|
||||
|
||||
while (queue.length > 0) {
|
||||
let [current, opensUsed, closesUsed] = queue.shift();
|
||||
|
||||
if (current.length === 2 * pairs) {
|
||||
result.push(current);
|
||||
} else {
|
||||
if (opensUsed < pairs) {
|
||||
queue.push([current + '(', opensUsed + 1, closesUsed]);
|
||||
}
|
||||
if (closesUsed < opensUsed) {
|
||||
queue.push([current + ')', opensUsed, closesUsed + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
console.log(genParentheses(2));
|
||||
console.log(genParentheses(3));
|
||||
```
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"isUpcomingChange": true,
|
||||
"dashedName": "workshop-breadth-first-search-js",
|
||||
"helpCategory": "JavaScript",
|
||||
"blockLayout": "challenge-grid",
|
||||
"challengeOrder": [
|
||||
{ "id": "6989eb65324d97775c4965fe", "title": "Step 1" },
|
||||
{ "id": "6989ef885db3a3488a13b426", "title": "Step 2" },
|
||||
{ "id": "6989f10a72ad424d4ad6d514", "title": "Step 3" },
|
||||
{ "id": "6989f1ba358acba651d5ee6b", "title": "Step 4" },
|
||||
{ "id": "6989f207306332c06b0add39", "title": "Step 5" },
|
||||
{ "id": "6989f2e35e6941e13e445156", "title": "Step 6" },
|
||||
{ "id": "6989f3632f8b8bdf168aa321", "title": "Step 7" },
|
||||
{ "id": "6989f46b6e9366b0e6ad32fe", "title": "Step 8" },
|
||||
{ "id": "6989f48c3f0292c84f8d8938", "title": "Step 9" },
|
||||
{ "id": "6989f555728e63ad8b349d84", "title": "Step 10" },
|
||||
{ "id": "6989f5bf7f1a1d0fc8ebd1e8", "title": "Step 11" },
|
||||
{ "id": "6989f711e57008f3a23482f2", "title": "Step 12" },
|
||||
{ "id": "6989f788362592a7238b1f94", "title": "Step 13" },
|
||||
{ "id": "6989f7d2f0bac8cfe05a068d", "title": "Step 14" }
|
||||
],
|
||||
"blockLabel": "workshop",
|
||||
"usesMultifileEditor": true,
|
||||
"hasEditableBoundaries": true
|
||||
}
|
||||
@@ -330,6 +330,7 @@
|
||||
"blocks": [
|
||||
"lecture-understanding-graphs-and-trees-js",
|
||||
"lab-adjacency-list-to-matrix-converter-js",
|
||||
"workshop-breadth-first-search-js",
|
||||
"lab-depth-first-search-js",
|
||||
"lab-n-queens-problem-js",
|
||||
"review-graphs-and-trees-js",
|
||||
|
||||
Reference in New Issue
Block a user