typstuff/misc/leetcode_trees/leetcode_trees.typ
2024-12-13 23:04:02 +01:00

97 lines
1.6 KiB
Typst

#import "@preview/cetz:0.3.1": canvas, draw
#let leetcode-tree(nodes, highlighted: ()) = {
let height = calc.ceil(
calc.log(
nodes.len() + 1,
base: 2
)
)
let dy = 1
let dx = 0.8
let r = 0.3
let width = dx * (calc.pow(2, height - 1) + 1)
for lvl in range(height) {
let n = calc.pow(2, lvl)
let y = -lvl * dy
for i in range(n) {
let j = i + n - 1
if j >= nodes.len() {
break
}
let node = nodes.at(j)
if node != none {
let x = width * (i + .5) / n
let name = "l" + str(lvl) + "-n" + str(i)
let is-highlighted = (j in highlighted) or (lvl, i) in highlighted
draw.circle(
(x, y),
radius: r,
name: name,
fill: if is-highlighted {
blue.lighten(75%)
} else {
none
}
)
draw.content(
name + ".center",
str(node)
)
if lvl != 0 {
let pi = i.bit-rshift(1)
draw.line(
"l" + str(lvl - 1) + "-n" + str(pi),
name
)
}
}
}
}
}
#set page(width: auto, height: auto, margin: 1cm)
#canvas({
leetcode-tree(
(2,1,3,none,none,none,4),
highlighted: (2,)
)
})
#pagebreak()
#canvas({
leetcode-tree(
(1,2,3,4,5,6,none,none,none,7,8)
)
})
#pagebreak()
#canvas({
leetcode-tree(
(99,3,2,none,6,4,5,none,none,none,none,8,7)
)
})
#pagebreak()
#canvas({
leetcode-tree(
(0,3,1,none,none,none,2)
)
})
#pagebreak()
#canvas({
leetcode-tree(
(0,3,1,2)
)
})