diff --git a/content/03_oscillation.html b/content/03_oscillation.html index 4ef00292..39cc7b96 100644 --- a/content/03_oscillation.html +++ b/content/03_oscillation.html @@ -858,9 +858,10 @@

Example 3.10: A Spring Connection

circle(this.anchor.x, this.anchor.y, 10); } - // Draw the spring connection between the bob position and the anchor. + //{!2.bottom-align} Draw the spring connection between the bob position and the anchor. showLine(bob) { stroke(0); + //{!2.continue} line(bob.position.x, bob.position.y, this.anchor.x, this.anchor.y); } } diff --git a/content/08_fractals.html b/content/08_fractals.html index f1985d07..12566230 100644 --- a/content/08_fractals.html +++ b/content/08_fractals.html @@ -232,7 +232,7 @@

Drawing the Cantor Set with Recur

Now the cantor() function looks like this:

function cantor(x, y, length) {
   line(x, y, x + len, y);
-  //{$1} Two recursive calls. Note that 20 pixels are added to y.
+  //{!2} Two recursive calls. Note that 20 pixels are added to y.
   cantor(x, y + 20, length / 3);
   cantor(x + (2 * length / 3), y + 20, length / 3);
 }
diff --git a/content/09_ga.html b/content/09_ga.html index 5a662a55..cca2b58c 100644 --- a/content/09_ga.html +++ b/content/09_ga.html @@ -39,7 +39,7 @@

Why Use Genetic Algorithms?

This is my meow-velous twist on the infinite monkey theorem, which is stated as follows: a monkey hitting keys randomly on a typewriter will eventually type the complete works of Shakespeare, given an infinite amount of time. It’s only a theory because in practice the number of possible combinations of letters and words makes the likelihood of the monkey actually typing Shakespeare minuscule. To put it in perspective, even if the monkey had started typing at the beginning of the universe, the probability that by now it would have produced just Hamlet, to say nothing of the entire works of Shakespeare, is still absurdly unlikely.

Consider a cat named Clawdius. Clawdius types on a reduced typewriter containing only 27 characters: the 26 English letters plus the spacebar. The probability of Clawdius hitting any given key is 1 in 27.

Next, consider the phrase “to be or not to be that is the question” (for simplicity, I’m ignoring capitalization and punctuation). The phrase is 39 characters long, including spaces. If Clawdius starts typing, the chance he’ll get the first character right is 1 in 27. Since the probability he’ll get the second character right is also 1 in 27, he has a 1 in 729 (27 \times 27) chance of landing the first two characters in correct order. (This follows directly from our discussion of probability in Chapter 0.) Therefore, the probability that Clawdius will type the full phrase is 1 in 27 multiplied by itself 39 times, or (1/27)^{39}. That equals a probability of . . .

-

1 \text{ in } \text{66,555,937,033,867,822,607,895,549,241,096,482,953,017,615,834,735,226,163}

+
1 \text{ in } \text{66,555,937,033,867,822,607,895,549,241,096,482,953,017,615,834,735,226,163}

Needless to say, even hitting just this one phrase, let alone an entire play, let alone all 38 Shakespeare plays (yes, even The Two Noble Kinsmen) is highly unlikely. Even if Clawdius were a computer simulation and could type a million random phrases per second, for Clawdius to have a 99 percent probability of eventually getting just the one phrase right, he would have to type for 9,719,096,182,010,563,073,125,591,133,903,305,625,605,017 years. (For comparison, the universe is estimated to be a mere 13,750,000,000 years old.)

The point of all these unfathomably large numbers isn’t to give you a headache, but to demonstrate that a brute-force algorithm (typing every possible random phrase) isn’t a reasonable strategy for arriving randomly at “to be or not to be that is the question.” Enter GAs, which start with random phrases and swiftly find the solution through simulated evolution, leaving plenty of time for Clawdius to savor a cozy catnap.

To be fair, this particular problem (to arrive at the phrase “to be or not to be that is the question”) is a ridiculous one. Since you know the answer already, all you need to do is type it. Here’s a p5.js sketch that solves the problem:

diff --git a/content/10_nn.html b/content/10_nn.html index d6445caf..15afeb32 100644 --- a/content/10_nn.html +++ b/content/10_nn.html @@ -368,11 +368,12 @@

The Perceptron Code

} } - //{!7} Train the network against known data. + //{!4} Train the network against known data. train(inputs, desired) { let guess = this.feedforward(inputs); let error = desired - guess; for (let i = 0; i < this.weights.length; i++) { + //{!3.continue} this.weights[i] = this.weights[i] + error * inputs[i] * this.learningConstant; } } diff --git a/magicbook/plugins/codesplit.js b/magicbook/plugins/codesplit.js index caacf59a..eb3434dc 100644 --- a/magicbook/plugins/codesplit.js +++ b/magicbook/plugins/codesplit.js @@ -49,9 +49,9 @@ Plugin.prototype = { // - when the custom max line number is achieved if ( (this.isComment(line) && pair.code.length > 0) || - currentIndent < pair.indent || - (line === '' && pair.comment.length > 0) || - (pair.maxLines !== null && pair.code.length >= pair.maxLines) + (!pair.maxLines && currentIndent < pair.indent) || + (!pair.maxLines && line === '' && pair.comment.length > 0) || + (!!pair.maxLines && pair.code.length >= pair.maxLines) ) { if (pair.code.length > 0 || pair.comment.length > 0) { pairs.push(pair); diff --git a/magicbook/stylesheets/components/codesplit.scss b/magicbook/stylesheets/components/codesplit.scss index 8001a2b3..425db2fb 100644 --- a/magicbook/stylesheets/components/codesplit.scss +++ b/magicbook/stylesheets/components/codesplit.scss @@ -52,6 +52,7 @@ display: flex; flex-wrap: wrap-reverse; justify-content: space-between; + break-inside: avoid; padding: 0 5mm; &:first-child { @@ -77,15 +78,19 @@ &.highlight { background: $color-gray-200; - } - // add a margin between adjacent highlight pairs - &.highlight + .pair.highlight { - border-top: 1pt solid $color-gray-100; - } + // add a margin between adjacent highlight pairs + + .pair.highlight { + border-top: 1pt solid $color-gray-100; + } - &.highlight + .pair.continue { - border-top: initial; + + .pair.continue { + border-top: initial; + } + + &.bottom-align { + align-items: flex-start; + } } .comment {