Skip to content

Commit 81a9867

Browse files
zairahiraJeevankumar-smajestic-owl448Ksound22
authored
feat(curriculum): add JS BFS workshop (freeCodeCamp#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>
1 parent 20fa1de commit 81a9867

17 files changed

Lines changed: 822 additions & 0 deletions

client/i18n/locales/english/intro.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5707,6 +5707,12 @@
57075707
"In this lab, you will implement a function that converts an adjacency list representation of a graph into an adjacency matrix representation."
57085708
]
57095709
},
5710+
"workshop-breadth-first-search-js": {
5711+
"title": "Implement the Breadth-First Search Algorithm",
5712+
"intro": [
5713+
"In this workshop, you will use the breadth-first search algorithm to generate all valid combinations of parentheses."
5714+
]
5715+
},
57105716
"lab-depth-first-search-js": {
57115717
"title": "Implement the Depth-First Search Algorithm",
57125718
"intro": [
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
---
2+
id: 6989eb65324d97775c4965fe
3+
title: Step 1
4+
challengeType: 1
5+
dashedName: step-1
6+
---
7+
8+
# --description--
9+
10+
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 `()()`.
11+
12+
Start by creating a function named `genParentheses` with a single parameter `pairs`. For now, return an empty array from the function.
13+
14+
# --hints--
15+
16+
You should define a function named `genParentheses`.
17+
18+
```js
19+
assert.isFunction(genParentheses);
20+
```
21+
22+
Your `genParentheses` function should have a single parameter named `pairs`.
23+
24+
```js
25+
const genParenthesesParams = __helpers.getFunctionParams(genParentheses.toString());
26+
assert.equal(genParenthesesParams[0].name, 'pairs')
27+
```
28+
29+
Your function should return an empty array.
30+
31+
```js
32+
assert.isArray(genParentheses(1));
33+
assert.lengthOf(genParentheses(1), 0);
34+
```
35+
36+
# --seed--
37+
38+
## --seed-contents--
39+
40+
```js
41+
--fcc-editable-region--
42+
43+
--fcc-editable-region--
44+
```
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
id: 6989ef885db3a3488a13b426
3+
title: Step 2
4+
challengeType: 1
5+
dashedName: step-2
6+
---
7+
8+
# --description--
9+
10+
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.
11+
12+
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.
13+
14+
If the condition is true, return the string `The number of pairs should be an integer`.
15+
16+
# --hints--
17+
18+
You should have an if statement with the condition `!Number.isInteger(pairs)` inside the `genParentheses` function.
19+
20+
```js
21+
assert.match(genParentheses.toString(), /if\s*\(\s*!\s*Number\.isInteger\s*\(\s*pairs\s*\)\s*\)/);
22+
```
23+
24+
You should return a string when the input is not an integer.
25+
26+
```js
27+
let result = genParentheses("i");
28+
assert.isString(result);
29+
```
30+
31+
You should return the string `The number of pairs should be an integer` when the input is a string.
32+
33+
```js
34+
let result = genParentheses("i");
35+
assert.strictEqual(result, 'The number of pairs should be an integer');
36+
```
37+
38+
# --seed--
39+
40+
## --seed-contents--
41+
42+
```js
43+
function genParentheses(pairs) {
44+
--fcc-editable-region--
45+
46+
--fcc-editable-region--
47+
return [];
48+
}
49+
```
50+
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
---
2+
id: 6989f10a72ad424d4ad6d514
3+
title: Step 3
4+
challengeType: 1
5+
dashedName: step-3
6+
---
7+
8+
# --description--
9+
10+
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.
11+
12+
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`.
13+
14+
# --hints--
15+
16+
You should have a second `if` statement with the condition `pairs < 1`.
17+
18+
```js
19+
assert.match(genParentheses.toString(), /if\s*\(\s*pairs\s*<\s*1\s*\)/);
20+
```
21+
22+
You should return the string `The number of pairs should be at least 1` when `pairs` is less than `1`.
23+
24+
```js
25+
let result = genParentheses(0);
26+
assert.strictEqual(result, 'The number of pairs should be at least 1');
27+
```
28+
29+
# --seed--
30+
31+
## --seed-contents--
32+
33+
```js
34+
function genParentheses(pairs) {
35+
if (!Number.isInteger(pairs)) {
36+
return 'The number of pairs should be an integer';
37+
}
38+
--fcc-editable-region--
39+
40+
--fcc-editable-region--
41+
return [];
42+
}
43+
```
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
id: 6989f1ba358acba651d5ee6b
3+
title: Step 4
4+
challengeType: 1
5+
dashedName: step-4
6+
---
7+
8+
# --description--
9+
10+
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.
11+
12+
Update your return statement to return `result` instead of an empty array.
13+
14+
# --hints--
15+
16+
You should declare a variable named `result` in your `genParentheses` function.
17+
18+
```js
19+
assert.match(genParentheses.toString(), /result/);
20+
```
21+
22+
You should initialize `result` to an empty array.
23+
24+
```js
25+
assert.match(genParentheses.toString(), /result\s*=\s*\[\]/);
26+
```
27+
28+
You should return `result` at the end of your function.
29+
30+
```js
31+
assert.match(genParentheses.toString(), /return\s*result/);
32+
```
33+
34+
# --seed--
35+
36+
## --seed-contents--
37+
38+
```js
39+
function genParentheses(pairs) {
40+
if (!Number.isInteger(pairs)) {
41+
return 'The number of pairs should be an integer';
42+
}
43+
if (pairs < 1) {
44+
return 'The number of pairs should be at least 1';
45+
}
46+
--fcc-editable-region--
47+
48+
return [];
49+
--fcc-editable-region--
50+
}
51+
```
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
id: 6989f207306332c06b0add39
3+
title: Step 5
4+
challengeType: 1
5+
dashedName: step-5
6+
---
7+
8+
# --description--
9+
10+
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:
11+
12+
- The current string being built
13+
- The number of opening parentheses used so far
14+
- The number of closing parentheses used so far
15+
16+
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.
17+
18+
# --hints--
19+
20+
You should declare a variable named `queue` in your `genParentheses` function.
21+
22+
```js
23+
assert.match(genParentheses.toString(), /queue/);
24+
```
25+
26+
You should initialize `queue` with an array containing the array `['', 0, 0]`.
27+
28+
```js
29+
assert.match(genParentheses.toString(), /queue\s*=\s*\[\s*\['',\s*0,\s*0\]\s*\]/);
30+
```
31+
32+
# --seed--
33+
34+
## --seed-contents--
35+
36+
```js
37+
function genParentheses(pairs) {
38+
if (!Number.isInteger(pairs)) {
39+
return 'The number of pairs should be an integer';
40+
}
41+
if (pairs < 1) {
42+
return 'The number of pairs should be at least 1';
43+
}
44+
--fcc-editable-region--
45+
46+
--fcc-editable-region--
47+
let result = [];
48+
return result;
49+
}
50+
```
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
---
2+
id: 6989f2e35e6941e13e445156
3+
title: Step 6
4+
challengeType: 1
5+
dashedName: step-6
6+
---
7+
8+
# --description--
9+
10+
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`.
11+
12+
Inside the loop, log `queue` to the console.
13+
14+
# --hints--
15+
16+
You should create a `while` loop with the condition `queue.length > 0`.
17+
18+
```js
19+
assert.match(genParentheses.toString(), /while\s*\(\s*queue\.length\s*>\s*0\s*\)/);
20+
```
21+
22+
You should log `queue` to the console inside your `while` loop.
23+
24+
```js
25+
assert.match(genParentheses.toString(), /while\s*\(\s*queue\.length\s*>\s*0\s*\)/);
26+
assert.match(genParentheses.toString(), /console\.log\s*\(\s*queue\s*\)/);
27+
```
28+
29+
# --seed--
30+
31+
## --seed-contents--
32+
33+
```js
34+
function genParentheses(pairs) {
35+
if (!Number.isInteger(pairs)) {
36+
return 'The number of pairs should be an integer';
37+
}
38+
if (pairs < 1) {
39+
return 'The number of pairs should be at least 1';
40+
}
41+
let queue = [['', 0, 0]];
42+
let result = [];
43+
--fcc-editable-region--
44+
45+
--fcc-editable-region--
46+
47+
return result;
48+
}
49+
```
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
---
2+
id: 6989f3632f8b8bdf168aa321
3+
title: Step 7
4+
challengeType: 1
5+
dashedName: step-7
6+
---
7+
8+
# --description--
9+
10+
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.
11+
12+
Destructure this array into three variables: `current`, `opensUsed`, and `closesUsed`.
13+
14+
# --hints--
15+
16+
You should use `queue.shift()` to get the first element from the queue.
17+
18+
```js
19+
assert.match(genParentheses.toString(), /queue\.shift\s*\(\s*\)/);
20+
```
21+
22+
You should destructure the result into three variables: `current`, `opensUsed`, and `closesUsed`.
23+
24+
```js
25+
assert.match(genParentheses.toString(), /opensUsed/);
26+
assert.match(genParentheses.toString(), /closesUsed/);
27+
assert.match(genParentheses.toString(), /current/);
28+
assert.match(genParentheses.toString(), /queue\.shift\s*\(\s*\)/);
29+
```
30+
31+
# --seed--
32+
33+
## --seed-contents--
34+
35+
```js
36+
function genParentheses(pairs) {
37+
if (!Number.isInteger(pairs)) {
38+
return 'The number of pairs should be an integer';
39+
}
40+
if (pairs < 1) {
41+
return 'The number of pairs should be at least 1';
42+
}
43+
44+
let queue = [['', 0, 0]];
45+
let result = [];
46+
47+
while (queue.length > 0) {
48+
console.log(queue);
49+
--fcc-editable-region--
50+
51+
--fcc-editable-region--
52+
}
53+
54+
return result;
55+
}
56+
```

0 commit comments

Comments
 (0)