From 03c691a869c488677afaf3d4457cdb5e6d15a4d3 Mon Sep 17 00:00:00 2001 From: Adam Djellouli <37275728+djeada@users.noreply.github.com> Date: Sat, 13 Sep 2025 14:23:59 +0200 Subject: [PATCH 1/7] Enhance matrices.md with formulas and pseudocode --- notes/matrices.md | 468 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 463 insertions(+), 5 deletions(-) diff --git a/notes/matrices.md b/notes/matrices.md index 289616f..84989dd 100644 --- a/notes/matrices.md +++ b/notes/matrices.md @@ -129,6 +129,21 @@ A^{\mathsf{T}} = \end{bmatrix} $$ +**Mathematical formula (3×3)** + +$$ +(A^{\mathsf T})_{r,c}=A_{c,r},\quad 0\le r,c<3. +$$ + +**Pseudocode (square, in-place)** + +``` +n = 3 # for this example; generalize to n = size +for r in 0..n-1: + for c in r+1..n-1: + swap A[r][c], A[c][r] +``` + *Example 2 (rectangular)* $$ @@ -150,6 +165,22 @@ A^{\mathsf{T}} = \begin{bmatrix} \ (3 \times 2) $$ +**Mathematical formula (2×3 → 3×2)** + +$$ +(A^{\mathsf T})_{r,c}=A_{c,r},\quad 0\le r<3,\ 0\le c<2. +$$ + +**Pseudocode (rectangular, new matrix)** + +``` +R, C = 2, 3 +B = zeros(C, R) +for r in 0..R-1: + for c in 0..C-1: + B[c][r] = A[r][c] +``` + **How it works** Iterate pairs once and swap. For square matrices, can be in-place by visiting only $c>r$. @@ -179,6 +210,21 @@ $$ \end{bmatrix} $$ +**Mathematical formula (2×3)** + +$$ +B_{r,c}=A_{r,\ C-1-c},\quad 0\le r<2,\ 0\le c<3. +$$ + +**Pseudocode (in-place)** + +``` +R, C = 2, 3 +for r in 0..R-1: + for c in 0..(C//2 - 1): + swap A[r][c], A[r][C-1-c] +``` + * Time: $O(R\cdot C)$ * Space: $O(1)$ @@ -206,6 +252,21 @@ $$ \end{bmatrix} $$ +**Mathematical formula (3×3)** + +$$ +B_{r,c}=A_{R-1-r,\ c},\quad 0\le r,c<3. +$$ + +**Pseudocode (in-place)** + +``` +R, C = 3, 3 +for r in 0..(R//2 - 1): + for c in 0..C-1: + swap A[r][c], A[R-1-r][c] +``` + * Time: $O(R\cdot C)$ * Space: $O(1)$ @@ -237,6 +298,26 @@ $$ \end{bmatrix} $$ +**Mathematical formula (n×n)** + +$$ +B_{r,c}=A_{n-1-c,\ r},\quad 0\le r,c top + A[first][i] = A[last - offset][first] + + # bottom -> left + A[last - offset][first] = A[last][last - offset] + + # right -> bottom + A[last][last - offset] = A[i][last] + + # top (saved) -> right + A[i][last] = tmp +``` + * Time: $O(n^{2})$ * Space: $O(1)$ @@ -365,11 +581,61 @@ $$ \text{Output sequence: } 1,2,3,4,8,12,11,10,9,5,6,7 $$ +**Mathematical formulation (general $R\times C$)** + +Let the matrix indices be $(r,c)$ with $0\le rt$): $(b,c)$ for $c=rgt-1,\ldots,\ellft$ (decreasing). +* Left edge (if $rgt>\ellft$): $(r,\ellft)$ for $r=b-1,\ldots,t+1$ (decreasing). + +Concatenate these per layer until all elements are visited. + +**Pseudocode (loops)** + +``` +R, C = dims(A) +top, bottom = 0, R - 1 +left, right = 0, C - 1 +out = [] + +while top <= bottom and left <= right: + # top row + for c in left..right: + out.append(A[top][c]) + top += 1 + + # right column + for r in top..bottom: + out.append(A[r][right]) + right -= 1 + + # bottom row (if any) + if top <= bottom: + for c in right..left step -1: + out.append(A[bottom][c]) + bottom -= 1 + + # left column (if any) + if left <= right: + for r in bottom..top step -1: + out.append(A[r][left]) + left += 1 +``` + **How it works** Maintain top, bottom, left, right. Walk edges in order; after each edge, move the corresponding bound inward. -* Time: $O(R\cdot C)$; Space: $O(1)$ beyond output. +* Time: $O(R\cdot C)$ +* Space: $O(1)$ beyond output #### Diagonal Order (r+c layers) @@ -389,7 +655,51 @@ d & e & f \text{One order: } a, b, d, e, c, f $$ -* Time: $O(R\cdot C)$; Space: $O(1)$. +**Mathematical formulation (general $R\times C$)** + +Let $s=r+c$. For $s=0,1,\dots,R+C-2$, define + +$$ +r_{\min}(s)=\max\!\big(0,\ s-(C-1)\big),\qquad +r_{\max}(s)=\min\!\big(R-1,\ s\big). +$$ + +The diagonal set is $\{(r,,s-r)\mid r_{\min}(s)\le r\le r_{\max}(s)\}$. +Traverse with alternating direction: + +$$ +\begin{cases} +\text{if } s \text{ even: } r=r_{\max}(s), r_{\max}(s)-1,\dots,r_{\min}(s);\ [2pt] +\text{if } s \text{ odd: } r=r_{\min}(s), r_{\min}(s)+1,\dots,r_{\max}(s). +\end{cases} +$$ + +(This parity choice reproduces the example order $a,b,d,e,c,f$ for $R=2,C=3$.) + +**Pseudocode (loops, alternating direction)** + +``` +R, C = dims(A) +out = [] + +for s in 0..(R + C - 2): + r_lo = max(0, s - (C - 1)) + r_hi = min(R - 1, s) + + if s % 2 == 0: + # even s: go downward-left (decreasing r) + for r in r_hi..r_lo step -1: + c = s - r + out.append(A[r][c]) + else: + # odd s: go upward-right (increasing r) + for r in r_lo..r_hi: + c = s - r + out.append(A[r][c]) +``` + +* Time: $O(R\cdot C)$ +* Space: $O(1)$ ### Grids as Graphs @@ -509,11 +819,66 @@ A & D & E & E \text{Output: true} $$ +**Mathematical formulation (general)** + +Let the word be $W=W_0W_1\cdots W_{L-1}$ and the grid be $G\in\Sigma^{R\times C}$. +We seek a path $P=\big((r_0,c_0),\ldots,(r_{L-1},c_{L-1})\big)$ such that + +$$ +\begin{aligned} +&\text{(match)} && G_{r_i,c_i}=W_i,\quad i=0,\ldots,L-1;\\ +&\text{(adjacent)} && |r_{i+1}-r_i|+|c_{i+1}-c_i|=1,\quad i=0,\ldots,L-2;\\ +&\text{(no reuse)} && (r_i,c_i)\neq(r_j,c_j)\ \text{for all }i\ne j. +\end{aligned} +$$ + +**Instantiation for the example (one valid path)** + +$$ +P=\big((0,0),(0,1),(0,2),(1,2),(2,2),(2,1)\big) +$$ + +gives $A\to B\to C\to C\to E\to D = \text{"ABCCED"}$. + +**Pseudocode (DFS with loops over starts and 4-neighbors)** + +``` +R, C = dims(board) +L = len(word) +visited = array(R, C, fill=false) +dr = [1, -1, 0, 0] +dc = [0, 0, 1, -1] + +def dfs(r, c, i): + if r < 0 or r >= R or c < 0 or c >= C: + return false + if visited[r][c] or board[r][c] != word[i]: + return false + if i == L - 1: + return true + + visited[r][c] = true + for k in 0..3: + nr = r + dr[k] + nc = c + dc[k] + if dfs(nr, nc, i + 1): + return true + visited[r][c] = false + return false + +# try every starting cell +for r in 0..R-1: + for c in 0..C-1: + if dfs(r, c, 0): + return true +return false +``` + **How it works** From each starting match, DFS to next char; mark visited (temporarily), backtrack on failure. -* Time: up to $O(R\cdot C\cdot b^{L})$ (branching $b\in[3,4]$, word length $L$) +* Time: up to $O(R\cdot C\cdot b^{L})$ (branching $b\in [3,4]$, word length $L$) * Space: $O(L)$ Pruning: early letter mismatch; frequency precheck; prefix trie when searching many words. @@ -522,9 +887,102 @@ Pruning: early letter mismatch; frequency precheck; prefix trie when searching m Place words to slots with crossings; verify consistency at intersections. +**Mathematical formulation** + +Let $S$ be the set of slots (across/down). Each slot $s\in S$ has a length $\ell(s)$ and ordered cell coordinates +$\mathrm{cells}(s) = \big((r_0,c_0),\ldots,(r_{\ell(s)-1},c_{\ell(s)-1})\big)$. +Let $D$ be the dictionary; define $D_\ell=\{w\in D:,|w|=\ell\}$. +Known letters from the grid induce a pattern constraint $P_s\in(\Sigma\cup\{_\})^{\ell(s)}$. + +Find an assignment $f:S\to D$ such that, for all $s\in S$, + +$$ +f(s)\in D_{\ell(s)}\quad\text{and}\quad +\forall i\ (P_s[i]\neq _ \Rightarrow f(s)[i]=P_s[i]), +$$ + +and for every intersection between slots $s$ at index $i$ and $t$ at index $j$, + +$$ +f(s)[i]=f(t)[j]. +$$ + +(Optionally enforce all-different: $s\neq t \Rightarrow f(s)\neq f(t)$.) + +**Pseudocode (backtracking with loops, MRV + trie filtering)** + +``` +# Preprocess +slots = extract_slots(grid) # with cells(s) and pattern P_s +trie = build_trie(dictionary) # for prefix/length checks + +# Build initial domains from patterns and lengths +domains = dict() +for s in slots: + domains[s] = { w in dictionary | len(w) == len(s) and matches_pattern(w, P_s) } + +# Order slots: Most-Restricted-Variable (smallest domain first) +slots.sort_by(|domains[s]| ascending, tiebreak by number_of_intersections) + +used = set() # if words must be unique +assignment = dict() + +def consistent(s, w): + # check crossings vs assigned neighbors + for each intersection (s,i) with (t,j): + if t in assignment and assignment[t][j] != w[i]: + return false + return true + +def forward_check_update_domains(s, w, removed): + # reduce neighbor domains by letter constraints from placing w at s + for each intersection (s,i) with (t,j): + for each v in copy(domains[t]): + if v[j] != w[i]: + domains[t].remove(v); removed.append((t, v)) + +def undo_forward_check(removed): + for (t, v) in removed: + domains[t].add(v) + +def backtrack(idx): + if idx == len(slots): + return true + + s = slots[idx] + + # iterate candidates; optionally skip ones already used + for w in iterate(domains[s]): + if w in used: + continue + if not consistent(s, w): + continue + + assignment[s] = w + used.add(w) + removed = [] + forward_check_update_domains(s, w, removed) + + if backtrack(idx + 1): + return true + + undo_forward_check(removed) + used.remove(w) + del assignment[s] + + return false + +# Start search +if backtrack(0): + return assignment # filled crossword +else: + return failure +``` + **How it works** Backtrack over slot assignments; use a trie for prefix feasibility; order by most constrained slot first. -* Time: exponential in slots; strong pruning and good heuristics are crucial. +* Time: exponential in slots; strong pruning and good heuristics important. + From e3d5c556c4cbe8e58a3485c66a7effafca45cae1 Mon Sep 17 00:00:00 2001 From: Adam Djellouli <37275728+djeada@users.noreply.github.com> Date: Sat, 13 Sep 2025 14:26:54 +0200 Subject: [PATCH 2/7] Update notes/matrices.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- notes/matrices.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notes/matrices.md b/notes/matrices.md index 84989dd..7e05499 100644 --- a/notes/matrices.md +++ b/notes/matrices.md @@ -664,7 +664,7 @@ r_{\min}(s)=\max\!\big(0,\ s-(C-1)\big),\qquad r_{\max}(s)=\min\!\big(R-1,\ s\big). $$ -The diagonal set is $\{(r,,s-r)\mid r_{\min}(s)\le r\le r_{\max}(s)\}$. +The diagonal set is $\{(r,s-r)\mid r_{\min}(s)\le r\le r_{\max}(s)\}$. Traverse with alternating direction: $$ From 873c32a2dc96f108ce212187a9b2c199eca28214 Mon Sep 17 00:00:00 2001 From: Adam Djellouli <37275728+djeada@users.noreply.github.com> Date: Sat, 13 Sep 2025 14:27:00 +0200 Subject: [PATCH 3/7] Update notes/matrices.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- notes/matrices.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notes/matrices.md b/notes/matrices.md index 7e05499..515cdaf 100644 --- a/notes/matrices.md +++ b/notes/matrices.md @@ -891,7 +891,7 @@ Place words to slots with crossings; verify consistency at intersections. Let $S$ be the set of slots (across/down). Each slot $s\in S$ has a length $\ell(s)$ and ordered cell coordinates $\mathrm{cells}(s) = \big((r_0,c_0),\ldots,(r_{\ell(s)-1},c_{\ell(s)-1})\big)$. -Let $D$ be the dictionary; define $D_\ell=\{w\in D:,|w|=\ell\}$. +Let $D$ be the dictionary; define $D_\ell=\{w\in D:|w|=\ell\}$. Known letters from the grid induce a pattern constraint $P_s\in(\Sigma\cup\{_\})^{\ell(s)}$. Find an assignment $f:S\to D$ such that, for all $s\in S$, From 060e1b6128fe5eb12193983d3d0fe6e29c380708 Mon Sep 17 00:00:00 2001 From: Adam Djellouli <37275728+djeada@users.noreply.github.com> Date: Sat, 13 Sep 2025 14:27:07 +0200 Subject: [PATCH 4/7] Update notes/matrices.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- notes/matrices.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/notes/matrices.md b/notes/matrices.md index 515cdaf..94a8ba7 100644 --- a/notes/matrices.md +++ b/notes/matrices.md @@ -586,15 +586,15 @@ $$ Let the matrix indices be $(r,c)$ with $0\le rt$): $(b,c)$ for $c=rgt-1,\ldots,\ellft$ (decreasing). -* Left edge (if $rgt>\ellft$): $(r,\ellft)$ for $r=b-1,\ldots,t+1$ (decreasing). +* Bottom edge (if $b>t$): $(b,c)$ for $c=rgt-1,\ldots,left$ (decreasing). +* Left edge (if $rgt>left$): $(r,left)$ for $r=b-1,\ldots,t+1$ (decreasing). Concatenate these per layer until all elements are visited. From 87ffe6a4a6fb00a165fd2510b450a48156f675db Mon Sep 17 00:00:00 2001 From: Adam Djellouli <37275728+djeada@users.noreply.github.com> Date: Sat, 13 Sep 2025 17:47:08 +0200 Subject: [PATCH 5/7] Update notes/matrices.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- notes/matrices.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notes/matrices.md b/notes/matrices.md index 94a8ba7..51f23e3 100644 --- a/notes/matrices.md +++ b/notes/matrices.md @@ -635,7 +635,7 @@ while top <= bottom and left <= right: Maintain top, bottom, left, right. Walk edges in order; after each edge, move the corresponding bound inward. * Time: $O(R\cdot C)$ -* Space: $O(1)$ beyond output +* Space: $O(1)$ beyond output. #### Diagonal Order (r+c layers) From b99dbe022cdc1f26172c3d30ebecffc5f1cb768e Mon Sep 17 00:00:00 2001 From: Adam Djellouli <37275728+djeada@users.noreply.github.com> Date: Sat, 13 Sep 2025 17:47:16 +0200 Subject: [PATCH 6/7] Update notes/matrices.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- notes/matrices.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notes/matrices.md b/notes/matrices.md index 51f23e3..ab6b43f 100644 --- a/notes/matrices.md +++ b/notes/matrices.md @@ -669,7 +669,7 @@ Traverse with alternating direction: $$ \begin{cases} -\text{if } s \text{ even: } r=r_{\max}(s), r_{\max}(s)-1,\dots,r_{\min}(s);\ [2pt] +\text{if } s \text{ even: } r=r_{\max}(s), r_{\max}(s)-1,\dots,r_{\min}(s);\\[2pt] \text{if } s \text{ odd: } r=r_{\min}(s), r_{\min}(s)+1,\dots,r_{\max}(s). \end{cases} $$ From ecfd7a67bc2c780ef70f9a67de0dbca2cfede6a1 Mon Sep 17 00:00:00 2001 From: Adam Djellouli <37275728+djeada@users.noreply.github.com> Date: Sat, 13 Sep 2025 17:47:23 +0200 Subject: [PATCH 7/7] Update notes/matrices.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- notes/matrices.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notes/matrices.md b/notes/matrices.md index ab6b43f..69583c1 100644 --- a/notes/matrices.md +++ b/notes/matrices.md @@ -983,6 +983,6 @@ else: Backtrack over slot assignments; use a trie for prefix feasibility; order by most constrained slot first. -* Time: exponential in slots; strong pruning and good heuristics important. +* Time: exponential in slots; strong pruning and good heuristics are important.