From 5dc709192c6c071f3c9a8e3d4014c2c47e33822d Mon Sep 17 00:00:00 2001 From: Josh Moncrieff Date: Sun, 11 Aug 2019 10:47:03 +1000 Subject: [PATCH] docs(book): fix grammar and typos in part01 --- book/content/part01/algorithms-analysis.asc | 8 ++++---- book/content/part01/big-o-examples.asc | 22 ++++++++++----------- package-lock.json | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/book/content/part01/algorithms-analysis.asc b/book/content/part01/algorithms-analysis.asc index a111f7d8..92ca306e 100644 --- a/book/content/part01/algorithms-analysis.asc +++ b/book/content/part01/algorithms-analysis.asc @@ -115,7 +115,7 @@ When we are comparing algorithms, we don't want to have complex expressions. Wha TIP: Asymptotic analysis describes the behavior of functions as their inputs approach to infinity. -In the previous example, we analyzed `getMin` with an array of size 3; what happen size is 10 or 10k or a million? +In the previous example, we analyzed `getMin` with an array of size 3; what happens if the size is 10, 10k, or 10 million? (((Tables, Intro, Operations of 3n+3))) .Operations performed by an algorithm with a time complexity of `3n + 3` @@ -152,11 +152,11 @@ To sum up: TIP: Big O only cares about the highest order of the run time function and the worst-case scenario. -WARNING: Don't drop terms that multiplying other terms. _O(n log n)_ is not equivalent to _O(n)_. However, _O(n + log n)_ is. +WARNING: Don't drop terms that are multiplying other terms. _O(n log n)_ is not equivalent to _O(n)_. However, _O(n + log n)_ is. There are many common notations like polynomial, _O(n^2^)_ like we saw in the `getMin` example; constant _O(1)_ and many more that we are going to explore in the next chapter. -Again, time complexity is not a direct measure of how long a program takes to execute but rather how many operations it performs in given the input size. Nevertheless, there’s a relationship between time complexity and clock time as we can see in the following table. +Again, time complexity is not a direct measure of how long a program takes to execute, but rather how many operations it performs given the input size. Nevertheless, there’s a relationship between time complexity and clock time as we can see in the following table. (((Tables, Intro, Input size vs clock time by Big O))) // tag::table[] @@ -172,7 +172,7 @@ Again, time complexity is not a direct measure of how long a program takes to ex |=============================================================== // end::table[] -This just an illustration since in different hardware the times will be slightly different. +This is just an illustration since in different hardware the times will be slightly different. NOTE: These times are under the assumption of running on 1 GHz CPU and it can execute on average one instruction in 1 nanosecond (usually takes more time). Also, keep in mind that each line might be translated into dozens of CPU instructions depending on the programming language. Regardless, bad algorithms would perform poorly even on a supercomputer. diff --git a/book/content/part01/big-o-examples.asc b/book/content/part01/big-o-examples.asc index abc3f65c..55042627 100644 --- a/book/content/part01/big-o-examples.asc +++ b/book/content/part01/big-o-examples.asc @@ -5,7 +5,7 @@ endif::[] === Big O examples -There are many kinds of algorithms. Most of them fall into one of the eight of the time complexities that we are going to explore in this chapter. +There are many kinds of algorithms. Most of them fall into one of the eight time complexities that we are going to explore in this chapter. .Eight Running Time complexity You Should Know - Constant time: _O(1)_ @@ -47,7 +47,7 @@ include::{codedir}/runtimes/01-is-empty.js[tag=isEmpty] Another more real life example is adding an element to the begining of a <>. You can check out the implementation <>. -As you can see, in both examples (array and linked list) if the input is a collection of 10 elements or 10M it would take the same amount of time to execute. You can't get any more performance than this! +As you can see, in both examples (array and linked list) if the input is a collection of 10 elements or 10M it would take the same amount of time to execute. You can't get any more performant than this! [[logarithmic]] ==== Logarithmic @@ -68,7 +68,7 @@ The binary search only works for sorted lists. It starts searching for an elemen include::{codedir}/runtimes/02-binary-search.js[tag=binarySearchRecursive] ---- -This binary search implementation is a recursive algorithm, which means that the function `binarySearch` calls itself multiple times until the solution is found. The binary search split the array in half every time. +This binary search implementation is a recursive algorithm, which means that the function `binarySearch` calls itself multiple times until the solution is found. The binary search splits the array in half every time. Finding the runtime of recursive algorithms is not very obvious sometimes. It requires some tools like recursion trees or the https://adrianmejia.com/blog/2018/04/24/analysis-of-recursive-algorithms/[Master Theorem]. The `binarySearch` divides the input in half each time. As a rule of thumb, when you have an algorithm that divides the data in half on each call you are most likely in front of a logarithmic runtime: _O(log n)_. @@ -134,7 +134,7 @@ The merge function combines two sorted arrays in ascending order. Let’s say th .Mergesort visualization. Shows the split, sort and merge steps image::image11.png[Mergesort visualization,width=500,height=600] -How do we obtain the running time of the merge sort algorithm? The mergesort divides the array in half each time in the split phase, _log n_, and the merge function join each splits, _n_. The total work we have *O(n log n)*. There more formal ways to reach to this runtime like using the https://adrianmejia.com/blog/2018/04/24/analysis-of-recursive-algorithms/[Master Method] and https://www.cs.cornell.edu/courses/cs3110/2012sp/lectures/lec20-master/lec20.html[recursion trees]. +How do we obtain the running time of the merge sort algorithm? The mergesort divides the array in half each time in the split phase, _log n_, and the merge function join each splits, _n_. The total work is *O(n log n)*. There are more formal ways to reach this runtime, like using the https://adrianmejia.com/blog/2018/04/24/analysis-of-recursive-algorithms/[Master Method] and https://www.cs.cornell.edu/courses/cs3110/2012sp/lectures/lec20-master/lec20.html[recursion trees]. [[quadratic]] ==== Quadratic @@ -142,7 +142,7 @@ How do we obtain the running time of the merge sort algorithm? The mergesort div (((Runtime, Quadratic))) Running times that are quadratic, O(n^2^), are the ones to watch out for. They usually don’t scale well when they have a large amount of data to process. -Usually, they have double-nested loops that where each one visits all or most elements in the input. One example of this is a naïve implementation to find duplicate words on an array. +Usually they have double-nested loops, where each one visits all or most elements in the input. One example of this is a naïve implementation to find duplicate words on an array. [[quadratic-example]] ===== Finding duplicates in an array (naïve approach) @@ -157,7 +157,7 @@ If you remember we have solved this problem more efficiently on the <> you will get the answer in seconds! [big]#🚀# @@ -165,7 +165,7 @@ Let’s say you want to find a duplicated middle name in a phone directory book ==== Cubic (((Cubic))) (((Runtime, Cubic))) -Cubic *O(n^3^)* and higher polynomial functions usually involve many nested loops. As an example of a cubic algorithm is a multi-variable equation solver (using brute force): +Cubic *O(n^3^)* and higher polynomial functions usually involve many nested loops. An example of a cubic algorithm is a multi-variable equation solver (using brute force): [[cubic-example]] ===== Solving a multi-variable equation @@ -184,15 +184,15 @@ A naïve approach to solve this will be the following program: include::{codedir}/runtimes/06-multi-variable-equation-solver.js[tag=findXYZ] ---- -WARNING: This just an example, there are better ways to solve multi-variable equations. +WARNING: This is just an example, there are better ways to solve multi-variable equations. -As you can see three nested loops usually translates to O(n^3^). If you have a four variable equation and four nested loops it would be O(n^4^) and so on when we have a runtime in the form of _O(n^c^)_, where _c > 1_, we can refer as a *polynomial runtime*. +As you can see three nested loops usually translates to O(n^3^). If you have a four variable equation and four nested loops it would be O(n^4^) and so on when we have a runtime in the form of _O(n^c^)_, where _c > 1_, we refer to this as a *polynomial runtime*. [[exponential]] ==== Exponential (((Exponential))) (((Runtime, Exponential))) -Exponential runtimes, O(2^n^), means that every time the input grows by one the number of operations doubles. Exponential programs are only usable for a tiny number of elements (<100) otherwise it might not finish on your lifetime. [big]#💀# +Exponential runtimes, O(2^n^), means that every time the input grows by one the number of operations doubles. Exponential programs are only usable for a tiny number of elements (<100) otherwise it might not finish in your lifetime. [big]#💀# Let’s do an example. @@ -251,7 +251,7 @@ include::{codedir}/runtimes/08-permutations.js[tag=snippet] As you can see in the `getPermutations` function, the resulting array is the factorial of the word length. -Factorial start very slow and then it quickly becomes uncontrollable. A word size of just 11 characters would take a couple of hours in most computers! +Factorial starts very slow, and quickly becomes uncontrollable. A word size of just 11 characters would take a couple of hours in most computers! [big]*🤯* ==== Summary diff --git a/package-lock.json b/package-lock.json index 79c75fba..1b15347b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "dsa.js", - "version": "1.3.2", + "version": "1.3.3", "lockfileVersion": 1, "requires": true, "dependencies": {