soi-manim/binary-search/binary-search-manim.py

93 lines
2.6 KiB
Python
Raw Normal View History

from manim import *
class Sequence(VMobject):
# evenly spaced characters
def __init__(self, seq):
VMobject.__init__(self)
seq = [t.move_to(i * 0.5 * RIGHT) for i, t in enumerate(seq)]
self.add(VGroup(*seq).move_to(ORIGIN + 2*UP))
class Pointer(VMobject):
# pointer to sequence element
def __init__(self, pointee, name):
VMobject.__init__(self)
arrow = Arrow(ORIGIN, DOWN).next_to(pointee, UP)
name_tex = Tex(name).next_to(arrow, UP)
self.add(arrow, name_tex)
class ProgramCounter(VMobject):
# pointer to current code line
def __init__(self, line):
VMobject.__init__(self)
self.add(Arrow(ORIGIN, RIGHT).next_to(line, LEFT))
class Base(Scene):
def construct(self, n, k):
# initial situation
seq = [Tex("1")] + [Tex("?") for _ in range(n-2)] + [Tex("0")]
self.play(Create(Sequence(seq)))
# source code binary search
code = Code(file_name="binary-search.py", language="Python", insert_line_no=False, style='monokai')
code.move_to(DOWN)
self.play(Write(code))
line_lr, line_while, line_m, line_test, line_l, _, line_r = code[2]
def test(x):
return 1 if x <= k else 0
def update_pc(pc, line):
npc = ProgramCounter(line)
self.play(ReplacementTransform(pc, npc))
return npc
# initialize borders
pc = ProgramCounter(line_lr)
self.play(Create(pc))
l, r = 0, n-1
lp = Pointer(seq[l], "l")
rp = Pointer(seq[r], "r")
self.play(Write(lp), Create(rp))
while r - l > 1:
# calculate m
pc = update_pc(pc, line_m)
m = (l + r) // 2
mp = Pointer(seq[m], "m")
self.play(Create(mp))
# test
pc = update_pc(pc, line_test)
old = seq.copy()
seq[m] = Tex(str(test(m)))
self.play(ReplacementTransform(Sequence(old), Sequence(seq)))
if test(m):
# update left
pc = update_pc(pc, line_l)
l = m
op = lp
lp = Pointer(seq[m], "l")
self.play(Uncreate(mp), ReplacementTransform(op, lp))
else:
# update right
pc = update_pc(pc, line_r)
r = m
op = rp
rp = Pointer(seq[m], "r")
self.play(Uncreate(mp), ReplacementTransform(op, rp))
self.wait(2)
class Main(Base):
def construct(self):
Base.construct(self, 20, 6)