fix(curriculum): format challenge markdown as per linting rules (#36326)

* fix: Format challenge markdown according to linting rules

* fix: Put spaces after section tags
This commit is contained in:
Oliver Eyton-Williams
2019-07-18 17:32:12 +02:00
committed by mrugesh
parent c387873640
commit 7d4dc382b4
63 changed files with 257 additions and 156 deletions

View File

@ -6,6 +6,7 @@ challengeType: 1
## Description
<section id='description'>
Now that we have an idea of the basics lets write a more complex method.
In this challenge, we will create a method to add new values to our binary search tree. The method should be called <code>add</code> and it should accept an integer value to add to the tree. Take care to maintain the invariant of a binary search tree: the value in each left child should be less than or equal to the parent value, and the value in each right child should be greater than or equal to the parent value. Here, let's make it so our tree cannot hold duplicate values. If we try to add a value that already exists, the method should return <code>null</code>. Otherwise, if the addition is successful, <code>undefined</code> should be returned.
Hint: trees are naturally recursive data structures!
@ -30,10 +31,12 @@ tests:
- text: Adding an element that already exists returns <code>null</code>
testString: assert((function() { var test = false; if (typeof BinarySearchTree !== 'undefined') { test = new BinarySearchTree() } else { return false; }; if (typeof test.add !== 'function') { return false; }; test.add(4); return test.add(4) == null; })(), 'Adding an element that already exists returns <code>null</code>');
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='js-seed'>
```js
@ -49,6 +52,7 @@ function BinarySearchTree() {
// change code above this line
}
```
</div>
### After Test
@ -100,6 +104,7 @@ BinarySearchTree.prototype = {
}
};
```
</div>
</section>
@ -145,4 +150,5 @@ function BinarySearchTree() {
};
}
```
</section>

View File

@ -6,6 +6,7 @@ challengeType: 1
## Description
<section id='description'>
Let's create a addAt(index,element) method that adds an element at a given index.
Just like how we remove elements at a given index, we need to keep track of the currentIndex as we traverse the linked list. When the currentIndex matches the given index, we would need to reassign the previous node's next property to reference the new added node. And the new node should reference the next node in the currentIndex.
Returning to the conga line example, a new person wants to join the line, but he wants to join in the middle. You are in the middle of the line, so you take your hands off of the person ahead of you. The new person walks over and puts his hands on the person you once had hands on, and you now have your hands on the new person.
@ -13,6 +14,7 @@ Returning to the conga line example, a new person wants to join the line, but he
## Instructions
<section id='instructions'>
Create an <code>addAt(index,element)</code> method that adds an element at a given index. Return false if an element could not be added.
<strong>Note:</strong> Remember to check if the given index is a negative or is longer than the length of the linked list.
</section>
@ -29,10 +31,12 @@ tests:
- text: Your <code>addAt</code> method should return <code>false</code> if a node was unable to be added.
testString: assert((function(){var test = new LinkedList(); test.add('cat'); test.add('dog'); return (test.addAt(4,'cat') === false); }()), 'Your <code>addAt</code> method should return <code>false</code> if a node was unable to be added.');
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='js-seed'>
```js
@ -74,6 +78,7 @@ function LinkedList() {
// Only change code above this line
}
```
</div>
</section>

View File

@ -6,6 +6,7 @@ challengeType: 1
## Description
<section id='description'>
Graphs can be represented in different ways. Here we describe one way, which is called an <dfn>adjacency list</dfn>.
An adjacency list is essentially a bulleted list where the left side is the node and the right side lists all the other nodes it's connected to. Below is a representation of an adjacency list.
<blockquote>Node1: Node2, Node3<br>Node2: Node1<br>Node3: Node1</blockquote>
@ -34,6 +35,7 @@ var undirectedGArr = [
## Instructions
<section id='instructions'>
Create a social network as an undirected graph with 4 nodes/people named <code>James</code>, <code>Jill</code>, <code>Jenny</code>, and <code>Jeff</code>. There are edges/relationships between James and Jeff, Jill and Jenny, and Jeff and Jenny.
</section>
@ -51,10 +53,12 @@ tests:
- text: There should be an edge between <code>Jeff</code> and <code>Jenny</code>.
testString: assert(undirectedAdjList.Jeff.indexOf("Jenny") !== -1 && undirectedAdjList.Jenny.indexOf("Jeff") !== -1, 'There should be an edge between <code>Jeff</code> and <code>Jenny</code>.');
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='js-seed'>
```js

View File

@ -6,6 +6,7 @@ challengeType: 1
## Description
<section id='description'>
Another way to represent a graph is to put it in an <dfn>adjacency matrix</dfn>.
An <dfn>adjacency matrix</dfn> is a two-dimensional (2D) array where each nested array has the same number of elements as the outer array. In other words, it is a matrix or grid of numbers, where the numbers represent the edges. Zeros mean there is no edge or relationship.
<blockquote> 1 2 3<br> ------<br>1 | 0 1 1<br>2 | 1 0 0<br>3 | 1 0 0</blockquote>
@ -36,6 +37,7 @@ Graphs can also have <dfn>weights</dfn> on their edges. So far, we have <dfn>unw
## Instructions
<section id='instructions'>
Create an adjacency matrix of an undirected graph with five nodes. This matrix should be in a multi-dimensional array. These five nodes have relationships between the first and fourth node, the first and third node, the third and fifth node, and the fourth and fifth node. All edge weights are one.
</section>
@ -55,10 +57,12 @@ tests:
- text: There should be an edge between the fourth and fifth node.
testString: assert((adjMatUndirected[3][4] === 1) && (adjMatUndirected[4][3] === 1), 'There should be an edge between the fourth and fifth node.');
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='js-seed'>
```js
@ -80,4 +84,5 @@ var adjMatUndirected = [
[0, 0, 1, 1, 0]
];
```
</section>

View File

@ -6,12 +6,14 @@ challengeType: 1
## Description
<section id='description'>
Now that we have a general sense of what a binary search tree is let's talk about it in a little more detail. Binary search trees provide logarithmic time for the common operations of lookup, insertion, and deletion in the average case, and linear time in the worst case. Why is this? Each of those basic operations requires us to find an item in the tree (or in the case of insertion to find where it should go) and because of the tree structure at each parent node we are branching left or right and effectively excluding half the size of the remaining tree. This makes the search proportional to the logarithm of the number of nodes in the tree, which creates logarithmic time for these operations in the average case.
Ok, but what about the worst case? Well, consider constructing a tree from the following values, adding them left to right: <code>10</code>, <code>12</code>, <code>17</code>, <code>25</code>. Following our rules for a binary search tree, we will add <code>12</code> to the right of <code>10</code>, <code>17</code> to the right of this, and <code>25</code> to the right of this. Now our tree resembles a linked list and traversing it to find <code>25</code> would require us to traverse all the items in linear fashion. Hence, linear time in the worst case. The problem here is that the tree is unbalanced. We'll look a little more into what this means in the following challenges.
</section>
## Instructions
<section id='instructions'>
In this challenge, we will create a utility for our tree. Write a method <code>isPresent</code> which takes an integer value as input and returns a boolean value for the presence or absence of that value in the binary search tree.
</section>
@ -29,6 +31,7 @@ tests:
- text: <code>isPresent</code> handles cases where the tree is empty.
testString: assert((function() { var test = false; if (typeof BinarySearchTree !== 'undefined') { test = new BinarySearchTree() } else { return false; }; if (typeof test.isPresent !== 'function') { return false; }; return test.isPresent(5) == false; })(), '<code>isPresent</code> handles cases where the tree is empty.');
```
</section>
## Challenge Seed

View File

@ -6,11 +6,12 @@ challengeType: 1
## Description
<section id='description'>
In this challenge you will be creating a Circular Queue. A circular queue is a queue that writes to the end of a collection then begins overwriting itself at the beginning of the collection. This type of data structure is useful in certain situations. For example, a circular queue can be used for streaming media. Once the queue is full, new media data will overwrite old data.
A good way to illustrate this concept is with an array of length `5`:
```output
```js
[null, null, null, null, null]
^Read @ 0
^Write @ 0
@ -18,21 +19,23 @@ A good way to illustrate this concept is with an array of length `5`:
Here the read and write are both at position `0`. Now the queue gets 3 new records `a`, `b`, and `c`. Our queue now looks like:
```output
```js
[a, b, c, null, null]
^Read @ 0
^Write @ 3
```
As the read head reads, it can remove values or keep them:
```output
```js
[null, null, null, null, null]
^Read @ 3
^Write @ 3
```
Now we write the values `d`, `e`, and `f` to the queue. Once the write reaches the end of the array it loops back to the beginning:
```output
```js
[f, null, null, d, e]
^Read @ 3
^Write @ 1
@ -43,6 +46,7 @@ This approach requires a constant amount of memory but allows files of a much la
## Instructions
<section id='instructions'>
In this challenge we will implement a circular queue. The circular queue should provide `enqueue` and `dequeue` methods which allow you to read from and write to the queue. The class itself should also accept an integer argument which you can use to specify the size of the queue when created. We've written the starting version of this class for you in the code editor. When you enqueue items to the queue, the write pointer should advance forward and loop back to the beginning once it reaches the end of the queue. Likewise, the read pointer should advance forward as you dequeue items. The write pointer should not be allowed to move past the read pointer (our class won't let you overwrite data you haven't read yet) and the read pointer should not be able to advance past data you have written.
In addition, the `enqueue` method should return the item you enqueued if it is successful; otherwise it will return `null`. Similarly, when you dequeue an item, that item should be returned and if you cannot dequeue an item you should return `null`.
</section>
@ -69,6 +73,7 @@ tests:
## Challenge Seed
<section id='challengeSeed'>
<div id='js-seed'>
```js
@ -159,4 +164,5 @@ class CircularQueue {
}
}
```
</section>

View File

@ -6,11 +6,13 @@ challengeType: 1
## Description
<section id='description'>
The next few challenges will cover maps and hash tables. Maps are data structures that store key-value pairs. In JavaScript, these are available to us as objects. Maps provide rapid lookup of stored items based on key values and are very common and useful data structures.
</section>
## Instructions
<section id='instructions'>
Let's get some practice creating our own map. Because JavaScript objects provide a much more efficient map structure than anything we could write here, this is intended primarily as a learning exercise. However, JavaScript objects only provide us with certain operations. What if we wanted to define custom operations?
Use the <code>Map</code> object provided here as a wrapper around a JavaScript <code>object</code>. Create the following methods and operations on the Map object:
<ul>
@ -44,6 +46,7 @@ tests:
- text: The clear method empties the map and the size method returns the number of items present in the map.
testString: assert((function() { var test = false; if (typeof Map !== 'undefined') { test = new Map() }; test.add('b','b'); test.add('c','d'); test.remove('asdfas'); var init = test.size(); test.clear(); return (init == 2 && test.size() == 0)})(), 'The clear method empties the map and the size method returns the number of items present in the map.');
```
</section>
## Challenge Seed

View File

@ -6,7 +6,8 @@ challengeType: 1
## Description
<section id='description'>
In this exercise we are going to create a class named <code>Set</code> to emulate an abstract data structure called "set". A set is like an array, but it cannot contain duplicate values. The typical use for a set is to simply check for the presence of an item.
In this exercise we are going to create a class named <code>Set</code> to emulate an abstract data structure called "set". A set is like an array, but it cannot contain duplicate values. The typical use for a set is to simply check for the presence of an item.
We can see how ES6 set object works in the example below-
```js
@ -26,6 +27,7 @@ And finally, we will create a size method that returns the number of elements in
## Instructions
<section id='instructions'>
Create an <code>add</code> method that adds a unique value to the set collection and returns <code>true</code> if the value was successfully added and <code>false</code> otherwise.
Create a <code>remove</code> method that accepts a value and checks if it exists in the set. If it does, then this method should remove it from the set collection, and return <code>true</code>. Otherwise, it should return <code>false</code>.
@ -63,6 +65,7 @@ tests:
## Challenge Seed
<section id='challengeSeed'>
<div id='js-seed'>
```js
@ -130,4 +133,5 @@ class Set {
}
}
```
</section>

View File

@ -6,6 +6,7 @@ challengeType: 1
## Description
<section id='description'>
In the last section, we talked about what a stack is and how we can use an array to represent a stack. In this section, we will be creating our own stack class.
Although you can use arrays to create stacks, sometimes it is best to limit the amount of control we have with our stacks.
Apart from the <code>push</code> and <code>pop</code> method, stacks have other useful methods. Let's add a <code>peek</code>, <code>isEmpty</code>, and <code>clear</code> method to our stack class.
@ -13,6 +14,7 @@ Apart from the <code>push</code> and <code>pop</code> method, stacks have other
## Instructions
<section id='instructions'>
Write a <code>push</code> method that pushes an element to the top of the stack, a <code>pop</code> method that removes the element on the top of the stack, a <code>peek</code> method that looks at the first element in the stack, an <code>isEmpty</code> method that checks if the stack is empty, and a <code>clear</code> method that removes all elements from the stack.
Normally stacks don't have this, but we've added a <code>print</code> helper method that console logs the collection.
</section>
@ -41,10 +43,12 @@ tests:
- text: The <code>clear</code> method should remove all element from the stack
testString: assert((function(){var test = new Stack(); test.push('CS50'); test.clear(); return (test.isEmpty())}()), 'The <code>clear</code> method should remove all element from the stack');
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='js-seed'>
```js
@ -58,6 +62,7 @@ function Stack() {
// Only change code above this line
}
```
</div>
</section>

View File

@ -6,6 +6,7 @@ challengeType: 1
## Description
<section id='description'>
Here we will move on from binary search trees and take a look at another type of tree structure called a trie. A trie is an ordered search tree commonly used to hold strings, or more generically associative arrays or dynamic datasets in which the keys are strings. They are very good at storing sets of data when many keys will have overlapping prefixes, for example, all the words in a dictionary.
Unlike a binary tree, nodes are not associated with actual values. Instead, the path to a node represents a specific key. For instance, if we wanted to store the string code in a trie, we would have four nodes, one for each letter: c — o — d — e. Following that path through all these nodes will then create code as a string — that path is the key we stored. Then, if we wanted to add the string coding, it would share the first three nodes of code before branching away after the d. In this way, large datasets can be stored very compactly. In addition, search can be very quick because it is effectively limited to the length of the string you are storing. Furthermore, unlike binary trees a node can store any number of child nodes.
As you might have guessed from the above example, some metadata is commonly stored at nodes that hold the end of a key so that on later traversals that key can still be retrieved. For instance, if we added codes in our example above we would need some way to know that the e in code represents the end of a key that was previously entered. Otherwise, this information would effectively be lost when we add codes.
@ -13,6 +14,7 @@ As you might have guessed from the above example, some metadata is commonly stor
## Instructions
<section id='instructions'>
Let's create a trie to store words. It will accept words through an <code>add</code> method and store these in a trie data structure. It will also allow us to query if a given string is a word with an <code>isWord</code> method, and retrieve all the words entered into the trie with a <code>print</code> method. <code>isWord</code> should return a boolean value and print should return an array of all these words as string values.
In order for us to verify that this data structure is implemented correctly, we've provided a <code>Node</code> structure for each node in the tree. Each node will be an object with a <code>keys</code> property which is a JavaScript Map object. This will hold the individual letters that are valid keys of each node. We've also created an <code>end</code> property on the nodes that can be set to <code>true</code> if the node represents the termination of a word.
</section>
@ -38,6 +40,7 @@ tests:
## Challenge Seed
<section id='challengeSeed'>
<div id='js-seed'>
```js
@ -57,6 +60,7 @@ var Trie = function() {
// change code above this line
};
```
</div>
</section>

View File

@ -6,6 +6,7 @@ challengeType: 1
## Description
<section id='description'>
The new version of JavaScript provides us with a built-in Map object which provides much of the functionality we wrote by hand in the last challenge. This Map object, although similar to regular JavaScript objects, provides some useful functionality that normal objects lack. For example, an ES6 Map tracks the insertion order of items that are added to it. Here is a more complete overview of its methods:
<code>.has(key)</code> returns true or false based on the presence of a key
<code>.get(key)</code> returns the value associated with a key
@ -18,6 +19,7 @@ The new version of JavaScript provides us with a built-in Map object which provi
## Instructions
<section id='instructions'>
Define a JavaScript Map object and assign to it a variable called myMap. Add the key, value pair <code>freeCodeCamp</code>, <code>Awesome!</code> to it.
</section>
@ -31,15 +33,18 @@ tests:
- text: myMap contains the key value pair <code>freeCodeCamp</code>, <code>Awesome!</code>.
testString: assert(myMap.get('freeCodeCamp') === 'Awesome!', 'myMap contains the key value pair <code>freeCodeCamp</code>, <code>Awesome!</code>.');
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='js-seed'>
```js
// change code below this line
```
</div>
</section>

View File

@ -7,6 +7,7 @@ challengeType: 1
## Description
<section id='description'>
This is the first of three challenges where we will implement a more difficult operation in binary search trees: deletion. Deletion is difficult because removing nodes breaks links in the tree. These links must be carefully reestablished to ensure the binary tree structure is maintained. For some deletions, this means the tree must be rearranged. In general, you will encounter one of three cases when trying to delete a node:
Leaf Node: The target to delete has zero children.
One Child: The target to delete only has one child.
@ -17,6 +18,7 @@ Removing a leaf node is easy, we simply remove it. Deleting a node with one chil
## Instructions
<section id='instructions'>
Create a method on our binary tree called <code>remove</code>. We'll build the logic for our deletion operation in here. First, you'll want to create a function within remove that finds the node we are trying to delete in the current tree. If the node is not present in the tree, <code>remove</code> should return <code>null</code>. Now, if the target node is a leaf node with no children, then the parent reference to it should be set to <code>null</code>. This effectively deletes the node from the tree. To do this, you will have to keep track of the parent of the node we are trying to delete as well. It will also be useful to create a way to track the number of children the target node has, as this will determine which case our deletion falls under.
We will handle the second and third cases in the next challenges. Good luck!
</section>
@ -37,10 +39,12 @@ tests:
- text: The <code>remove</code> method removes leaf nodes from the tree
testString: assert((function() { var test = false; if (typeof BinarySearchTree !== 'undefined') { test = new BinarySearchTree() } else { return false; }; if (typeof test.remove !== 'function') { return false; }; test.add(5); test.add(3); test.add(7); test.add(6); test.add(10); test.add(12); test.remove(3); test.remove(12); test.remove(10); return (test.inorder().join('') == '567'); })(), 'The <code>remove</code> method removes leaf nodes from the tree');
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='js-seed'>
```js

View File

@ -6,11 +6,13 @@ challengeType: 1
## Description
<section id='description'>
Now that we can delete leaf nodes let's move on to the second case: deleting a node with one child. For this case, say we have a tree with the following nodes 1 — 2 — 3 where 1 is the root. To delete 2, we simply need to make the right reference in 1 point to 3. More generally to delete a node with only one child, we make that node's parent reference the next node in the tree.
</section>
## Instructions
<section id='instructions'>
We've provided some code in our <code>remove</code> method that accomplishes the tasks from the last challenge. We find the target to delete and its parent and define the number of children the target node has. Let's add the next case here for target nodes with only one child. Here, we'll have to determine if the single child is a left or right branch in the tree and then set the correct reference in the parent to point to this node. In addition, let's account for the case where the target is the root node (this means the parent node will be <code>null</code>). Feel free to replace all the starter code with your own as long as it passes the tests.
</section>
@ -34,10 +36,12 @@ tests:
- text: Removing the root in a tree with two nodes sets the second to be the root.
testString: assert((function() { var test = false; if (typeof BinarySearchTree !== 'undefined') { test = new BinarySearchTree() } else { return false; }; if (typeof test.remove !== 'function') { return false; }; test.add(15); test.add(27); test.remove(15); return (test.inorder().join('') == '27'); })(), 'Removing the root in a tree with two nodes sets the second to be the root.');
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='js-seed'>
```js

View File

@ -6,12 +6,14 @@ challengeType: 1
## Description
<section id='description'>
Removing nodes that have two children is the hardest case to implement. Removing a node like this produces two subtrees that are no longer connected to the original tree structure. How can we reconnect them? One method is to find the smallest value in the right subtree of the target node and replace the target node with this value. Selecting the replacement in this way ensures that it is greater than every node in the left subtree it becomes the new parent of but also less than every node in the right subtree it becomes the new parent of.
Once this replacement is made the replacement node must be removed from the right subtree. Even this operation is tricky because the replacement may be a leaf or it may itself be the parent of a right subtree. If it is a leaf we must remove its parent's reference to it. Otherwise, it must be the right child of the target. In this case, we must replace the target value with the replacement value and make the target reference the replacement's right child.
</section>
## Instructions
<section id='instructions'>
Let's finish our <code>remove</code> method by handling the third case. We've provided some code again for the first two cases. Add some code now to handle target nodes with two children. Any edge cases to be aware of? What if the tree has only three nodes? Once you are finished this will complete our deletion operation for binary search trees. Nice job, this is a pretty hard problem!
</section>
@ -39,10 +41,12 @@ tests:
- text: The root can be removed on a tree of three nodes.
testString: assert((function() { var test = false; if (typeof BinarySearchTree !== 'undefined') { test = new BinarySearchTree() } else { return false; }; if (typeof test.remove !== 'function') { return false; }; test.add(100); test.add(50); test.add(300); test.remove(100); return (test.inorder().join('') == 50300); })(), 'The root can be removed on a tree of three nodes.');
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='js-seed'>
```js

View File

@ -6,6 +6,7 @@ challengeType: 1
## Description
<section id='description'>
We know how to search a binary search tree for a specific value. But what if we just want to explore the entire tree? Or what if we don't have an ordered tree and we need to just search for a value? Here we will introduce some tree traversal methods which can be used to explore tree data structures. First up is depth-first search. In depth-first search, a given subtree is explored as deeply as possible before the search continues on to another subtree. There are three ways this can be done:
In-order: Begin the search at the left-most node and end at the right-most node.
Pre-order: Explore all the roots before the leaves.
@ -15,6 +16,7 @@ As you may guess, you may choose different search methods depending on what type
## Instructions
<section id='instructions'>
Here we will create these three search methods on our binary search tree. Depth-first search is an inherently recursive operation which continues to explore further subtrees so long as child nodes are present. Once you understand this basic concept, you can simply rearrange the order in which you explore the nodes and subtrees to produce any of the three searches above. For example, in post-order search we would want to recurse all the way to a leaf node before we begin to return any of the nodes themselves, whereas in pre-order search we would want to return the nodes first, and then continue recursing down the tree.
Define <code>inorder</code>, <code>preorder</code>, and <code>postorder</code> methods on our tree. Each of these methods should return an array of items which represent the tree traversal. Be sure to return the integer values at each node in the array, not the nodes themselves. Finally, return <code>null</code> if the tree is empty.
</section>
@ -45,6 +47,7 @@ tests:
- text: The <code>postorder</code> method returns <code>null</code> for an empty tree.
testString: assert((function() { var test = false; if (typeof BinarySearchTree !== 'undefined') { test = new BinarySearchTree() } else { return false; }; if (typeof test.postorder !== 'function') { return false; }; return (test.postorder() == null); })(), 'The <code>postorder</code> method returns <code>null</code> for an empty tree.');
```
</section>
## Challenge Seed