From 7d10ec940dc1bf72d14b9a40504f8254bc349c59 Mon Sep 17 00:00:00 2001 From: Varun0157 Date: Sun, 16 Nov 2025 22:44:45 +0530 Subject: [PATCH 1/6] working bin exp? --- algorithms/binary-exponentiation.typ | 125 +++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 algorithms/binary-exponentiation.typ diff --git a/algorithms/binary-exponentiation.typ b/algorithms/binary-exponentiation.typ new file mode 100644 index 0000000..7da52d5 --- /dev/null +++ b/algorithms/binary-exponentiation.typ @@ -0,0 +1,125 @@ +#import "../lib/style.typ": * +#import "../lib/mapcode.typ": * + +== Binary Exponentiation +#set math.equation(numbering: none) + +Compute $"base"^"exp"$ for a non-negative integer exponent. + +Formal definition: +$ +"pow"("base", "exp") &= cases( + 1 & "if " exp = 0, + ("pow"("base", "exp"/2))^2 & "if " "exp" " is even", + "base" * ("pow"("base", "exp"/2))^2 & "if " "exp" " is odd" +) +$ + +Examples: +- $"pow"(2, 10) -> 1024$ +- $"pow"(3, 5) -> 243$ + +*As mapcode:* + +_primitives_: `mult`($*$) is strict. + +$ I = ("base", "exp"): NN times NN quad quad quad X_"exp" &= "Map"(NN -> NN_bot) quad quad quad A = NN\ +rho("base", "exp") & = {e -> bot | e " is a required subproblem for " "exp"}\ +F(x_"exp") & = cases( + 1 & "if " e = 0, + (x_(e/2))^2 & "if " e " is even", + "base" * (x_(e/2))^2 & "if " e " is odd" + )\ + pi(x) & = x_"exp" +$ + + +#let inst_base = 2; +#let inst_exp = 10; +#figure( + caption: [Binary Exponentiation computation using mapcode for $#inst_base^#inst_exp$], +$ +#{ + let get_val = (x, key) => { + let item = x.find(p => p.at(0) == key) + if item != none { + item.at(1) + } else { + none + } + } + + let rho = ((base, exp)) => { + let keys = () + let current_exp = exp + while true { + keys.push(current_exp) + if current_exp == 0 { + break + } + current_exp = calc.floor(current_exp / 2) + } + keys.sorted().map(k => (k, none)) + } + + let F_i = ((base, exp)) => (x) => (elem) => { + let e = elem.at(0) + let val = elem.at(1) + if val != none { + return (e, val) + } + + if e == 0 { + (e, 1) + } else if calc.rem(e, 2) == 0 { + let half_e = calc.floor(e/2); + let half_val = get_val(x, half_e) + if half_val != none { + (e, half_val * half_val) + } else { + (e, none) + } + } else { + let half_e = calc.floor(e/2); + let half_val = get_val(x, half_e) + if half_val != none { + (e, base * half_val * half_val) + } else { + (e, none) + } + } + } + + let F = ((base, exp)) => (x) => { + x.map(elem => F_i((base, exp))(x)(elem)) + } + + let pi = ((base, exp)) => (x) => get_val(x, exp) + + let X_h = (x, diff_mask: none) => { + let cells = x.enumerate().map(((i, p)) => { + let key = p.at(0) + let val = p.at(1) + let val_str = if val != none {[$#val$]} else {[$bot$]} + let cell_content = [$#key -> #val_str$] + if diff_mask != none and diff_mask.at(i).at(1) { + rect(fill: yellow.transparentize(70%), inset: 2pt)[#cell_content] + } else { + rect(stroke: none, inset: 2pt)[#cell_content] + } + }) + $vec(delim: "{", ..cells)$ + } + + mapcode-viz( + rho, F((inst_base, inst_exp)), pi((inst_base, inst_exp)), + I_h: ((b,e)) => [$#b^#e$], + X_h: X_h, + pi_name: [$pi ((#inst_base, #inst_exp))$], + group-size: 2, + cell-size: 30mm, + scale-fig: 95% + )((inst_base, inst_exp)) +} +$ +) From c7278e8367f259debdfba4957c92df880e51ec61 Mon Sep 17 00:00:00 2001 From: Varun0157 Date: Sun, 16 Nov 2025 23:01:21 +0530 Subject: [PATCH 2/6] gcd typ --- algorithms/gcd.typ | 111 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 algorithms/gcd.typ diff --git a/algorithms/gcd.typ b/algorithms/gcd.typ new file mode 100644 index 0000000..41b0506 --- /dev/null +++ b/algorithms/gcd.typ @@ -0,0 +1,111 @@ +#import "../lib/style.typ": * +#import "../lib/mapcode.typ": * + +== Greatest Common Divisor (GCD) +#set math.equation(numbering: none) + +Computes the greatest common divisor of two non-negative integers using the Euclidean algorithm. + +Formal definition: +$ +"gcd"(a, b) &= cases( + a & "if " b = 0, + "gcd"(b, a mod b) & "otherwise" +) +$ + +Examples: +- $`gcd`(48, 18) -> 6$ +- $`gcd`(101, 103) -> 1$ + +*As mapcode:* + +_primitives_: `mod` (modulo operator) + +$ +I = ("a", "b"): NN times NN \ +X = "Map"(("a","b") -> NN_bot) \ +A = NN\\ +rho("a", "b") & = { ("x","y") -> bot | ("x","y") " is a pair in the GCD chain"}\ +F(x) & = cases( + "a" & "if " "b" = 0, + x_("b", "a" " mod " "b") & "otherwise" +)\ +pi(x) & = "last computed value" +$ + +#let inst_a = 48; +#let inst_b = 18; + +#figure( + caption: [GCD computation using mapcode for $`gcd`(#inst_a, #inst_b)$], +$ +#{ + let get_pairs = (a_start, b_start) => { + let pairs = () + let a = a_start + let b = b_start + while true { + pairs.push((a, b)) + if b == 0 { + break + } + let temp = b + b = calc.rem(a, b) + a = temp + } + pairs + } + + let pairs = get_pairs(inst_a, inst_b) + let num_steps = pairs.len() + + let rho = (inst) => { + let x = () + for i in range(0, num_steps) { + x.push(none) + } + x + } + + let F_i = (x) => ((i,)) => { + if i == num_steps - 1 { + // Base case: gcd(a, 0) = a + let (a, b) = pairs.at(i) + a + } else if x.at(i + 1) != none { + x.at(i + 1) + } else { + none + } + } + let F = map_tensor(F_i, dim: 1) + + let pi = (x) => x.at(0) + + let X_h = (x, diff_mask: none) => { + let cells = x.enumerate().map(((i, x_i)) => { + let (a, b) = pairs.at(i) + let val = if x_i != none {[#x_i]} else {[$bot$]} + let cell_content = [$"gcd"(#a, #b) -> #val$] + if diff_mask != none and diff_mask.at(i) { + rect(fill: yellow.transparentize(70%), inset: 2pt)[#cell_content] + } else { + rect(stroke: none, inset: 2pt)[#cell_content] + } + }) + $vec(delim: "{", ..cells)$ + } + + mapcode-viz( + rho, F, pi, + I_h: ((a,b)) => [$"gcd"(#a, #b)$], + X_h: X_h, + pi_name: [$pi$], + group-size: 2, + cell-size: 40mm, + scale-fig: 95% + )((inst_a, inst_b)) +} +$ +) From 41b9539b5a52562914cffa528e7be5ba3fbc33bf Mon Sep 17 00:00:00 2001 From: Varun0157 Date: Sun, 16 Nov 2025 23:02:47 +0530 Subject: [PATCH 3/6] fix: euclidian gcd --- algorithms/gcd.typ | 3 ++- main.typ | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/algorithms/gcd.typ b/algorithms/gcd.typ index 41b0506..e01f912 100644 --- a/algorithms/gcd.typ +++ b/algorithms/gcd.typ @@ -25,7 +25,8 @@ _primitives_: `mod` (modulo operator) $ I = ("a", "b"): NN times NN \ X = "Map"(("a","b") -> NN_bot) \ -A = NN\\ +A = NN\ +\ rho("a", "b") & = { ("x","y") -> bot | ("x","y") " is a pair in the GCD chain"}\ F(x) & = cases( "a" & "if " "b" = 0, diff --git a/main.typ b/main.typ index 9952d9b..62a79b5 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/binary-exponentiation.typ" +#pagebreak() +#include "algorithms/binary-exponentiation.typ" +#pagebreak() +#include "algorithms/gcd.typ" From aeda7655884d4e3b9eccc201d0e066046f60da84 Mon Sep 17 00:00:00 2001 From: Varun0157 Date: Sun, 16 Nov 2025 23:19:09 +0530 Subject: [PATCH 4/6] fix pi in final edge --- algorithms/binary-exponentiation.typ | 13 +++++++------ algorithms/gcd.typ | 6 +++--- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/algorithms/binary-exponentiation.typ b/algorithms/binary-exponentiation.typ index 7da52d5..08001df 100644 --- a/algorithms/binary-exponentiation.typ +++ b/algorithms/binary-exponentiation.typ @@ -94,9 +94,10 @@ $ x.map(elem => F_i((base, exp))(x)(elem)) } - let pi = ((base, exp)) => (x) => get_val(x, exp) + let pi_func = ((base, exp)) => (x) => get_val(x, exp) - let X_h = (x, diff_mask: none) => { + let X_h = (base) => (x, diff_mask: none) => { + let base_info = [$"base": #base$] let cells = x.enumerate().map(((i, p)) => { let key = p.at(0) let val = p.at(1) @@ -108,14 +109,14 @@ $ rect(stroke: none, inset: 2pt)[#cell_content] } }) - $vec(delim: "{", ..cells)$ + stack(dir: ttb, spacing: 0.5em, base_info, $vec(delim: "{", ..cells)$) } mapcode-viz( - rho, F((inst_base, inst_exp)), pi((inst_base, inst_exp)), + rho, F((inst_base, inst_exp)), pi_func((inst_base, inst_exp)), I_h: ((b,e)) => [$#b^#e$], - X_h: X_h, - pi_name: [$pi ((#inst_base, #inst_exp))$], + X_h: X_h(inst_base), + pi_name: [$pi((#inst_base, #inst_exp))$], group-size: 2, cell-size: 30mm, scale-fig: 95% diff --git a/algorithms/gcd.typ b/algorithms/gcd.typ index e01f912..dc023f4 100644 --- a/algorithms/gcd.typ +++ b/algorithms/gcd.typ @@ -82,7 +82,7 @@ $ } let F = map_tensor(F_i, dim: 1) - let pi = (x) => x.at(0) + let pi_func = (x) => x.at(0) let X_h = (x, diff_mask: none) => { let cells = x.enumerate().map(((i, x_i)) => { @@ -99,10 +99,10 @@ $ } mapcode-viz( - rho, F, pi, + rho, F, pi_func, I_h: ((a,b)) => [$"gcd"(#a, #b)$], X_h: X_h, - pi_name: [$pi$], + pi_name: [$pi((#inst_a, #inst_b))$], group-size: 2, cell-size: 40mm, scale-fig: 95% From 4619e9a4a428bb0b86bca0ff9de06cedb07864cb Mon Sep 17 00:00:00 2001 From: Varun0157 Date: Sun, 16 Nov 2025 23:25:31 +0530 Subject: [PATCH 5/6] clarify pi(x) in gcd --- algorithms/gcd.typ | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/algorithms/gcd.typ b/algorithms/gcd.typ index dc023f4..f6fd5c3 100644 --- a/algorithms/gcd.typ +++ b/algorithms/gcd.typ @@ -32,7 +32,7 @@ F(x) & = cases( "a" & "if " "b" = 0, x_("b", "a" " mod " "b") & "otherwise" )\ -pi(x) & = "last computed value" +pi(x) & = x_((a,b)) " where " b=0 $ #let inst_a = 48; From e6cf058c13eaa453561dad11e80f1d7eff8a0c47 Mon Sep 17 00:00:00 2001 From: Varun0157 Date: Mon, 17 Nov 2025 00:00:29 +0530 Subject: [PATCH 6/6] remove excess bin exp render --- main.typ | 2 -- 1 file changed, 2 deletions(-) diff --git a/main.typ b/main.typ index 62a79b5..ee6d2d1 100644 --- a/main.typ +++ b/main.typ @@ -55,6 +55,4 @@ All primitives are _strict_ meaning they do not allow for undefined values (i.e. #pagebreak() #include "algorithms/binary-exponentiation.typ" #pagebreak() -#include "algorithms/binary-exponentiation.typ" -#pagebreak() #include "algorithms/gcd.typ"