BuildFiveFromFour of eop/combinations

This commit is contained in:
Grant Sanderson 2017-11-29 15:12:39 -08:00
parent e95acbdce7
commit 0e7fbe73b8

View file

@ -36,6 +36,8 @@ def get_stack(
obj1, obj2, n, k,
fixed_start = None,
fixed_end = None,
obj_to_obj_buff = SMALL_BUFF,
vertical_buff = MED_SMALL_BUFF,
):
stack = VGroup()
for indices in it.combinations(range(n), k):
@ -47,9 +49,9 @@ def get_stack(
term.add_to_back(fixed_start.copy())
if fixed_end:
term.add(fixed_end.copy())
term.arrange_submobjects(RIGHT, buff = SMALL_BUFF)
term.arrange_submobjects(RIGHT, buff = obj_to_obj_buff)
stack.add(term)
stack.arrange_submobjects(DOWN)
stack.arrange_submobjects(DOWN, buff = vertical_buff)
return stack
def get_stacks(obj1, obj2, n, **kwargs):
@ -802,12 +804,13 @@ class ProbabilityOfThreeWomenInGroupOfFive(Scene):
])
return lineup
def get_lineup(self, *mobjects):
def get_lineup(self, *mobjects, **kwargs):
buff = kwargs.get("buff", MED_SMALL_BUFF)
lines = VGroup(*[
Line(ORIGIN, self.item_line_width*RIGHT)
for mob in mobjects
])
lines.arrange_submobjects(RIGHT)
lines.arrange_submobjects(RIGHT, buff = buff)
items = VGroup()
for line, mob in zip(lines, mobjects):
item = VectorizedPoint() if mob is None else mob.copy()
@ -824,6 +827,337 @@ class RememberThisSensation(TeacherStudentsScene):
self.change_student_modes("confused", "pondering", "erm")
self.dither(2)
class GroupsOf6(Scene):
def construct(self):
title = TexMobject("2^6 =", "64", "\\text{ Possibilities}")
title.to_edge(UP, buff = MED_SMALL_BUFF)
title.highlight_by_tex("64", YELLOW)
man, woman = Male(), Female()
stacks = get_stacks(man, woman, 6, vertical_buff = SMALL_BUFF)
stacks.scale_to_fit_height(6.25)
stacks.to_edge(DOWN, buff = MED_SMALL_BUFF)
women_groups = VGroup()
for stack in stacks:
for lineup in stack:
group = VGroup()
for item in lineup:
if "female" in item.get_tex_string():
group.add(item)
women_groups.add(group)
numbers = VGroup()
for stack in stacks:
number = TexMobject(str(len(stack)))
number.next_to(stack, UP, SMALL_BUFF)
numbers.add(number)
self.add(title)
self.play(LaggedStart(
LaggedStart, stacks,
lambda s : (FadeIn, s),
run_time = 3,
))
self.play(Write(numbers, run_time = 3))
self.dither()
self.play(LaggedStart(
ApplyMethod, women_groups,
lambda m : (m.highlight, PINK),
lag_ratio = 0.1,
rate_func = wiggle,
run_time = 6,
))
class GroupsOf7(Scene):
def construct(self):
stack = get_stack(Male(), Female(), 7, 3)
question = TextMobject(
"How many groups \\\\ of 7 with 3 ", "$\\female$", "?"
)
question.highlight_by_tex("female", MAROON_B)
question.shift(1.5*UP)
self.add(question)
for n, item in enumerate(stack):
item.center()
number = TexMobject(str(n))
number.next_to(ORIGIN, DOWN, LARGE_BUFF)
self.add(item, number)
self.dither(0.2)
self.remove(item, number)
self.add(item, number)
self.dither(2)
class BuildFiveFromFour(ProbabilityOfThreeWomenInGroupOfFive):
def construct(self):
self.show_all_configurations_of_four()
self.organize_into_stacks()
self.walk_through_stacks()
self.split_into_two_possibilities()
self.combine_stacks()
def show_all_configurations_of_four(self):
man, woman = Male(), Female()
n = 4
vects = [
1.5*UP,
0.5*UP,
3.5*RIGHT,
1.5*RIGHT,
]
lineup_groups = VGroup()
for k in range(n+1):
lineup_group = VGroup()
for tup in it.product(*[[man, woman]]*k):
lineup = self.get_lineup(*list(tup) + (n-k)*[None])
lineup.scale(1.4*(0.9)**k)
lineup.move_to(0.5*DOWN)
for mob, vect in zip(tup, vects):
if mob is woman:
lineup.shift(vect)
else:
lineup.shift(-vect)
lineup_group.add(lineup)
lineup_groups.add(lineup_group)
n_possibilities = TexMobject(
"2 \\cdot", "2 \\cdot", "2 \\cdot", "2",
"\\text{ Possibilities}"
)
n_possibilities.to_edge(UP)
twos = VGroup(*n_possibilities[-2::-1])
two_anims = [
ReplacementTransform(
VectorizedPoint(twos[0].get_center()),
twos[0]
)
] + [
ReplacementTransform(t1.copy(), t2)
for t1, t2 in zip(twos, twos[1:])
]
curr_lineup_group = lineup_groups[0]
self.play(
ShowCreation(curr_lineup_group[0]),
)
for i, lineup_group in enumerate(lineup_groups[1:]):
anims = [ReplacementTransform(curr_lineup_group, lineup_group)]
anims += two_anims[:i+1]
if i == 0:
anims.append(FadeIn(n_possibilities[-1]))
self.remove(twos)
self.play(*anims)
self.dither()
curr_lineup_group = lineup_group
self.lineups = curr_lineup_group
eq_16 = TexMobject("=", "16")
eq_16.move_to(twos.get_right())
eq_16.highlight_by_tex("16", YELLOW)
self.play(
n_possibilities[-1].next_to, eq_16, RIGHT,
twos.next_to, eq_16, LEFT,
FadeIn(eq_16),
)
self.dither()
n_possibilities.add(eq_16)
self.n_possibilities = n_possibilities
def organize_into_stacks(self):
lineups = self.lineups
stacks = VGroup(*[VGroup() for x in range(5)])
for lineup in lineups:
women = filter(
lambda m : "female" in m.get_tex_string(),
lineup.items
)
stacks[len(women)].add(lineup)
stacks.generate_target()
stacks.target.scale(0.75)
for stack in stacks.target:
stack.arrange_submobjects(DOWN, buff = SMALL_BUFF)
stacks.target.arrange_submobjects(
RIGHT, buff = MED_LARGE_BUFF, aligned_edge = DOWN
)
stacks.target.to_edge(DOWN, buff = MED_SMALL_BUFF)
self.play(MoveToTarget(
stacks,
run_time = 2,
path_arc = np.pi/2
))
self.dither()
self.stacks = stacks
def walk_through_stacks(self):
stacks = self.stacks
numbers = VGroup()
for stack in stacks:
rect = SurroundingRectangle(stack)
rect.set_stroke(WHITE, 2)
self.play(ShowCreation(rect))
for n, lineup in enumerate(stack):
lineup_copy = lineup.copy()
lineup_copy.highlight(YELLOW)
number = TexMobject(str(n+1))
number.next_to(stack, UP)
self.add(lineup_copy, number)
self.dither(0.25)
self.remove(lineup_copy, number)
self.add(number)
numbers.add(number)
self.play(FadeOut(rect))
self.dither()
stacks.numbers = numbers
def split_into_two_possibilities(self):
bottom_stacks = self.stacks
top_stacks = bottom_stacks.deepcopy()
top_group = VGroup(top_stacks, top_stacks.numbers)
h_line = DashedLine(SPACE_WIDTH*LEFT, SPACE_WIDTH*RIGHT)
#Initial split
self.play(
FadeOut(self.n_possibilities),
top_group.to_edge, UP, MED_SMALL_BUFF,
)
self.play(ShowCreation(h_line))
#Add extra slot
for stacks, sym in (top_stacks, Female()), (bottom_stacks, Male()):
sym.set_fill(opacity = 0)
new_stacks = VGroup()
to_fade_in = VGroup()
for stack in stacks:
new_stack = VGroup()
for lineup in stack:
new_lineup = self.get_lineup(*[
Female() if "female" in item.get_tex_string() else Male()
for item in lineup.items
] + [sym], buff = SMALL_BUFF)
new_lineup.replace(lineup, dim_to_match = 1)
new_stack.add(new_lineup)
for group in lineup.items, lineup.lines:
point = VectorizedPoint(group[-1].get_center())
group.add(point)
to_fade_in.add(lineup.items[-1])
new_stacks.add(new_stack)
new_stacks.arrange_submobjects(
RIGHT, buff = MED_LARGE_BUFF, aligned_edge = DOWN
)
new_stacks.move_to(stacks, DOWN)
stacks.target = new_stacks
stacks.to_fade_in = to_fade_in
stacks.numbers.generate_target()
for number, stack in zip(stacks.numbers.target, new_stacks):
number.next_to(stack, UP)
for stacks in top_stacks, bottom_stacks:
self.play(
MoveToTarget(stacks),
MoveToTarget(stacks.numbers)
)
self.dither()
#Fill extra slot
add_man = TextMobject("Add", "$\\male$")
add_man.highlight_by_tex("male", BLUE)
add_woman = TextMobject("Add", "$\\female$")
add_woman.highlight_by_tex("female", MAROON_B)
add_man.next_to(ORIGIN, DOWN).to_edge(LEFT)
add_woman.to_corner(UP+LEFT)
for stacks, words in (bottom_stacks, add_man), (top_stacks, add_woman):
to_fade_in = stacks.to_fade_in
to_fade_in.set_fill(opacity = 1)
to_fade_in.save_state()
Transform(to_fade_in, VGroup(words[-1])).update(1)
self.play(Write(words, run_time = 1))
self.play(to_fade_in.restore)
self.dither()
#Perform shift
dist = top_stacks[1].get_center()[0] - top_stacks[0].get_center()[0]
self.play(
top_stacks.shift, dist*RIGHT/2,
top_stacks.numbers.shift, dist*RIGHT/2,
bottom_stacks.shift, dist*LEFT/2,
bottom_stacks.numbers.shift, dist*LEFT/2,
)
self.dither()
self.play(*map(FadeOut, [add_man, add_woman, h_line]))
self.set_variables_as_attrs(top_stacks, bottom_stacks)
def combine_stacks(self):
top_stacks = self.top_stacks
bottom_stacks = self.bottom_stacks
rects = VGroup()
for stacks, color in (top_stacks, MAROON_C), (bottom_stacks, BLUE_D):
for stack in stacks:
rect = SurroundingRectangle(stack)
rect.set_stroke(color, 2)
rects.add(rect)
stack.add(rect)
new_numbers = VGroup()
self.play(LaggedStart(ShowCreation, rects, run_time = 1))
for i, top_stack in enumerate(top_stacks[:-1]):
bottom_stack = bottom_stacks[i+1]
top_number = top_stacks.numbers[i]
bottom_number = bottom_stacks.numbers[i+1]
movers = top_stack, top_number, bottom_number
for mob in movers:
mob.generate_target()
top_stack.target.move_to(bottom_stack.get_top(), DOWN)
plus = TexMobject("+")
expr = VGroup(top_number.target, plus, bottom_number.target)
expr.arrange_submobjects(RIGHT, buff = SMALL_BUFF)
expr.next_to(top_stack.target.get_top(), UP)
new_number = TexMobject(str(
len(top_stack) + len(bottom_stack) - 2
))
new_number.next_to(expr, UP)
new_numbers.add(new_number)
self.play(
Write(plus),
*map(MoveToTarget, movers)
)
self.play(
VGroup(top_stacks[-1], top_stacks.numbers[-1]).align_to,
bottom_stacks, DOWN
)
self.dither()
new_numbers.add_to_back(bottom_stacks.numbers[0].copy())
new_numbers.add(top_stacks.numbers[-1].copy())
new_numbers.highlight(PINK)
self.play(Write(new_numbers, run_time = 3))
self.dither()