Skip to content

Commit c9647ca

Browse files
committed
Add exercises for chapter 22
1 parent e020fe5 commit c9647ca

File tree

5 files changed

+85
-13
lines changed

5 files changed

+85
-13
lines changed

11_async.md

+2
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,8 @@ Such a function no longer, like a regular JavaScript function, runs from start t
370370

371371
For most asynchronous code, this notation is more convenient than directly using promises. You do still need an understanding of promises, since in many cases you still interact with them directly. But when wiring them together, `async` functions are generally more pleasant to write than chains of `then` calls.
372372

373+
{{id generator}}
374+
373375
## Generators
374376

375377
{{index "async function"}}

code/solutions/22_1_prime_numbers.js

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
function* primes() {
2+
for (let n = 2;; n++) {
3+
let skip = false;
4+
for (let d = 2; d < n; d++) {
5+
if (n % d == 0) {
6+
skip = true;
7+
break;
8+
}
9+
}
10+
if (!skip) yield n;
11+
}
12+
}
13+
14+
function measurePrimes() {
15+
let iter = primes(), t0 = Date.now();
16+
for (let i = 0; i < 10000; i++) {
17+
iter.next();
18+
}
19+
console.log(`Took ${Date.now() - t0}ms`);
20+
}
21+
22+
measurePrimes();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
function* primes() {
2+
let found = [];
3+
for (let n = 2;; n++) {
4+
let skip = false, root = Math.sqrt(n);
5+
for (let prev of found) {
6+
if (prev > root) {
7+
break;
8+
} else if (n % prev == 0) {
9+
skip = true;
10+
break;
11+
}
12+
}
13+
if (!skip) {
14+
found.push(n);
15+
yield n;
16+
}
17+
}
18+
}
19+
20+
function measurePrimes() {
21+
let iter = primes(), t0 = Date.now();
22+
for (let i = 0; i < 10000; i++) {
23+
iter.next();
24+
}
25+
console.log(`Took ${Date.now() - t0}ms`);
26+
}
27+
28+
measurePrimes();

src/chapter_info.mjs

+29-11
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ for (let file of fs.readdirSync(".").sort()) {
8686
number: "1[3]",
8787
type: "js",
8888
code: "async function locateScalpel(nest) {\n // Your code here.\n}\n\nfunction locateScalpel2(nest) {\n // Your code here.\n}\n\nlocateScalpel(bigOak).then(console.log);\n// → Butcher Shop",
89-
solution: "async function locateScalpel(nest) {\n let current = nest.name;\n for (;;) {\n let next = await anyStorage(nest, current, \"scalpel\");\n if (next == current) return current;\n current = next;\n }\n}\n\nfunction locateScalpel2(nest) {\n function loop(current) {\n return anyStorage(nest, current, \"scalpel\").then(next => {\n if (next == current) return current;\n else return loop(next);\n });\n }\n return loop(nest.name);\n}\n\nlocateScalpel(bigOak).then(console.log);\n// → Butcher's Shop\nlocateScalpel2(bigOak).then(console.log);\n// → Butcher's Shop"
89+
solution: "async function locateScalpel(nest) {\n let current = nest.name;\n for (;;) {\n let next = await anyStorage(nest, current, \"scalpel\");\n if (next == current) return current;\n current = next;\n }\n}\n\nfunction locateScalpel2(nest) {\n function loop(current) {\n return anyStorage(nest, current, \"scalpel\").then(next => {\n if (next == current) return current;\n else return loop(next);\n });\n }\n return loop(nest.name);\n}\n\nlocateScalpel(bigOak).then(console.log);\n// → Butcher's Shop\nlocateScalpel2(bigOak).then(console.log);\n// → Butcher's Shop",
90+
goto: "https://eloquentjavascript.net/3rd_edition/code/#11.1"
9091
})
9192
if (chapter.number == 20) chapter.exercises = [
9293
{name: "Search tool",
@@ -134,29 +135,46 @@ for (let file of fs.readdirSync(".").sort()) {
134135
output.push({
135136
title: "JavaScript and Performance",
136137
number: 22,
137-
start_code: "<!-- This chapter exists in the paper book, not in the online version -->\n\n<script>\n runLayout(forceDirected_simple, treeGraph(4, 4));\n</script>\n",
138+
start_code: "<!-- This chapter exists in the paper book, not in the online version -->\n\n<script>\n runLayout(forceDirected_simple, gridGraph(12));\n</script>\n",
138139
include: ["code/draw_layout.js", "code/chapter/22_fast.js"],
139140
exercises: [
140-
{name: "Pathfinding",
141-
file: "code/solutions/22_1_pathfinding.js",
141+
{name: "Prime numbers",
142+
file: "code/solutions/22_1_prime_numbers.js",
142143
number: 1,
143144
type: "js",
145+
code: "function* primes() {\n for (let n = 2;; n++) {\n // ...\n }\n}\n\nfunction measurePrimes() {\n // ...\n}\n\nmeasurePrimes();\n",
146+
solution: fs.readFileSync("code/solutions/22_1_prime_numbers.js", "utf8")
147+
},
148+
{name: "Faster prime numbers",
149+
file: "code/solutions/22_2_faster_prime_numbers.js",
150+
number: 2,
151+
type: "js",
152+
code: "function* primes() {\n for (let n = 2;; n++) {\n // ...\n }\n}\n\nfunction measurePrimes() {\n // ...\n}\n\nmeasurePrimes();\n",
153+
solution: fs.readFileSync("code/solutions/22_2_faster_prime_numbers.js", "utf8"),
154+
},
155+
{name: "Pathfinding [3rd ed]",
156+
file: "code/solutions/22_1_pathfinding.js",
157+
number: "1[3]",
158+
type: "js",
144159
code: "function findPath(a, b) {\n // Your code here...\n}\n\nlet graph = treeGraph(4, 4);\nlet root = graph[0], leaf = graph[graph.length - 1];\nconsole.log(findPath(root, leaf).length);\n// → 4\n\nleaf.connect(root);\nconsole.log(findPath(root, leaf).length);\n// → 2\n",
145-
solution: fs.readFileSync("code/solutions/22_1_pathfinding.js", "utf8")
160+
solution: fs.readFileSync("code/solutions/22_1_pathfinding.js", "utf8"),
161+
goto: "https://eloquentjavascript.net/3rd_edition/code/#22.1"
146162
},
147-
{name: "Timing",
163+
{name: "Timing [3rd ed]",
148164
file: "code/solutions/22_2_timing.js",
149-
number: 2,
165+
number: "2[3]",
150166
type: "js",
151167
code: "",
152-
solution: fs.readFileSync("code/solutions/22_2_timing.js", "utf8")
168+
solution: fs.readFileSync("code/solutions/22_2_timing.js", "utf8"),
169+
goto: "https://eloquentjavascript.net/3rd_edition/code/#22.2"
153170
},
154-
{name: "Optimizing",
171+
{name: "Optimizing [3rd ed]",
155172
file: "code/solutions/22_3_optimizing.js",
156-
number: 3,
173+
number: "3[3]",
157174
type: "js",
158175
code: "",
159-
solution: fs.readFileSync("code/solutions/22_3_optimizing.js", "utf8")
176+
solution: fs.readFileSync("code/solutions/22_3_optimizing.js", "utf8"),
177+
goto: "https://eloquentjavascript.net/3rd_edition/code/#22.3"
160178
}
161179
]
162180
});

src/client/code.mjs

+4-2
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,12 @@ class CodeSandbox {
100100
if (chapter.start_code) code += "\n\n" + chapter.start_code
101101
this.setEditorState(code, {include: chapter.include})
102102
visible = "box"
103-
} else if (value == "11.1[3]") {
104-
document.location = "https://eloquentjavascript.net/3rd_edition/code/#11.1"
105103
} else {
106104
let exercise = findExercise(value, chapter)
105+
if (exercise.goto) {
106+
document.location = exercise.goto
107+
return
108+
}
107109
this.setEditorState(exercise.code, {
108110
include: chapter.include,
109111
solution: exercise.solution,

0 commit comments

Comments
 (0)