From 3d51778bd015c0a2f343065dc9c443d612856037 Mon Sep 17 00:00:00 2001 From: Peng-Yu Chen Date: Mon, 19 Oct 2026 21:52:36 -0400 Subject: [PATCH 1/2] Update package.json, format.mjs, main.yaml, AGENTS.md --- .github/workflows/main.yaml | 9 ++++ .gitignore | 1 + AGENTS.md | 5 +- package-lock.json | 28 +++++++++++ package.json | 11 +++++ scripts/format.mjs | 92 +++++++++++++++++++++++++++++++++++++ 6 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 scripts/format.mjs diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 220418e19c..a7f7ebaaa7 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -23,6 +23,15 @@ jobs: - run: python3 -m pip install -r requirements.txt + - uses: actions/setup-node@v4 + with: + node-version: '24' + cache: 'npm' + + - run: npm ci + + - run: npm run format:check + - run: python3 scripts/check_math.py - run: mkdocs build --strict diff --git a/.gitignore b/.gitignore index 33e315d54b..3448ee92e8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .DS_Store site/ venv/ +node_modules/ diff --git a/AGENTS.md b/AGENTS.md index 35fb39df01..4d56f1a877 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -18,15 +18,18 @@ Solutions to _Introduction to Algorithms_, Third Edition, published at https://w - Literal braces are `\\{` and `\\}`. - `_` and `*` inside `$...$` sometimes need `\_` and `\*` when Markdown turns them into emphasis. - GitHub's preview applies the same Markdown escaping inside math, so this source renders there too, apart from occasional quirks in `$$` blocks. +- List items use `- `, and anything continuing an item is indented 4 spaces; MkDocs drops 2-space continuations out of the list. `npm run format` (Prettier with math masked out) enforces this. - Inside a list item, GitHub ignores `$$`. Use a ` ```math ` fence there instead, with plain LaTeX (`\\`, `\{`), since fenced content skips Markdown. ## Verify ```sh pip install -r requirements.txt +npm ci +npm run format python3 scripts/check_math.py mkdocs build --strict mkdocs serve ``` -CI runs `scripts/check_math.py` and `mkdocs build --strict` on every pull request and deploys `main` to the `gh-pages` branch. +CI runs `npm run format:check`, `scripts/check_math.py`, and `mkdocs build --strict` on every pull request and deploys `main` to the `gh-pages` branch. diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000..240612f910 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,28 @@ +{ + "name": "fwt", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "devDependencies": { + "prettier": "3.9.10" + } + }, + "node_modules/prettier": { + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.10.tgz", + "integrity": "sha512-skGHTH1Yb9QvaTC4hWnRTzEYtCpApF0UMBPz+t/0ZPzP8ihefo/btKd+QA7pUE0fEwA1SbS/NmhyEcstdXOIdA==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000000..2ae9c67b0d --- /dev/null +++ b/package.json @@ -0,0 +1,11 @@ +{ + "private": true, + "type": "module", + "scripts": { + "format": "node scripts/format.mjs", + "format:check": "node scripts/format.mjs --check" + }, + "devDependencies": { + "prettier": "3.9.10" + } +} diff --git a/scripts/format.mjs b/scripts/format.mjs new file mode 100644 index 0000000000..b39381496a --- /dev/null +++ b/scripts/format.mjs @@ -0,0 +1,92 @@ +import { readFile, writeFile } from 'node:fs/promises'; +import { glob } from 'node:fs/promises'; +import * as prettier from 'prettier'; + +const OPTIONS = { parser: 'markdown', proseWrap: 'preserve', singleQuote: true, tabWidth: 4 }; + +// Prettier's Markdown printer does not treat every $...$ as math and rewrites +// its contents (e.g. ^* becomes ^_), so math is swapped out for opaque tokens. +function findEnd(text, delim, start) { + let braces = 0; + for (let i = start; i < text.length; i++) { + if (braces <= 0 && text.startsWith(delim, i)) return i; + const c = text[i]; + if (c === '\\') i++; + else if (c === '{') braces++; + else if (c === '}') braces--; + } + return -1; +} + +function mask(text) { + const math = []; + let out = ''; + let fence = null; + for (const line of text.split(/(?<=\n)/)) { + const m = line.match(/^[\s>]*(`{3,}|~{3,})/); + if (fence !== null || m) { + if (fence === null) fence = m[1]; + else if (m && m[1].startsWith(fence)) fence = null; + out += `\u0000${line}`; + continue; + } + out += line; + } + let result = ''; + for (let i = 0; i < out.length; i++) { + if (out[i] === '\u0000') { + const end = out.indexOf('\n', i); + result += out.slice(i + 1, end === -1 ? out.length : end + 1); + i = end === -1 ? out.length : end; + continue; + } + if (out[i] === '`') { + const run = out.slice(i).match(/^`+/)[0]; + const end = out.indexOf(run, i + run.length); + if (end !== -1) { + result += out.slice(i, end + run.length); + i = end + run.length - 1; + continue; + } + } + if (out[i] === '\\') { + result += out.slice(i, i + 2); + i++; + continue; + } + if (out[i] === '$') { + const delim = out.startsWith('$$', i) ? '$$' : '$'; + const end = findEnd(out, delim, i + delim.length); + if (end !== -1 && !out.slice(i, end).includes('\u0000')) { + math.push(out.slice(i, end + delim.length)); + result += `MATHTOKEN${math.length - 1}X`; + i = end + delim.length - 1; + continue; + } + } + result += out[i]; + } + return { masked: result, math }; +} + +const unmask = (text, math) => text.replace(/MATHTOKEN(\d+)X/g, (_, n) => math[n]); + +export async function formatMarkdown(text) { + const { masked, math } = mask(text); + return unmask(await prettier.format(masked, OPTIONS), math); +} + +const check = process.argv.includes('--check'); +let unformatted = 0; +for await (const path of glob('docs/**/*.md')) { + const text = await readFile(path, 'utf8'); + const formatted = await formatMarkdown(text); + if (formatted === text) continue; + unformatted++; + if (check) console.log(path); + else await writeFile(path, formatted); +} +if (check && unformatted) { + console.log(`${unformatted} file(s) need formatting; run npm run format`); + process.exit(1); +} From be5d05146c4f8d0c3c9d157378ea30c5bfa4857d Mon Sep 17 00:00:00 2001 From: Peng-Yu Chen Date: Mon, 19 Oct 2026 21:52:36 -0400 Subject: [PATCH 2/2] Update *.md --- docs/Chap02/2.3.md | 68 +++++++++++++++++------------------ docs/Chap04/4.3.md | 56 ++++++++++++++--------------- docs/Chap04/4.6.md | 2 +- docs/Chap06/Problems/6-1.md | 2 +- docs/Chap07/Problems/7-4.md | 3 +- docs/Chap09/Problems/9-2.md | 2 +- docs/Chap10/10.4.md | 2 +- docs/Chap11/11.4.md | 2 +- docs/Chap12/12.1.md | 10 +++--- docs/Chap13/13.1.md | 8 ++--- docs/Chap13/13.3.md | 12 +++---- docs/Chap15/15.3.md | 2 +- docs/Chap15/Problems/15-9.md | Bin 2785 -> 2774 bytes docs/Chap22/22.2.md | 4 +-- docs/Chap27/Problems/27-1.md | 2 +- docs/Chap31/31.3.md | 26 +++++++------- 16 files changed, 100 insertions(+), 101 deletions(-) diff --git a/docs/Chap02/2.3.md b/docs/Chap02/2.3.md index ce0270c64f..e92cfb1008 100755 --- a/docs/Chap02/2.3.md +++ b/docs/Chap02/2.3.md @@ -62,22 +62,22 @@ MERGE(A, p, q, r) - Base case - For $n = 2^1$, $T(n) = 2\lg 2 = 2$. + For $n = 2^1$, $T(n) = 2\lg 2 = 2$. - Suppose $n = 2^k$, $T(n) = n\lg n = 2^k \lg 2^k = 2^kk$. - For $n = 2^{k + 1}$, + For $n = 2^{k + 1}$, - ```math - \begin{aligned} - T(n) & = 2T(2^{k + 1} / 2) + 2^{k + 1} \\ - & = 2T(2^k) + 2^{k + 1} \\ - & = 2 \cdot 2^kk + 2^{k + 1} \\ - & = 2^{k + 1}(k + 1) \\ - & = 2^{k + 1} \lg 2^{k + 1} \\ - & = n\lg n. - \end{aligned} - ``` + ```math + \begin{aligned} + T(n) & = 2T(2^{k + 1} / 2) + 2^{k + 1} \\ + & = 2T(2^k) + 2^{k + 1} \\ + & = 2 \cdot 2^kk + 2^{k + 1} \\ + & = 2^{k + 1}(k + 1) \\ + & = 2^{k + 1} \lg 2^{k + 1} \\ + & = n\lg n. + \end{aligned} + ``` By P.M.I., $T(n) = n\lg n$, when $n$ is an exact power of $2$. @@ -102,31 +102,31 @@ The solution of the recurrence is $\Theta(n^2)$. - Iterative: - ```cpp - ITERATIVE-BINARY-SEARCH(A, v, low, high) - while low ≤ high - mid = floor((low + high) / 2) - if v == A[mid] - return mid - else if v > A[mid] - low = mid + 1 - else high = mid - 1 - return NIL - ``` + ```cpp + ITERATIVE-BINARY-SEARCH(A, v, low, high) + while low ≤ high + mid = floor((low + high) / 2) + if v == A[mid] + return mid + else if v > A[mid] + low = mid + 1 + else high = mid - 1 + return NIL + ``` - Recursive: - ```cpp - RECURSIVE-BINARY-SEARCH(A, v, low, high) - if low > high - return NIL - mid = floor((low + high) / 2) - if v == A[mid] - return mid - else if v > A[mid] - return RECURSIVE-BINARY-SEARCH(A, v, mid + 1, high) - else return RECURSIVE-BINARY-SEARCH(A, v, low, mid - 1) - ``` + ```cpp + RECURSIVE-BINARY-SEARCH(A, v, low, high) + if low > high + return NIL + mid = floor((low + high) / 2) + if v == A[mid] + return mid + else if v > A[mid] + return RECURSIVE-BINARY-SEARCH(A, v, mid + 1, high) + else return RECURSIVE-BINARY-SEARCH(A, v, low, mid - 1) + ``` Each time we do the comparison of $v$ with the middle element, the search range continues with range halved. diff --git a/docs/Chap04/4.3.md b/docs/Chap04/4.3.md index 810df78e88..27a5ad2bb0 100755 --- a/docs/Chap04/4.3.md +++ b/docs/Chap04/4.3.md @@ -99,37 +99,37 @@ To show $\Theta$ bound, separately show $O$ and $\Omega$ bounds. - For $O(n\lg n)$, we guess $T(n) \le c(n - 2)\lg(n - 2) - 2c$, - ```math - \begin{aligned} - T(n) & \le c(\lceil n / 2 \rceil -2 )\lg(\lceil n / 2 \rceil - 2) + c(\lfloor n / 2 \rfloor - 2)\lg(\lfloor n / 2 \rfloor - 2) + dn \\ - & \le c(n / 2 + 1 - 2)\lg(n / 2 + 1 - 2) - 2c + c(n / 2 - 2)\lg(n / 2 - 2) - 2c + dn \\ - & \le c(n / 2 - 1 )\lg(n / 2 - 1) + c(n / 2 - 1)\lg(n / 2 - 1) + dn \\ - & = c\frac{n - 2}{2}\lg\frac{n - 2}{2} + c\frac{n - 2}{2}\lg\frac{n - 2}{2} - 4c + dn \\ - & = c(n - 2)\lg\frac{n - 2}{2} - 4c + dn \\ - & = c(n - 2)\lg(n - 2) - c(n - 2) - 4c + dn \\ - & = c(n - 2)\lg(n - 2) + (d - c)n + 2c - 4c \\ - & \le c(n - 2)\lg(n - 2) - 2c, - \end{aligned} - ``` - - where the last step holds for $c > d$. + ```math + \begin{aligned} + T(n) & \le c(\lceil n / 2 \rceil -2 )\lg(\lceil n / 2 \rceil - 2) + c(\lfloor n / 2 \rfloor - 2)\lg(\lfloor n / 2 \rfloor - 2) + dn \\ + & \le c(n / 2 + 1 - 2)\lg(n / 2 + 1 - 2) - 2c + c(n / 2 - 2)\lg(n / 2 - 2) - 2c + dn \\ + & \le c(n / 2 - 1 )\lg(n / 2 - 1) + c(n / 2 - 1)\lg(n / 2 - 1) + dn \\ + & = c\frac{n - 2}{2}\lg\frac{n - 2}{2} + c\frac{n - 2}{2}\lg\frac{n - 2}{2} - 4c + dn \\ + & = c(n - 2)\lg\frac{n - 2}{2} - 4c + dn \\ + & = c(n - 2)\lg(n - 2) - c(n - 2) - 4c + dn \\ + & = c(n - 2)\lg(n - 2) + (d - c)n + 2c - 4c \\ + & \le c(n - 2)\lg(n - 2) - 2c, + \end{aligned} + ``` + + where the last step holds for $c > d$. - For $\Omega(n\lg n)$, we guess $T(n) \ge c(n + 2)\lg (n + 2) + 2c$, - ```math - \begin{aligned} - T(n) & \ge c(\lceil n / 2 \rceil +2 )\lg(\lceil n / 2 \rceil + 2) + c(\lfloor n / 2 \rfloor + 2)\lg(\lfloor n / 2 \rfloor + 2) + dn \\ - & \ge c(n / 2 + 2)\lg(n / 2 + 2) + 2c + c(n / 2 - 1 + 2)\lg(n / 2 - 1 + 2) + 2c + dn \\ - & \ge c(n / 2 + 1)\lg(n / 2 + 1) + c(n / 2 + 1)\lg(n / 2 + 1) + 4c + dn \\ - & \ge c\frac{n + 2}{2}\lg\frac{n + 2}{2} + c\frac{n + 2}{2}\lg\frac{n + 2}{2} + 4c + dn \\ - & = c(n + 2)\lg\frac{n + 2}{2} + 4c + dn \\ - & = c(n + 2)\lg(n + 2) - c(n + 2) + 4c + dn \\ - & = c(n + 2)\lg(n + 2) + (d - c)n - 2c + 4c \\ - & \ge c(n + 2)\lg(n + 2) + 2c, - \end{aligned} - ``` - - where the last step holds for $d > c$. + ```math + \begin{aligned} + T(n) & \ge c(\lceil n / 2 \rceil +2 )\lg(\lceil n / 2 \rceil + 2) + c(\lfloor n / 2 \rfloor + 2)\lg(\lfloor n / 2 \rfloor + 2) + dn \\ + & \ge c(n / 2 + 2)\lg(n / 2 + 2) + 2c + c(n / 2 - 1 + 2)\lg(n / 2 - 1 + 2) + 2c + dn \\ + & \ge c(n / 2 + 1)\lg(n / 2 + 1) + c(n / 2 + 1)\lg(n / 2 + 1) + 4c + dn \\ + & \ge c\frac{n + 2}{2}\lg\frac{n + 2}{2} + c\frac{n + 2}{2}\lg\frac{n + 2}{2} + 4c + dn \\ + & = c(n + 2)\lg\frac{n + 2}{2} + 4c + dn \\ + & = c(n + 2)\lg(n + 2) - c(n + 2) + 4c + dn \\ + & = c(n + 2)\lg(n + 2) + (d - c)n - 2c + 4c \\ + & \ge c(n + 2)\lg(n + 2) + 2c, + \end{aligned} + ``` + + where the last step holds for $d > c$. ## 4.3-6 diff --git a/docs/Chap04/4.6.md b/docs/Chap04/4.6.md index 4f9c2e5d82..27b9cb8f9c 100755 --- a/docs/Chap04/4.6.md +++ b/docs/Chap04/4.6.md @@ -2,7 +2,7 @@ > Give a simple and exact expression for $n_j$ in equation $\text{(4.27)}$ for the case in which $b$ is a positive integer instead of an arbitrary real number. -We state that $\forall{j \ge 0}, n_j = \left \lceil \frac{n}{b^j} \right \rceil$. +We state that $\forall{j \ge 0}, n_j = \left \lceil \frac{n}{b^j} \right \rceil$. Indeed, for $j = 0$ we have from the recurrence's base case that $n_0 = n = \left \lceil \frac{n}{b^0} \right \rceil$. Now, suppose $n_{j - 1} = \left \lceil \frac{n}{b^{j - 1}} \right \rceil$ for some $j > 0$. By definition, $n_j = \left \lceil \frac{n_{j - 1}}{b} \right \rceil$. diff --git a/docs/Chap06/Problems/6-1.md b/docs/Chap06/Problems/6-1.md index 69458907dd..8d1dfd88f6 100755 --- a/docs/Chap06/Problems/6-1.md +++ b/docs/Chap06/Problems/6-1.md @@ -17,4 +17,4 @@ - $\text{BUILD-MAX-HEAP}(A)$: $A = \langle 3, 2, 1 \rangle$. - $\text{BUILD-MAX-HEAP}'(A)$: $A = \langle 3, 1, 2 \rangle$. -**b.** It is very easy to find out that the $\text{MAX-HEAP-INSERT}$ operation for each iteration takes $\Theta(\log i)$ time, therefore the total time complexity is the sum of the individual complexities for $i$ from $2$ to $n$, which is : $\Theta(\log 2) + \Theta(\log 3) + \dots + \Theta(\log n) = \Theta(\log n!) $. By using Stirling's approximation, $\Theta (\log n!) \approx \Theta(n\log n)$, so the overall complexity is $\Theta(n\log⁡ n)$. +**b.** It is very easy to find out that the $\text{MAX-HEAP-INSERT}$ operation for each iteration takes $\Theta(\log i)$ time, therefore the total time complexity is the sum of the individual complexities for $i$ from $2$ to $n$, which is : $\Theta(\log 2) + \Theta(\log 3) + \dots + \Theta(\log n) = \Theta(\log n!) $. By using Stirling's approximation, $\Theta (\log n!) \approx \Theta(n\log n)$, so the overall complexity is $\Theta(n\log⁡ n)$. diff --git a/docs/Chap07/Problems/7-4.md b/docs/Chap07/Problems/7-4.md index 6c8eb15074..e071dbf04c 100755 --- a/docs/Chap07/Problems/7-4.md +++ b/docs/Chap07/Problems/7-4.md @@ -21,7 +21,6 @@ It is clear that the conditions starting the second iteration of the **while** loop in $\text{TAIL-RECURSIVE-QUICKSORT}$ are identical to the conditions starting the second recursive call in $\text{QUICKSORT}$. Therefore, $\text{TAIL-RECURSIVE-QUICKSORT}$ effectively performs the sort in the same manner as $\text{QUICKSORT}$. Therefore, $\text{TAIL-RECURSIVE-QUICKSORT}$ must correctly sort the array $A$. - **b.** The stack depth will be $\Theta(n)$ if the input array is already sorted. The right subarray will always have size $0$ so there will be $n − 1$ recursive calls before the **while**-condition $p < r$ is violated. **c.** @@ -36,4 +35,4 @@ MODIFIED-TAIL-RECURSIVE-QUICKSORT(A, p, r) else MODIFIED-TAIL-RECURSIVE-QUICKSORT(A, q + 1, r) r = q - 1 -``` \ No newline at end of file +``` diff --git a/docs/Chap09/Problems/9-2.md b/docs/Chap09/Problems/9-2.md index 589956e94a..c45cbfd82c 100755 --- a/docs/Chap09/Problems/9-2.md +++ b/docs/Chap09/Problems/9-2.md @@ -22,7 +22,7 @@ **a.** Let $m_k$ be the number of $x_i$ smaller than $x_k$. When weights of $1 / n$ are assigned to each $x_i$, we have $\sum_{x_i < x_k} w_i = m_k / n$ and $\sum_{x_i > x_k} w_i = (n - m_k - 1) / 2$. The only value of $m_k$ which makes these sums $< 1 / 2$ and $\le 1 / 2$ respectively is when $\lceil n / 2 \rceil - 1$, and this value $x$ must be the median since it has equal numbers of $x_i's$ which are larger and smaller than it. -**b.** First use mergesort to sort the $x_i$'s by value in $O(n\lg n)$ time. Let $S_i$ be the sum of the weights of the first $i$ elements of this sorted array and note that it is $O(1)$ to update $S_i$. Compute $S_1, S_2, \dots$ until you reach $k$ such that $S_{k − 1} < 1 / 2$ and $S_k \ge 1 / 2$. The weighted median is $x_k$. +**b.** First use mergesort to sort the $x_i$'s by value in $O(n\lg n)$ time. Let $S_i$ be the sum of the weights of the first $i$ elements of this sorted array and note that it is $O(1)$ to update $S_i$. Compute $S_1, S_2, \dots$ until you reach $k$ such that $S_{k − 1} < 1 / 2$ and $S_k \ge 1 / 2$. The weighted median is $x_k$. **c.** We modify $\text{SELECT}$ to do this in linear time. Let $x$ be the median of medians. Compute $\sum_{x_i < x} w_i$ and $\sum_{x_i > x} w_i$ and check if either of these is larger than $1 / 2$. If not, stop. If so, recurse on the collection of smaller or larger elements known to contain the weighted median. This doesn't change the runtime, so it is $\Theta(n)$. diff --git a/docs/Chap10/10.4.md b/docs/Chap10/10.4.md index 5040ccf852..d31f0fec5d 100755 --- a/docs/Chap10/10.4.md +++ b/docs/Chap10/10.4.md @@ -90,7 +90,7 @@ PRINT-KEY(T) else if x.right x = x.right - else + else x = x.parent else if prev == x.left and x.right != NIL prev = x diff --git a/docs/Chap11/11.4.md b/docs/Chap11/11.4.md index ed253ec750..618ca67715 100755 --- a/docs/Chap11/11.4.md +++ b/docs/Chap11/11.4.md @@ -108,7 +108,7 @@ HASH-INSERT(T, k) - successful: $\frac{1}{\frac{3}{4}} \ln\frac{1}{1-\frac{3}{4}} \approx 1.848$ probes. - $\alpha = 7 / 8$, - + - unsuccessful: $\frac{1}{1 - \frac{7}{8}} = 8$ probes, - successful: $\frac{1}{\frac{7}{8}} \ln\frac{1}{1 - \frac{7}{8}} \approx 2.377$ probes. diff --git a/docs/Chap12/12.1.md b/docs/Chap12/12.1.md index 4fcb49fbff..9c08708c98 100755 --- a/docs/Chap12/12.1.md +++ b/docs/Chap12/12.1.md @@ -4,23 +4,23 @@ - $height = 2$: - ![](../img/12.1-1-1.png) + ![](../img/12.1-1-1.png) - $height = 3$: - ![](../img/12.1-1-2.png) + ![](../img/12.1-1-2.png) - $height = 4$: - ![](../img/12.1-1-3.png) + ![](../img/12.1-1-3.png) - $height = 5$: - ![](../img/12.1-1-4.png) + ![](../img/12.1-1-4.png) - $height = 6$: - ![](../img/12.1-1-5.png) + ![](../img/12.1-1-5.png) ## 12.1-2 diff --git a/docs/Chap13/13.1.md b/docs/Chap13/13.1.md index 5bf815fab1..711562a5fa 100755 --- a/docs/Chap13/13.1.md +++ b/docs/Chap13/13.1.md @@ -4,19 +4,19 @@ - Complete binary tree of $height = 3$: - ![](../img/13.1-1-1.png) + ![](../img/13.1-1-1.png) - Red-black tree of $black\text-heights = 2$: - ![](../img/13.1-1-2.png) + ![](../img/13.1-1-2.png) - Red-black tree of $black\text-heights = 3$: - ![](../img/13.1-1-3.png) + ![](../img/13.1-1-3.png) - Red-black tree of $black\text-heights = 4$: - ![](../img/13.1-1-4.png) + ![](../img/13.1-1-4.png) ## 13.1-2 diff --git a/docs/Chap13/13.3.md b/docs/Chap13/13.3.md index d7893f3ae6..0a9e1f39c9 100755 --- a/docs/Chap13/13.3.md +++ b/docs/Chap13/13.3.md @@ -10,27 +10,27 @@ If we chose to set the color of $z$ to black then we would be violating property - insert $41$: - ![](../img/13.3-2-1.png) + ![](../img/13.3-2-1.png) - insert $38$: - ![](../img/13.3-2-2.png) + ![](../img/13.3-2-2.png) - insert $31$: - ![](../img/13.3-2-3.png) + ![](../img/13.3-2-3.png) - insert $12$: - ![](../img/13.3-2-4.png) + ![](../img/13.3-2-4.png) - insert $19$: - ![](../img/13.3-2-5.png) + ![](../img/13.3-2-5.png) - insert $8$: - ![](../img/13.3-2-6.png) + ![](../img/13.3-2-6.png) ## 13.3-3 diff --git a/docs/Chap15/15.3.md b/docs/Chap15/15.3.md index 3e5cbe55bb..3fa0286518 100755 --- a/docs/Chap15/15.3.md +++ b/docs/Chap15/15.3.md @@ -14,7 +14,7 @@ Consider the treatment of subproblems by each approach: > Draw the recursion tree for the $\text{MERGE-SORT}$ procedure from Section 2.3.1 on an array of $16$ elements. Explain why memoization fails to speed up a good divide-and-conquer algorithm such as $\text{MERGE-SORT}$. -Draw a recursion tree. +Draw a recursion tree. ![](../img/15.3-2.png) The $\text{MERGE-SORT}$ procedure performs at most a single call to any pair of indices of the array that is being sorted. In other words, the subproblems do not overlap and therefore memoization will not improve the running time. diff --git a/docs/Chap15/Problems/15-9.md b/docs/Chap15/Problems/15-9.md index 92c44d142f445fc006c9efde27fca5a60d21a21b..d3c0e77ec7afeb181dd550338bc2808ef80a13f2 100755 GIT binary patch delta 40 ucmaDTdQEi094;{*1zUw^V;uzx9R)*!Sgv3o*T{ft@;)wkR)&Ox1TFySAPOP? delta 77 zcmca6`cQPk94=P{An;MJRfsm$QLxZaFf@qe0tp2Jg^UcqOy|%L-QbWQPd|4J9~}h) V9fh3KJPjXBFtb>bD Argue that in a breadth-first search, the value $u.d$ assigned to a vertex $u$ is independent of the order in which the vertices appear in each adjacency list. Using Figure 22.3 as an example, show that the breadth-first tree computed by $\text{BFS}$ can depend on the ordering within adjacency lists. -First, we will show that the value $d$ assigned to a vertex is independent of the order that entries appear in adjacency lists. To show this, we rely on theorem 22.5, which proves correctness of $\text{BFS}$. In particular, the theorem states that $v.d = \delta(s, v)$ at the termination of $\text{BFS}$. Since $\delta(s, v)$ is a property of the underlying graph, for any adjacency list representation of the graph (including any reordering of the adjacency lists), $\delta(s, v)$ will not change. Since the $d$ values are equal to $\delta(s, v)$ and $\delta(s, v)$ is invariant for any ordering of the adjacency list, $d$ is also not dependent of the ordering of the adjacency list. +First, we will show that the value $d$ assigned to a vertex is independent of the order that entries appear in adjacency lists. To show this, we rely on theorem 22.5, which proves correctness of $\text{BFS}$. In particular, the theorem states that $v.d = \delta(s, v)$ at the termination of $\text{BFS}$. Since $\delta(s, v)$ is a property of the underlying graph, for any adjacency list representation of the graph (including any reordering of the adjacency lists), $\delta(s, v)$ will not change. Since the $d$ values are equal to $\delta(s, v)$ and $\delta(s, v)$ is invariant for any ordering of the adjacency list, $d$ is also not dependent of the ordering of the adjacency list. Now, to show that $\pi$ does depend on the ordering of the adjacency lists, we will be using Figure 22.3 as a guide. diff --git a/docs/Chap27/Problems/27-1.md b/docs/Chap27/Problems/27-1.md index 59230e3205..f363df3735 100755 --- a/docs/Chap27/Problems/27-1.md +++ b/docs/Chap27/Problems/27-1.md @@ -47,7 +47,7 @@ SUM-ARRAYS(A, B, C) **c.** Let $g$ be the grainsize. The runtime of the function that spawns all the other functions is $\left\lceil \frac{n}{g} \right\rceil$. The runtime of any particular spawned task is $g$. So, we want to minimize $$\frac{n}{g} + g.$$ - + To do this we pull out our freshman calculus hat and take a derivative, we have $$0 = 1 − \frac{n}{g^2}.$$ diff --git a/docs/Chap31/31.3.md b/docs/Chap31/31.3.md index 1c703edb0e..46949901c0 100755 --- a/docs/Chap31/31.3.md +++ b/docs/Chap31/31.3.md @@ -4,21 +4,21 @@ $\mathbb Z_4$ -| | 0 | 1 | 2 | 3 | -|---|---|---|---|---| -| 0 | 0 | 1 | 2 | 3 | -| 1 | 1 | 2 | 3 | 0 | -| 2 | 2 | 3 | 0 | 1 | -| 3 | 3 | 0 | 1 | 2 | +| | 0 | 1 | 2 | 3 | +| --- | --- | --- | --- | --- | +| 0 | 0 | 1 | 2 | 3 | +| 1 | 1 | 2 | 3 | 0 | +| 2 | 2 | 3 | 0 | 1 | +| 3 | 3 | 0 | 1 | 2 | $\mathbb Z_5^*$ -| | 1 | 2 | 3 | 4 | -|---|---|---|---|---| -| 1 | 1 | 2 | 3 | 4 | -| 2 | 2 | 4 | 1 | 3 | -| 3 | 3 | 1 | 4 | 2 | -| 4 | 4 | 3 | 2 | 1 | +| | 1 | 2 | 3 | 4 | +| --- | --- | --- | --- | --- | +| 1 | 1 | 2 | 3 | 4 | +| 2 | 2 | 4 | 1 | 3 | +| 3 | 3 | 1 | 4 | 2 | +| 4 | 4 | 3 | 2 | 1 | Define isomorphism $\alpha : \mathbb Z_4 \to \mathbb Z_5^*$ by $\alpha(x) = 2^{x}$. @@ -32,7 +32,7 @@ By Lagrange's Theorem, any subgroup of $\mathbb Z_9$ must be of order $1, 3, 9$. - $\\{ 1 \\} \cong \mathbb Z_1$ - $\\{3, 6, 9\\} \cong \mathbb Z_3$ -- $\mathbb Z_9$ (not isomorphic to $\mathbb Z_3^2$) +- $\mathbb Z_9$ (not isomorphic to $\mathbb Z_3^2$) Observe $\mathbb Z_{13}^\*$ consists of units $\\{1, \dots, 12\\}$ and is generated by $2$, i.e. $\mathbb Z_{13}^\* = \langle 2 \rangle$. The generators are thus $\langle 2^n \rangle$ for $n | 12$