From 271e1500774e8e5a05ea21ca9c79288da82f3870 Mon Sep 17 00:00:00 2001 From: bibin Date: Mon, 5 Jul 2021 15:24:31 +0200 Subject: [PATCH] add early version of binary search animation --- binary-search/binary-search-manim.py | 92 ++++++++++++++++++++++++++++ binary-search/binary-search.py | 7 +++ 2 files changed, 99 insertions(+) create mode 100644 binary-search/binary-search-manim.py create mode 100644 binary-search/binary-search.py diff --git a/binary-search/binary-search-manim.py b/binary-search/binary-search-manim.py new file mode 100644 index 0000000..8477117 --- /dev/null +++ b/binary-search/binary-search-manim.py @@ -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) diff --git a/binary-search/binary-search.py b/binary-search/binary-search.py new file mode 100644 index 0000000..937361e --- /dev/null +++ b/binary-search/binary-search.py @@ -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