add early version of binary search animation
This commit is contained in:
parent
0b983516c9
commit
271e150077
|
@ -0,0 +1,92 @@
|
|||
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)
|
|
@ -0,0 +1,7 @@
|
|||
l, r = 0, n-1
|
||||
while r - l > 1:
|
||||
m = (l + r) / 2
|
||||
if test(m):
|
||||
l = m
|
||||
else:
|
||||
r = m
|
Loading…
Reference in New Issue