fixes
This commit is contained in:
parent
c9401b3104
commit
0fcf9f84fa
58 changed files with 673 additions and 643 deletions
|
@ -10,7 +10,7 @@ while (i) {
|
|||
|
||||
Every loop iteration decreases `i` by `1`. The check `while(i)` stops the loop when `i = 0`.
|
||||
|
||||
Hence, the steps of the loop make the following sequence ("loop unrolled"):
|
||||
Hence, the steps of the loop form the following sequence ("loop unrolled"):
|
||||
|
||||
```js
|
||||
let i = 3;
|
||||
|
@ -23,4 +23,3 @@ alert(i--) // shows 1, decreases i to 0
|
|||
|
||||
// done, while(i) check stops the loop
|
||||
```
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ importance: 3
|
|||
|
||||
# Last loop value
|
||||
|
||||
What is be the last value alerted by this code? Why?
|
||||
What is the last value alerted by this code? Why?
|
||||
|
||||
```js
|
||||
let i = 3;
|
||||
|
@ -13,4 +13,3 @@ while (i) {
|
|||
alert( i-- );
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ The task demonstrates how postfix/prefix forms can lead to different results whe
|
|||
|
||||
Then follow `2,3,4…` -- the values show up one after another. The comparison always uses the incremented value, because `++` is before the variable.
|
||||
|
||||
Finally, `i=4` is incremented to `5`, the comparison `while(5 < 5)` fails and the loop stops. So `5` is not shown.
|
||||
Finally, `i=4` is incremented to `5`, the comparison `while(5 < 5)` fails, and the loop stops. So `5` is not shown.
|
||||
2. **From 1 to 5**
|
||||
|
||||
```js run
|
||||
|
@ -28,4 +28,3 @@ The task demonstrates how postfix/prefix forms can lead to different results whe
|
|||
Let's stop on `i=4`. The prefix form `++i` would increment it and use `5` in the comparison. But here we have the postfix form `i++`. So it increments `i` to `5`, but returns the old value. Hence the comparison is actually `while(4 < 5)` -- true, and the control goes on to `alert`.
|
||||
|
||||
The value `i=5` is the last one, because on the next step `while(5 < 5)` is false.
|
||||
|
||||
|
|
|
@ -4,9 +4,9 @@ importance: 4
|
|||
|
||||
# Which values shows the while?
|
||||
|
||||
For every loop, scribe down which values it shows, in your opinion.
|
||||
For every loop, write down which values it shows, in your opinion. And then compare with the answer.
|
||||
|
||||
And then compare with the answer.
|
||||
Both loops `alert` same values or not?
|
||||
|
||||
1. The prefix form `++i`:
|
||||
|
||||
|
@ -20,4 +20,3 @@ And then compare with the answer.
|
|||
let i = 0;
|
||||
while (i++ < 5) alert( i );
|
||||
```
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ for (let i = 0; i < 5; i++) alert( i );
|
|||
|
||||
That can be easily deducted from the algorithm of `for`:
|
||||
|
||||
1. Execute once `i=0` before everything.
|
||||
1. Execute once `i=0` before everything (begin).
|
||||
2. Check the condition `i<5`
|
||||
3. If `true` -- execute the loop body `alert(i)`, and then `i++`
|
||||
|
||||
|
|
|
@ -4,9 +4,9 @@ importance: 4
|
|||
|
||||
# Which values get shown by the "for" loop?
|
||||
|
||||
For each loop scribe down which values it is going to show.
|
||||
For each loop write down which values it is going to show. Then compare with the answer.
|
||||
|
||||
Then compare with the answer.
|
||||
Both loops `alert` same values or not?
|
||||
|
||||
1. The postfix form:
|
||||
|
||||
|
@ -18,4 +18,3 @@ Then compare with the answer.
|
|||
```js
|
||||
for (let i = 0; i < 5; ++i) alert( i );
|
||||
```
|
||||
|
||||
|
|
|
@ -10,6 +10,6 @@ do {
|
|||
The loop `do..while` repeats while both checks are truthy:
|
||||
|
||||
1. The check for `num <= 100` -- that is, the entered value is still not greater than `100`.
|
||||
2. The check for a truthiness of `num` checks that `num != null` and `num != ""` simultaneously.
|
||||
2. The check `&& num` is false when `num` is `null` or a empty strig. Then the `while` loop stops too.
|
||||
|
||||
P.S. By the way, if `num` is `null` then `num <= 100` would return `false`, not `true`!
|
||||
P.S. If `num` is `null` then `num <= 100` is `false`, so without the 2nd check the loop wouldn't stop if the user clicks CANCEL. Both checks are required.
|
||||
|
|
|
@ -4,11 +4,10 @@ importance: 5
|
|||
|
||||
# Repeat until the input is incorrect
|
||||
|
||||
Write a loop which prompts for a number greater than `100`. If the visitor enters another number -- ask him to repeat the input, and so on.
|
||||
Write a loop which prompts for a number greater than `100`. If the visitor enters another number -- ask him to input again.
|
||||
|
||||
The loop must ask for a number until either the visitor enters a number greater than `100` or cancels the input/enters an empty line.
|
||||
|
||||
Here we can assume that the visitor only inputs numbers. There's no need to implement the special handling for a non-numeric input in this task.
|
||||
Here we can assume that the visitor only inputs numbers. There's no need to implement a special handling for a non-numeric input in this task.
|
||||
|
||||
[demo]
|
||||
|
||||
|
|
|
@ -13,8 +13,10 @@ For each i in the interval {
|
|||
The code using a label:
|
||||
|
||||
```js run
|
||||
let n = 10;
|
||||
|
||||
nextPrime:
|
||||
for (let i = 2; i <= 10; i++) { // for each i...
|
||||
for (let i = 2; i <= n; i++) { // for each i...
|
||||
|
||||
for (let j = 2; j < i; j++) { // look for a divisor..
|
||||
if (i % j == 0) continue nextPrime; // not a prime, go next i
|
||||
|
@ -24,5 +26,4 @@ for (let i = 2; i <= 10; i++) { // for each i...
|
|||
}
|
||||
```
|
||||
|
||||
Surely, there's a lot of space to opimize it. Like, we could look for the divisors from `2` to square root of `i`. But anyway, if we want to be really efficient for large intervals, we need change the approach and rely heavily on advanced maths and algorithms like [Quadratic sieve](https://en.wikipedia.org/wiki/Quadratic_sieve), [General number field sieve](https://en.wikipedia.org/wiki/General_number_field_sieve) etc.
|
||||
|
||||
There's a lot of space to opimize it. For instance, we could look for the divisors from `2` to square root of `i`. But anyway, if we want to be really efficient for large intervals, we need change the approach and rely on advanced maths and complex algorithms like [Quadratic sieve](https://en.wikipedia.org/wiki/Quadratic_sieve), [General number field sieve](https://en.wikipedia.org/wiki/General_number_field_sieve) etc.
|
||||
|
|
|
@ -4,15 +4,14 @@ importance: 3
|
|||
|
||||
# Output prime numbers
|
||||
|
||||
An integer number greater than `1` is called a [prime](https://en.wikipedia.org/wiki/Prime_number) if it cannot be not divided without a remainder by anything except `1` and itself.
|
||||
An integer number greater than `1` is called a [prime](https://en.wikipedia.org/wiki/Prime_number) if it cannot be divided without a remainder by anything except `1` and itself.
|
||||
|
||||
In other words, `n>1` is a prime if the result of it's division by anything except `1` and `n` is not integer.
|
||||
In other words, `n>1` is a prime if it can't be evenly divided by anything except `1` and `n`.
|
||||
|
||||
For example, `5` is a prime, because it cannot be divided without a remainder by `2`, `3` and `4`.
|
||||
|
||||
**Write the code which outputs prime numbers in the interval from `2` to `10`.**
|
||||
**Write the code which outputs prime numbers in the interval from `2` to `n`.**
|
||||
|
||||
The result will be `2,3,5,7`.
|
||||
|
||||
P.S. The code should be easily modifiable for other intervals.
|
||||
For `n=10` the result will be `2,3,5,7`.
|
||||
|
||||
P.S. The code should work for any `n`, not be hard-tuned for any fixed value.
|
||||
|
|
|
@ -14,7 +14,8 @@ The `while` loop has the following syntax:
|
|||
|
||||
```js
|
||||
while (condition) {
|
||||
// code ("loop body")
|
||||
// code
|
||||
// so-called "loop body"
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -30,18 +31,18 @@ while (i < 3) { // shows 0, then 1, then 2
|
|||
}
|
||||
```
|
||||
|
||||
There's a special term *iteration* for each loop run. The loop in the example above makes 3 iterations.
|
||||
A single execution of the loop body is called *an iteration*. The loop in the example above makes 3 iterations.
|
||||
|
||||
If there were no `i++` in the example above, the loop would repeat (in theory) forever, eating 100% CPU. In practice, the browser would show a message about a "hanging" script and let the user stop it.
|
||||
If there were no `i++` in the example above, the loop would repeat (in theory) forever. In practice, the browser provides ways to stop such loops, and for server-side JavaScript we can kill the process.
|
||||
|
||||
The `while` converts `condition` to a logical value. It can be any expression, not just a comparison.
|
||||
Any expression or a variable can be a loop condition, not just a comparison. They are evaluated and converted to boolean by `while`.
|
||||
|
||||
For instance, the shorter way to write `while (i!=0)` could be `while (i)`:
|
||||
|
||||
```js run
|
||||
let i = 3;
|
||||
*!*
|
||||
while (i) { // when i becomes 0, the condition is falsy and the loop stops
|
||||
while (i) { // when i becomes 0, the condition becomes falsy, and the loop stops
|
||||
*/!*
|
||||
alert( i );
|
||||
i--;
|
||||
|
@ -69,7 +70,7 @@ do {
|
|||
} while (condition);
|
||||
```
|
||||
|
||||
The loop will first execute the body and then check the condition.
|
||||
The loop will first execute the body, then check the condition, and while it's truthy -- execute it again and again.
|
||||
|
||||
For example:
|
||||
|
||||
|
@ -81,11 +82,11 @@ do {
|
|||
} while (i < 3);
|
||||
```
|
||||
|
||||
This form of syntax is rarely used, because the ordinary `while` is more obvious. We don't need to scroll down the code looking for the condition.
|
||||
This form of syntax is rarely used. Usually, if there's no special reason, the other form is preferred: `while(…) {…}`.
|
||||
|
||||
## The "for" loop
|
||||
|
||||
The `for` loop is actually the most often used one.
|
||||
The `for` loop is the most often used one.
|
||||
|
||||
It looks like this:
|
||||
|
||||
|
@ -95,7 +96,7 @@ for (begin; condition; step) {
|
|||
}
|
||||
```
|
||||
|
||||
Let's see these parts in an example. For instance, the loop below runs `alert(i)` for `i` from `0` up to (but not including) `3`:
|
||||
Let's learn the meaning of these parts by example. The loop below runs `alert(i)` for `i` from `0` up to (but not including) `3`:
|
||||
|
||||
```js run
|
||||
for (let i = 0; i < 3; i++) { // shows 0, then 1, then 2
|
||||
|
@ -103,42 +104,45 @@ for (let i = 0; i < 3; i++) { // shows 0, then 1, then 2
|
|||
}
|
||||
```
|
||||
|
||||
Let's examine the last example part-by-part:
|
||||
Let's examine the `for` statement part by part:
|
||||
|
||||
| part | | |
|
||||
|-------|----------|----------------------------------------------------------------------------|
|
||||
| begin | `i=0` | Executes once upon entering the loop. |
|
||||
| condition | `i<3`| Checked before every loop iteration, if fails the loop stops. |
|
||||
| body | `alert(i)`| Runs again and again while the condition is truthy |
|
||||
| step| `i++` | Executes after the body on each iteration, but before the condition check. |
|
||||
| body | `alert(i)`| Runs again and again while the condition is truthy |
|
||||
|
||||
|
||||
The general loop algorithm works like this:
|
||||
```
|
||||
Begin
|
||||
Run begin
|
||||
→ (if condition → run body and run step)
|
||||
→ ... repeat while the condition is truthy
|
||||
→ (if condition → run body and run step)
|
||||
→ (if condition → run body and run step)
|
||||
→ ...
|
||||
```
|
||||
|
||||
If you are new to loops, then maybe it would help if you go back to the example and reproduce how it runs step-by-step on a piece of paper.
|
||||
|
||||
That's what exactly happens in our case:
|
||||
Here's what exactly happens in our case:
|
||||
|
||||
```js
|
||||
// for (let i = 0; i < 3; i++) alert(i)
|
||||
|
||||
// begin
|
||||
// run begin
|
||||
let i = 0
|
||||
// if condition → run body and run step
|
||||
if (i < 3) { alert(i); i++ }
|
||||
// repeat while the condition is truthy
|
||||
// if condition → run body and run step
|
||||
if (i < 3) { alert(i); i++ }
|
||||
// if condition → run body and run step
|
||||
if (i < 3) { alert(i); i++ }
|
||||
// ...finish, because now i == 3
|
||||
```
|
||||
|
||||
````smart header="Inline variable declaration"
|
||||
Here the "counter" variable `i` is declared right in the the loop. That's called an "inline" variable declaration. Such variable is visible only inside the loop.
|
||||
Here the "counter" variable `i` is declared right in the loop. That's called an "inline" variable declaration. Such variable is visible only inside the loop.
|
||||
|
||||
```js run
|
||||
for (*!*let*/!* i = 0; i < 3; i++) {
|
||||
|
@ -147,13 +151,15 @@ for (*!*let*/!* i = 0; i < 3; i++) {
|
|||
alert(i); // error, no such variable
|
||||
```
|
||||
|
||||
We can use an existing variable as well:
|
||||
Instead of defining a variable, we can use an existing one:
|
||||
|
||||
```js run
|
||||
let i = 0;
|
||||
|
||||
for (i = 0; i < 3; i++) { // use an existing variable
|
||||
alert(i); // 0, 1, 2
|
||||
}
|
||||
|
||||
alert(i); // 3, visible, because declared outside of the loop
|
||||
```
|
||||
|
||||
|
@ -162,14 +168,14 @@ alert(i); // 3, visible, because declared outside of the loop
|
|||
|
||||
### Skipping parts
|
||||
|
||||
Any part of the `for` can be skipped.
|
||||
Any part of `for` can be skipped.
|
||||
|
||||
For example, we can omit `begin` if we don't need to do anything at the loop start.
|
||||
|
||||
Like here:
|
||||
|
||||
```js run
|
||||
let i = 0; // imagine we have i already declared and assigned
|
||||
let i = 0; // we have i already declared and assigned
|
||||
|
||||
for (; i < 3; i++) { // no need for "begin"
|
||||
alert( i ); // 0, 1, 2
|
||||
|
@ -223,7 +229,7 @@ while (true) {
|
|||
alert( 'Sum: ' + sum );
|
||||
```
|
||||
|
||||
The `break` directive is activated in the line `(*)` if the user enters an empty line or cancels the input. It stops the loop immediately, passing the control to the first line after it's loop. Namely, `alert`.
|
||||
The `break` directive is activated in the line `(*)` if the user enters an empty line or cancels the input. It stops the loop immediately, passing the control to the first line after the loop. Namely, `alert`.
|
||||
|
||||
The combination: "infinite loop + `break` as needed" is great for situations when the condition must be checked not in beginning/end of the loop, but in the middle. Or even in several places of the body.
|
||||
|
||||
|
@ -248,7 +254,7 @@ for (let i = 0; i < 10; i++) {
|
|||
For even values of `i` the `continue` directive stops body execution, passing the control to the next iteration of `for` (with the next number). So the `alert` is only called for odd values.
|
||||
|
||||
````smart header="The directive `continue` helps to decrease nesting level"
|
||||
A loop for odd-only values could look like this:
|
||||
A loop that shows odd values could look like this:
|
||||
|
||||
```js
|
||||
for (let i = 0; i < 10; i++) {
|
||||
|
@ -268,7 +274,7 @@ But as a side-effect we got one more figure brackets nesting level. If the code
|
|||
````warn header="No `break/continue` to the right side of '?'"
|
||||
Please note that syntax constructs that are not expressions cannot be used in `'?'`. In particular, directives `break/continue` are disallowed there.
|
||||
|
||||
For example, if one we take this code:
|
||||
For example, if we take this code:
|
||||
|
||||
```js
|
||||
if (i > 5) {
|
||||
|
@ -295,7 +301,7 @@ That's just another reason not to use a question mark operator `'?'` instead of
|
|||
|
||||
Sometimes we need to break out from multiple nested loops at once.
|
||||
|
||||
For example, in the code below we loop over `i` and `j` asking for values on coordinates `(i, j)` from `(0,0)` to `(3,3)`:
|
||||
For example, in the code below we loop over `i` and `j` prompting for coordinates `(i, j)` from `(0,0)` to `(3,3)`:
|
||||
|
||||
```js run no-beautify
|
||||
for (let i = 0; i < 3; i++) {
|
||||
|
@ -312,7 +318,7 @@ for (let i = 0; i < 3; i++) {
|
|||
alert('Done!');
|
||||
```
|
||||
|
||||
Let's say we need a way to stop the process. Like if we user decides to cancel the input.
|
||||
We need a way to stop the process if the user cancels the input.
|
||||
|
||||
The ordinary `break` after `input` would only break the inner loop. That's not sufficient. Labels come to the rescue.
|
||||
|
||||
|
@ -323,7 +329,7 @@ labelName: for(...) {
|
|||
}
|
||||
```
|
||||
|
||||
We can put the `labelName` after a break statement, and it will break out of the labelled loop.
|
||||
The `break <labelName>` statement in the loop breaks out to the label.
|
||||
|
||||
Like here:
|
||||
|
||||
|
@ -354,7 +360,7 @@ outer:
|
|||
for (let i = 0; i < 3; i++) { ... }
|
||||
```
|
||||
|
||||
The `continue` directive can also be used with a label. In this case the execution would jump onto the next iteration of the labelled loop.
|
||||
The `continue` directive can also be used with a label. In this case the execution jumps to the next iteration of the labelled loop.
|
||||
|
||||
````warn header="Labels are not a \"goto\""
|
||||
Labels do not allow to jump into an arbitrary place of code.
|
||||
|
@ -379,6 +385,6 @@ We covered 3 types of loops:
|
|||
|
||||
To make an "infinite" loop, usually the `while(true)` construct is used. Such a loop, just like any other, can be stopped with the `break` directive.
|
||||
|
||||
If we don't want to do anything more on this iteration and would like to forward on to the next one -- the `continue` directive does it.
|
||||
If we don't want to do anything on the current iteration and would like to forward to the next one -- the `continue` directive does it.
|
||||
|
||||
`Break/continue` support labels before the loop. A label is the only way for `break/continue` to escape the nesting and go to the outer loop.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue