def construct(self): term_en = CyrTex(r"Dynamic Programming").scale(2) #term_bg = CyrTex(r"\foreignlanguage{bulgarian}{\textit{Динамично програмиране}}").scale(1.5) group = VGroup(term_en) self.play(FadeIn(term_en)) #term_bg.next_to(term_en, direction=DOWN) self.wait(2) #self.play(FadeIn(term_bg), group.center) self.wait(5) self.play(FadeOut(group)) photo = ImageMobject("Richard_Ernest_Bellman.jpg").set_height(6) title_below = CyrTex( r"\foreignlanguage{english}{Richard Ernest Bellman}") group2 = Group(photo, title_below) self.play(FadeIn(photo), photo.to_edge, UP) title_below.next_to(photo, direction=DOWN) self.play(Write(title_below, run_time=1)) self.wait(5) self.play(FadeOut(group2)) self.wait(5) for x, y in random_points: print(f"[{x}, {y}]") coin = Coin("10").move_to(np.array((x, y, 0))).shift_onto_screen() self.add(coin) self.wait(5) new_coin = Coin("10").move_to(np.array((2, -2, 0))) self.play(FadeIn(new_coin)) self.wait(10)
def construct(self): term_en = CyrTex(r"Brute Force").scale(2) term_bg = CyrTex( r"\foreignlanguage{bulgarian}{\textit{Метод на грубата сила}}" ).scale(1.5) group = VGroup(term_bg, term_en) self.play(FadeIn(term_en)) term_bg.next_to(term_en, direction=DOWN) self.wait() self.play(FadeIn(term_bg), group.center) self.wait(2) self.play(FadeOut(group))
def construct(self): term_en = CyrTex(r"Optimal Substructure").scale(2) term_bg = CyrTex( r"\foreignlanguage{bulgarian}{\textit{Оптимална подструктура}}" ).scale(1.5) group = VGroup(term_bg, term_en) self.play(FadeIn(term_en)) term_bg.next_to(term_en, direction=DOWN) self.wait() self.play(FadeIn(term_bg), group.center) self.wait(5) self.play(FadeOut(group)) self.wait(10)
def construct(self): amount_main = CyrTex(r'\foreignlanguage{bulgarian}{1,42 лева}').scale( 3) self.play(Write(amount_main)) self.wait() amount_cents = CyrTex( r'\foreignlanguage{bulgarian}{142 стотинки}').scale(3) self.play(FadeOutAndShift(amount_main, UP), FadeInFrom(amount_cents, DOWN)) self.wait() all_coins = Group() all_coins.add(Coin(1)) all_coins.add(Coin(2)) all_coins.add(Coin(5)) all_coins.add(Coin(10)) all_coins.add(Coin(20)) all_coins.add(Coin(50)) all_coins.arrange() self.add(all_coins) all_coins.next_to(amount_cents, DOWN, buff=LARGE_BUFF) amount_cents_small = CyrTex( r'\foreignlanguage{bulgarian}{142 ст.} =').scale(2) amount_cents_small.shift(amount_cents_small.get_width() * LEFT + UP) self.play(amount_cents.shift, amount_cents_small.get_width() * LEFT + UP, ReplacementTransform(amount_cents, amount_cents_small), all_coins.to_edge, DOWN) brace = MathTex(r'\underbrace{\qquad\qquad\qquad\qquad}').scale( 1).rotate(-PI / 2) brace.next_to(amount_cents_small, RIGHT) self.play(FadeIn(brace)) cents50 = all_coins[5] cents20 = all_coins[4] cents2 = all_coins[1] buff = DEFAULT_MOBJECT_TO_MOBJECT_BUFFER cents50_1 = cents50.copy() edge = brace.get_critical_point(RIGHT) + RIGHT * 0.75 up = (cents50_1.get_height() + buff) * UP down = (cents50_1.get_height() + buff) * DOWN self.play(cents50_1.move_to, edge + up) cents50_2 = cents50.copy() self.play(cents50_2.next_to, cents50_1) cents20_1 = cents20.copy() self.play(cents20_1.move_to, edge) cents20_2 = cents20.copy() self.play(cents20_2.next_to, cents20_1) cents2_1 = cents2.copy() self.play(cents2_1.move_to, edge + down) self.wait() self.wait(10)
def construct(self): term_en = CyrTex(r"Greedy Algorithm").scale(2) term_bg = CyrTex( r"\foreignlanguage{bulgarian}{\textit{Алчен алгоритъм}}").scale( 1.5) group = VGroup(term_bg, term_en) self.play(FadeIn(term_en)) term_bg.next_to(term_en, direction=DOWN) self.wait() self.play(FadeIn(term_bg), group.center) self.wait(5) self.play(FadeOut(group)) self.wait(10)
def construct(self): term_en = CyrTex(r"Greedy Algorithm").scale(2) group = VGroup(term_en) self.play(FadeIn(term_en)) #term_bg.next_to(term_en, direction=DOWN) self.wait(2) #self.play(FadeIn(term_bg), group.center) self.wait(5) self.play(FadeOut(group)) self.wait(10)
def construct(self): amount_cents_small = CyrTex( r'\foreignlanguage{bulgarian}{142 ¢} $=$').scale(2) amount_cents_small.shift(amount_cents_small.get_width() * LEFT + UP * 0.5) self.add(amount_cents_small) mo_group = Group() for loop in range(1): for group in groups: self.remove(mo_group) # self.play(FadeOut(mo_group, run_time=0.05)) mo_group = Group() uniq, counts = numpy.unique(group, return_counts=True) print(uniq) first = None for coin, count in zip(uniq, counts): print(f"{count} x {coin}") mo_coins = [Coin(coin) for _ in range(count)] mo_group.add(*mo_coins) if first: mo_coins[0].next_to(first, DOWN) first = mo_coins[0] for prev, cur in zip(mo_coins, mo_coins[1:]): cur.next_to(prev, RIGHT) brace = Brace(mo_group, direction=LEFT) brace2 = BraceLabel(mo_group, r'\foreignlanguage{english}{$' + str(len(group)) + "$ coins}", label_constructor=CyrTex) mo_group.add(brace, brace2) mo_group.shift( amount_cents_small.get_critical_point(RIGHT) - brace.get_tip() + X_AXIS * DEFAULT_MOBJECT_TO_MOBJECT_BUFFER) self.add(mo_group) # self.play(FadeIn(mo_group, run_time=0.05)) self.wait(0.2) self.wait() self.play(FadeOut(amount_cents_small), FadeOut(mo_group)) self.wait(10)
def construct(self): title = CyrTex(r'Min Coin Change', color="#83d126").scale(3) self.play(Write(title)) #sub_title = CyrTex(r'\foreignlanguage{bulgarian}{Ресто с най-малък брой монети}').scale(1.5) #self.play(title.shift, UP * sub_title.get_height()) #sub_title.next_to(title, DOWN, buff=SMALL_BUFF) #self.play(Write(sub_title)) self.wait() channel_name = CyrTex( r'\foreignlanguage{english}{\textbf{Svilen Talks About Programming}}', color=TEAL_E) episode_num = CyrTex(r'\foreignlanguage{english}{Episode №2}', color=TEAL_E).scale(0.8) episode_num.next_to(channel_name, DOWN, buff=SMALL_BUFF) v_group = VGroup(channel_name, episode_num) v_group.to_edge(DOWN) self.play(Write(v_group)) self.wait(10)
def construct(self): title = CyrTex(r'Min Coin Change', color=LIGHT_PINK).scale(3) self.play(Write(title)) sub_title = CyrTex( r'\foreignlanguage{bulgarian}{Ресто с най-малък брой монети}' ).scale(1.5) self.play(title.shift, UP * sub_title.get_height()) sub_title.next_to(title, DOWN, buff=SMALL_BUFF) self.play(Write(sub_title)) channel_name = CyrTex( r'\foreignlanguage{bulgarian}{\textbf{Свилен говори за програмиране}}', color=TEAL_E) episode_num = CyrTex(r'\foreignlanguage{bulgarian}{Епизод №2}', color=TEAL_E).scale(0.8) episode_num.next_to(channel_name, DOWN, buff=SMALL_BUFF) v_group = VGroup(channel_name, episode_num) v_group.to_edge(DOWN) self.play(Write(v_group)) self.wait(10)
def __init__(self, **kwargs): super().__init__(**kwargs) self.coin1 = Coin(1) self.coin2 = Coin(2) self.coin5 = Coin(5) self.coins = [self.coin1, self.coin2, self.coin5] self.mins = [MinCount(i) for i in range(10)] self.eq = CyrTex('$=$') self.plus = CyrTex('$+$') self.min_word = CyrTex('$min$') self.cdots = CyrTex(r'$\cdots$') self.zero = CyrTex('$0$') self.question_mark = CyrTex('?') self.same_min = [[] for _ in self.mins] self.iteration_groups = []
class Algo(MovingCameraScene): def __init__(self, **kwargs): super().__init__(**kwargs) self.coin1 = Coin(1) self.coin2 = Coin(2) self.coin5 = Coin(5) self.coins = [self.coin1, self.coin2, self.coin5] self.mins = [MinCount(i) for i in range(10)] self.eq = CyrTex('$=$') self.plus = CyrTex('$+$') self.min_word = CyrTex('$min$') self.cdots = CyrTex(r'$\cdots$') self.zero = CyrTex('$0$') self.question_mark = CyrTex('?') self.same_min = [[] for _ in self.mins] self.iteration_groups = [] def to_edge(self, direction, buff=DEFAULT_MOBJECT_TO_EDGE_BUFFER): def update_function(mob): """ Direction just needs to be a vector pointing towards side or corner in the 2d plane. """ print(self.camera_frame.get_center()) target_point = self.camera_frame.get_center( ) + np.sign(direction) * (np.array( (self.camera_frame.get_width() / 2, self.camera_frame.get_height() / 2, 0))) point_to_align = mob.get_critical_point(direction) shift_val = target_point - point_to_align - buff * np.array( direction) mob.shift(shift_val) return update_function def construct(self): coin_group = Group(*self.coins) coin_group.arrange() coin_group.add_updater(self.to_edge(DOWN)) self.play(FadeIn(coin_group)) self.wait() mobject9 = self.mins[9].copy() self.same_min[9].append(mobject9) self.play(FadeIn(mobject9)) self.wait() target = self.animate_question_mark(mobject9, first=True) self.wait() group9 = self.animate_min(target, [8, 7, 4]) self.play(*group9.shift_into_focus(self, 0)) min8eq = self.animate_question_mark(group9.lines[0]) group8 = self.animate_min(min8eq, [7, 6, 3]) self.play(*group9.space_out(), self.camera_frame.scale, 2) self.play(self.camera_frame.scale, 0.5, *group9.shift_into_focus(self, 1)) self.wait() min7eq = self.animate_question_mark(group9.lines[1]) group7 = self.animate_min(min7eq, [6, 5, 2]) self.play(*group9.shift_into_focus(self, 2)) self.wait() min4eq = self.animate_question_mark(group9.lines[2]) group4 = self.animate_min(min4eq, [3, 2]) self.play(self.camera_frame.scale, 1.8, self.camera_frame.move_to, group9.get_critical_point(RIGHT), coin_group.to_edge, DR) self.wait() more_anim = [] for group in (group8, group7, group4): for line in group.lines: eq = self.eq.copy() eq.next_to(line) cdots = self.cdots.copy() cdots.next_to(eq) group.add(eq, cdots) more_anim.append(FadeIn(eq)) more_anim.append(FadeIn(cdots)) self.play(*more_anim) self.wait() self.play(*self.focus_these_fade_rest(self.same_min[7], color="#e86e1c"), run_time=0.5) self.wait() self.play(*self.focus_others(self.same_min[6], color="#bf1ce8"), run_time=0.5) self.wait() self.play(*self.focus_others(self.same_min[2], color="#45e81c"), run_time=0.5) self.wait(5) self.play(*[FadeOut(mob) for mob in self.all_mobjects_in_scene()]) self.wait(10) def all_mobjects_in_scene(self): uniq_mobjects = set() def recursive(mobjects): for submob in mobjects: if isinstance(submob, ScreenRectangle): pass elif isinstance(submob, (MinOption, Group, VGroup)): print(f"--- {submob}") recursive(submob.submobjects) else: uniq_mobjects.add(submob) recursive(self.get_mobjects()) return uniq_mobjects def focus_these_fade_rest(self, to_focus, color=WHITE): animations = [] for mob in self.all_mobjects_in_scene() - set(to_focus): animations.extend([mob.fade, 0.5]) for mob in to_focus: animations.extend([mob.set_color, color]) return animations def focus_others(self, to_focus, color=WHITE): animations = [] for mob in to_focus: animations.extend([mob.set_color, color, mob.fade, -1]) return animations def animate_question_mark(self, align_to_mobject, first=False): eq = self.eq.copy() eq.add_updater(lambda mob: mob.next_to(align_to_mobject)) question_mark = self.question_mark.copy().next_to(eq) self.add(align_to_mobject, eq, question_mark) group = Group() group.add(align_to_mobject, eq, question_mark) if first: group.center() self.wait(5) self.play( VGroup(align_to_mobject, eq).to_edge, LEFT, FadeOut(question_mark)) else: self.play(FadeIn(question_mark), run_time=0.5) self.play(FadeOut(question_mark), run_time=0.5) group.remove(question_mark) return eq def animate_min(self, target, options): group = MinOption() self.add(group) num_coins = len(options) coins = [self.coins[i].copy() for i in range(num_coins)] if num_coins == 3: brace = MathTex(r'\underbrace{\qquad\qquad\qquad\qquad}').scale( 1).rotate(-PI / 2) coin_animations = [ coins[0].next_to, brace, { "aligned_edge": UL }, coins[1].next_to, brace, { "aligned_edge": LEFT }, coins[2].next_to, brace, { "aligned_edge": DL }, ] elif num_coins == 2: brace = MathTex(r'\underbrace{\qquad\qquad}').scale(1).rotate(-PI / 2) coin_animations = [ coins[0].next_to, brace, { "aligned_edge": UL }, coins[1].next_to, brace, { "aligned_edge": DL }, ] elif num_coins == 1: brace = MathTex(r'\underbrace{\qquad}').scale(1).rotate(-PI / 2) coin_animations = [ coins[0].next_to, brace, { "aligned_edge": LEFT }, ] else: coin_animations = None brace = None if coin_animations: min_word = self.min_word.copy() min_word.next_to(target) brace.next_to(min_word) brace.set_height( len(coins) * coins[0].get_height() + (len(coins) - 1) * DEFAULT_MOBJECT_TO_MOBJECT_BUFFER) self.play(FadeIn(brace), FadeIn(min_word)) group.add(brace, min_word, *coins) self.play(*coin_animations) for i, coin in zip(options, coins): plus = self.plus.copy().next_to(coin) new_min = self.mins[i].copy().next_to(plus) self.same_min[i].append(new_min) self.play(FadeIn(VGroup(plus, new_min))) group.add(plus, new_min) group.add_line(coin, plus, new_min) group.add_brace(brace) group.add_min_word(min_word) else: zero = self.zero.copy() zero.next_to(target) self.play(FadeIn(zero)) group.add(zero) group.add_updater(lambda mob: mob.next_to(target)) return group def shift_into_focus(self, mobject): new_pos = mobject.get_critical_point(LEFT) + ( config.frame_x_radius - DEFAULT_MOBJECT_TO_EDGE_BUFFER) * X_AXIS return self.camera_frame.move_to, new_pos
def construct(self): all_coins = Group() all_coins.add(Coin(1)) all_coins.add(Coin(5)) all_coins.add(Coin(10)) all_coins.add(Coin(20)) all_coins.add(Coin(25)) all_coins.arrange() self.add(all_coins) all_coins.to_edge(DOWN, buff=LARGE_BUFF) amount_cents_small = CyrTex( r'\foreignlanguage{bulgarian}{$40$ ст.} =').scale(2) amount_cents_small.shift(amount_cents_small.get_width() * LEFT + UP) self.add(amount_cents_small) brace = MathTex(r'\underbrace{\qquad\qquad\qquad\qquad}').scale( 1).rotate(-PI / 2) brace.next_to(amount_cents_small, RIGHT) self.play(FadeIn(brace)) cents25 = all_coins[4] cents10 = all_coins[2] cents5 = all_coins[1] buff = DEFAULT_MOBJECT_TO_MOBJECT_BUFFER cents25_1 = cents25.copy() edge = brace.get_critical_point(RIGHT) + RIGHT * 0.75 up = (cents25_1.get_height() + buff) * UP down = (cents25_1.get_height() + buff) * DOWN self.play(cents25_1.move_to, edge + up) cents10_1 = cents10.copy() self.play(cents10_1.move_to, edge) cents5_1 = cents5.copy() self.play(cents5_1.move_to, edge + down) self.wait() wrong_group = Group(cents25_1, cents10_1, cents5_1) cross = Cross(wrong_group) self.add(cross) self.wait() self.play( LaggedStart( *[FadeOut(wrong_group), FadeOut(cross), FadeOut(brace)], lag_ratio=0.2)) brace = MathTex(r'\underbrace{\qquad\qquad\quad}').scale(1).rotate( -PI / 2) brace.next_to(amount_cents_small, RIGHT) self.play(FadeIn(brace)) cents20 = all_coins[3] up = (cents20.get_height() + buff) * UP * 0.5 down = (cents20.get_height() + buff) * DOWN * 0.5 cents20_1 = cents20.copy() self.play(cents20_1.move_to, edge + up) cents20_2 = cents20.copy() self.play(cents20_2.move_to, edge + down) self.wait() self.play(*[FadeOut(x) for x in self.mobjects]) self.wait(10)