From 61511aa73d5daf2f0d3680e9b6e49ec761da9497 Mon Sep 17 00:00:00 2001 From: Manas-7854 Date: Fri, 14 Nov 2025 21:24:29 -0500 Subject: [PATCH 1/4] added exp_squaring --- algorithms/exp_squaring.typ | 103 ++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 algorithms/exp_squaring.typ diff --git a/algorithms/exp_squaring.typ b/algorithms/exp_squaring.typ new file mode 100644 index 0000000..c460812 --- /dev/null +++ b/algorithms/exp_squaring.typ @@ -0,0 +1,103 @@ +#import "../lib/style.typ": * +#import "../lib/mapcode.typ": * + +== Exponentiation by Squaring +#set math.equation(numbering: none) + +Compute $b^n$ for base $b in NN$ and exponent $n in NN_0$ using binary exponentiation. + +Formal definition: +$ +b^n = cases( + 1 & "if " n = 0, + b & "if " n = 1, + (b^(n/2))^2 & "if " n "is even", + b dot (b^(floor(n/2)))^2 & "if " n "is odd" +) +$ + +Examples: +- $"exp"(3, 5) -> 243$ +- $"exp"(2, 10) -> 1024$ + +*As mapcode:* + +_primitives_: `multiply`($*$) and `floor-divide`($div$) are strict. i.e operations on $bot$ are undefined. + +$ I = (b, n) : NN times NN_0 quad quad quad X_((b,n)) &= [0..n] -> NN_bot quad quad quad A = NN\ +rho((b,n)) & = {i -> bot | i in [0..n]}\ +F(x_k) & = cases( + 1 & "if " k = 0, + x_(floor(k/2))^2 & "if " k > 0 "and " k "is even and" x_(floor(k/2)) != bot, + b dot x_(floor(k/2))^2 & "if " k > 0 "and " k "is odd and" x_(floor(k/2)) != bot, + bot & "otherwise" + )\ + pi(x) & = x_n +$ + +#let base = 3; +#let exp = 5; +#figure( + caption: [Exponentiation by squaring computation using mapcode for $#base^#exp$], +$ +#{ + let rho = (inst) => { + let (b, n) = inst + let x = () + for i in range(0, n + 1) { + x.push(none) + } + x + } + + let F_i = (x) => ((i,)) => { + if i == 0 { + 1 + } else { + let half_idx = calc.floor(i / 2) + if x.at(half_idx) != none { + let half_val = x.at(half_idx) + let squared = half_val * half_val + if calc.rem(i, 2) == 0 { + // even: x[i/2]^2 + squared + } else { + // odd: b * x[(i-1)/2]^2 + base * squared + } + } else { + none + } + } + } + let F = map_tensor(F_i, dim: 1) + + let pi = (i) => (x) => x.at(i) + + let X_h = (x, diff_mask: none) => { + let cells = x.enumerate().map(((i, x_i)) => { + let val = if x_i != none {[$#x_i$]} else {[$bot$]} + if diff_mask != none and diff_mask.at(i) { + // changed element: highlight + rect(fill: yellow.transparentize(70%), inset: 2pt)[$#val$] + } else { + rect(stroke: none, inset: 2pt)[$#val$] + } + }) + $vec(delim: "[", ..cells)$ + } + + mapcode-viz( + rho, F, pi(exp), + X_h: X_h, + I_h: (inst) => { + let (b, n) = inst + $((#b, #n))$ + }, + pi_name: [$pi(#exp)$], + group-size: calc.min(7, exp + 1), + cell-size: 10mm, scale-fig: 85% + )((base, exp)) +} +$ +) \ No newline at end of file From e07e122f86297c0baa45274b51617a88552ca367 Mon Sep 17 00:00:00 2001 From: Manas-7854 Date: Fri, 14 Nov 2025 22:56:31 -0500 Subject: [PATCH 2/4] added digit reversal --- algorithms/digit_reversal.typ | 115 ++++++++++++++++++++++++++++++++++ main.typ | 6 ++ 2 files changed, 121 insertions(+) create mode 100644 algorithms/digit_reversal.typ diff --git a/algorithms/digit_reversal.typ b/algorithms/digit_reversal.typ new file mode 100644 index 0000000..a253918 --- /dev/null +++ b/algorithms/digit_reversal.typ @@ -0,0 +1,115 @@ +#import "../lib/style.typ": * +#import "../lib/mapcode.typ": * + +== Digit Reversal +#set math.equation(numbering: none) + +Reverse the digits of a non-negative integer $N in NN_0$ using accumulator-based recursion. + +Formal definition using helper function $R(n, a)$ where $n$ is the remaining number and $a$ is the accumulator: + +Main function: +$ +"reverse"(N) = R(N, 0) +$ + +Recursive helper: +$ +R(n, a) = cases( + a & "if " n = 0, + R(floor(n/10), (a times 10) + (n mod 10)) & "if " n > 0 +) +$ + +Examples: +- $"reverse"(123) -> 321$ +- $"reverse"(5040) -> 405$ + +*As mapcode:* + +_primitives_: `floor-divide`($div$) and `modulo`($mod$) are strict. i.e operations on $bot$ are undefined. + +$ I = (n_"in", a_"in") : NN times NN quad quad quad X &= (NN times NN) -> NN_bot quad quad quad A = NN\ +rho(n_"in", a_"in") & = {(n, a) -> bot | n, a in NN}\ +F(m)(n, a) & = cases( + a & "if " n = 0, + m[floor(n/10), (a times 10) + (n mod 10)] & "if " n > 0 "and" m[...] != bot, + bot & "otherwise" + )\ + pi(n_"in", a_"in")(m) & = m[n_"in", a_"in"] +$ + +#let number = 123; +#figure( + caption: [Digit reversal computation using mapcode for $"reverse"(#number)$], +$ +#{ + // Generate the chain of (n, a) pairs + let generate_chain = (num) => { + let chain = ((num, 0),) + let n = num + let a = 0 + while n > 0 { + let digit = calc.rem(n, 10) + n = calc.floor(n / 10) + a = a * 10 + digit + chain.push((n, a)) + } + chain + } + + let chain = generate_chain(number) + let len = chain.len() + + let rho = (inst) => { + let x = () + for i in range(0, len) { + x.push(none) + } + x + } + + let F_i = (x) => ((i,)) => { + let (n, a) = chain.at(i) + if n == 0 { + a + } else if i < len - 1 and x.at(i + 1) != none { + x.at(i + 1) + } else { + none + } + } + let F = map_tensor(F_i, dim: 1) + + let pi = (i) => (x) => x.at(i) + + let X_h = (x, diff_mask: none) => { + let cells = x.enumerate().map(((i, x_i)) => { + let (n, a) = chain.at(i) + let key_str = $((#n, #a))$ + let val = if x_i != none {[$#x_i$]} else {[$bot$]} + let entry = $#key_str -> #val$ + + if diff_mask != none and diff_mask.at(i) { + // changed element: highlight + rect(fill: yellow.transparentize(70%), inset: 2pt)[$#entry$] + } else { + rect(stroke: none, inset: 2pt)[$#entry$] + } + }) + $vec(delim: "[", ..cells)$ + } + + mapcode-viz( + rho, F, pi(0), + X_h: X_h, + I_h: (inst) => { + $((#number, 0))$ + }, + pi_name: [$pi((#number, 0))$], + group-size: calc.min(7, len), + cell-size: 20mm, scale-fig: 80% + )(number) +} +$ +) \ No newline at end of file diff --git a/main.typ b/main.typ index 9952d9b..3b52314 100644 --- a/main.typ +++ b/main.typ @@ -52,3 +52,9 @@ All primitives are _strict_ meaning they do not allow for undefined values (i.e. #include "algorithms/LongestCommonSubsequence.typ" #pagebreak() #include "algorithms/leetcode/P2_add-two-numbers.typ" +#pagebreak() +#include "algorithms/digit_reversal.typ" +#pagebreak() +#include "algorithms/exp_squaring.typ" +#pagebreak() + From 5721b68d06445364c548485d3168fa126cd27eb0 Mon Sep 17 00:00:00 2001 From: Manas-7854 Date: Sat, 15 Nov 2025 17:24:04 -0500 Subject: [PATCH 3/4] added digit reversal --- main.typ | 3 --- 1 file changed, 3 deletions(-) diff --git a/main.typ b/main.typ index 3b52314..095634a 100644 --- a/main.typ +++ b/main.typ @@ -55,6 +55,3 @@ All primitives are _strict_ meaning they do not allow for undefined values (i.e. #pagebreak() #include "algorithms/digit_reversal.typ" #pagebreak() -#include "algorithms/exp_squaring.typ" -#pagebreak() - From af00ca0dcdc03a7d9ba381a54d692dbf00036ff5 Mon Sep 17 00:00:00 2001 From: Manas-7854 Date: Sat, 15 Nov 2025 17:27:00 -0500 Subject: [PATCH 4/4] removed exp squaring --- algorithms/exp_squaring.typ | 103 ------------------------------------ 1 file changed, 103 deletions(-) delete mode 100644 algorithms/exp_squaring.typ diff --git a/algorithms/exp_squaring.typ b/algorithms/exp_squaring.typ deleted file mode 100644 index c460812..0000000 --- a/algorithms/exp_squaring.typ +++ /dev/null @@ -1,103 +0,0 @@ -#import "../lib/style.typ": * -#import "../lib/mapcode.typ": * - -== Exponentiation by Squaring -#set math.equation(numbering: none) - -Compute $b^n$ for base $b in NN$ and exponent $n in NN_0$ using binary exponentiation. - -Formal definition: -$ -b^n = cases( - 1 & "if " n = 0, - b & "if " n = 1, - (b^(n/2))^2 & "if " n "is even", - b dot (b^(floor(n/2)))^2 & "if " n "is odd" -) -$ - -Examples: -- $"exp"(3, 5) -> 243$ -- $"exp"(2, 10) -> 1024$ - -*As mapcode:* - -_primitives_: `multiply`($*$) and `floor-divide`($div$) are strict. i.e operations on $bot$ are undefined. - -$ I = (b, n) : NN times NN_0 quad quad quad X_((b,n)) &= [0..n] -> NN_bot quad quad quad A = NN\ -rho((b,n)) & = {i -> bot | i in [0..n]}\ -F(x_k) & = cases( - 1 & "if " k = 0, - x_(floor(k/2))^2 & "if " k > 0 "and " k "is even and" x_(floor(k/2)) != bot, - b dot x_(floor(k/2))^2 & "if " k > 0 "and " k "is odd and" x_(floor(k/2)) != bot, - bot & "otherwise" - )\ - pi(x) & = x_n -$ - -#let base = 3; -#let exp = 5; -#figure( - caption: [Exponentiation by squaring computation using mapcode for $#base^#exp$], -$ -#{ - let rho = (inst) => { - let (b, n) = inst - let x = () - for i in range(0, n + 1) { - x.push(none) - } - x - } - - let F_i = (x) => ((i,)) => { - if i == 0 { - 1 - } else { - let half_idx = calc.floor(i / 2) - if x.at(half_idx) != none { - let half_val = x.at(half_idx) - let squared = half_val * half_val - if calc.rem(i, 2) == 0 { - // even: x[i/2]^2 - squared - } else { - // odd: b * x[(i-1)/2]^2 - base * squared - } - } else { - none - } - } - } - let F = map_tensor(F_i, dim: 1) - - let pi = (i) => (x) => x.at(i) - - let X_h = (x, diff_mask: none) => { - let cells = x.enumerate().map(((i, x_i)) => { - let val = if x_i != none {[$#x_i$]} else {[$bot$]} - if diff_mask != none and diff_mask.at(i) { - // changed element: highlight - rect(fill: yellow.transparentize(70%), inset: 2pt)[$#val$] - } else { - rect(stroke: none, inset: 2pt)[$#val$] - } - }) - $vec(delim: "[", ..cells)$ - } - - mapcode-viz( - rho, F, pi(exp), - X_h: X_h, - I_h: (inst) => { - let (b, n) = inst - $((#b, #n))$ - }, - pi_name: [$pi(#exp)$], - group-size: calc.min(7, exp + 1), - cell-size: 10mm, scale-fig: 85% - )((base, exp)) -} -$ -) \ No newline at end of file