漢字プリント 数学プリント
問題文
黒玉 $3$ 個、赤玉 $4$ 個、白玉 $5$ 個が入っている袋から玉を $1$ 個ずつ取り出し、取り出した玉を順に横一列に $12$ 個すべて並べる。ただし、袋から個々の玉が取り出される確率は等しいものとする。
  1. どの赤玉も隣り合わない確率 $p$ を求めよ。
  2. どの赤玉も隣り合わないとき、どの黒玉も隣り合わない条件付き確率 $q$ を求めよ。
(2023 東京大学 理系第2問 文系第3問)
  1. $\,\frac{14}{55}$
  2. $\frac{103}{168}$
※ この答えは学校側が公表したものではありません。個人が作成した非公式の答えです。
コード
import itertools
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as ani
from matplotlib.lines import Line2D

#色の準備
col_bg  = "powderblue"
col_r   = "orangered"
col_k   = "0.2"
col_w   = "wheat"
col_ng  = "crimson"
col_ok  = "dodgerblue"
col_txt = "0.4"

#紙の準備
fig = plt.figure(facecolor=col_bg)
fig.suptitle("2023東大数学 理系第2問 文系第3問",
             color="0.6",x=0.97,y=0.05,ha="right",va="center")
fig.subplots_adjust(top=0.9,bottom=0.2)
ax1 = fig.add_subplot(211)
ax1.set_xlim(-1,12)
ax1.set_ylim(-1,1)
ax1.set_aspect("equal")
ax1.axis("off")
ax2 = fig.add_subplot(212)
ax2.set_xlim(-8,6)
ax2.set_ylim(-2,2)
ax2.set_aspect("equal")
ax2.axis("off")

#玉を準備
tama = ax1.scatter([4,5,6,4,5,6,7,4,5,6,7,8],
                   [-1]*3+[-3]*4+[-5]*5,
                   facecolors=[col_k]*3+[col_r]*4+[col_w]*5,
                   s=400,clip_on=False)

#数え上げ領域の準備
objs = []
batsu1,= ax1.plot([0.5,2.5],[-2.5,-3.5],color=col_ng,linewidth=3,solid_capstyle="round",clip_on=False)
batsu2,= ax1.plot([0.5,2.5],[-3.5,-2.5],color=col_ng,linewidth=3,solid_capstyle="round",clip_on=False)
objs = objs + [batsu1] + [batsu2]
objs +=  ax2.plot([-7,-1],[0,0],color=col_txt)
objs +=  ax2.plot([ 1, 3],[0,0],color=col_txt)
objs += [ax2.text(0,0,"=",color=col_txt,size=20,ha="center",va="center")]
objs += [ax2.text(-6.0,-.80,"赤",color="w",size=16,ha="center",va="center",fontfamily="HGSoeiKakupoptai",
                  bbox=dict(fc=col_r,boxstyle="circle",linewidth=0,pad=0.4))]
objs += [ax2.text(-6.0,0.75,"黒",color="w",size=16,ha="center",va="center",fontfamily="HGSoeiKakupoptai",
                  bbox=dict(fc=col_k,boxstyle="circle",linewidth=0,pad=0.4))]
objs += [ax2.text(-3.3,-.85,"が隣り合わない",color=col_txt,size=14,ha="center",va="center",fontfamily="HGSoeiKakupoptai")]
objs += [ax2.text(-3.3,0.70,"が隣り合わない",color=col_txt,size=14,ha="center",va="center",fontfamily="HGSoeiKakupoptai")]
nump  =  ax2.text( 1.1,-.85,"for number",color=col_txt,size=20,ha="left",va="center",fontfamily="fantasy")
numq  =  ax2.text( 1.1,0.60,"for number",color=col_txt,size=20,ha="left",va="center",fontfamily="fantasy")
mkup  =  ax2.text( 3.3,0.65,"$\\uparrow$",color=col_ok,size=22,ha="center",va="center")
txok  =  ax2.text(-1,0,"( `д´)b オッケー!",color=col_ok,size=24,ha="center",va="center")
objs += [nump,numq,mkup,txok]
for obj in objs:
    obj.set_visible(False)

#減らずグチたち
commentdic={
"ha" : "center",
"va" : "center",
"size" : 20,
"color" : "white",
"zorder" : 10,
"fontfamily": "Meiryo",
"linespacing" : 2,
}
commentbgdic={
"facecolor" : "black",
"pad" : 300,
}
msg_opening1 = "絶対に\n負けられない 戦いが\n\nここにはある"
msg_opening2 = "今は昔\n黒玉3個、赤玉4個、白玉5個\nがありました"
msg_opening3 = "おばあさんは\n赤玉が隣り合わないよう\n一列に並べました"
msg_opening4 = "このとき\n黒玉が隣り合っていたら\nダメです"
msg_opening5 = "赤玉も黒玉も\n隣り合っていなかったら\nOKです!"
msg_opening6 = "今から\n無の時間が\nやってきます"
msg_opening7 = "行くぞ!"
msg_ending1  = "(答)\n$\\dfrac{\\:103\\:}{\\:168\\:}$"
msg_ending2  = "場合の数は\n退屈との戦いです"
msg_ending3  = "-----  END  -----"
comment = fig.text(0.5,0.5,"",fontdict=commentdic,bbox=commentbgdic)

#訂正線
strike_through = Line2D([0.29,0.29],[0.56,0.56],
                        color="w",linewidth=2.5,zorder=11)
fig.add_artist(strike_through)
txt_opening1 = fig.text(0.43,0.47,"数え切る",
                        zorder=11,alpha=0,fontdict=commentdic)

#エンディング用
endings = []
endings +=  ax2.plot([4.8,6.4],[0,0],color=col_txt,clip_on=False)
endings += [ax2.text(4,0,"=",color=col_txt,size=20,ha="center",va="center",fontfamily="Meiryo")]
endings += [ax2.text(5.6,-.85,str(168),color=col_txt,size=20,ha="center",va="center",fontfamily="fantasy")]
endings += [ax2.text(5.6,0.60,str(103),color=col_txt,size=20,ha="center",va="center",fontfamily="fantasy")]
for obj in endings:
    obj.set_alpha(0)

#まずはパイソン君に数えさせます
l1 = list(range(12))
cases = []
count = 0
for r in itertools.combinations(l1,4):
    l2 = [i for i in l1 if i not in r]
    for k in itertools.combinations(l2,3):
        if 1 not in np.diff(r):
            if 1 not in np.diff(k):
                count += 1
                cases.append([r,k,count])
            else:
                cases.append([r,k,count])

#お気に入りのイージング関数
def easing(x):
    return -(np.cos(np.pi*x)-1)/2

#無の時間を作り出す関数
def show_case(t):
    
    i = min(t,len(cases)-1)
    r = cases[i][0]
    k = cases[i][1]
    
    colors = []
    for j in range(12):
        if j in r:
            color = col_r
        elif j in k:
            color = col_k
        else:
            color = col_w
        colors.append(color)
    tama.set_facecolors(colors)
    
    q = cases[i][2]
    numq.set_text("{:^5}".format(q))
    nump.set_text("{:^5}".format(i+1))
    
    if 1 in np.diff(k):
        batsux = k[np.argmin(np.diff(k)!=1)]
        batsu1.set_data([batsux-0.5,batsux+1.5],[0.5,-0.5])
        batsu2.set_data([batsux-0.5,batsux+1.5],[-0.5,0.5])
        for obj in [batsu1,batsu2]:
            obj.set_visible(True)
        mkup.set_visible(False)
    else:
        for obj in [batsu1,batsu2]:
            obj.set_visible(False)
        if t < len(cases):
            mkup.set_visible(True)
        else:
            mkup.set_visible(False)

#オープニング
def opening(t):
    if t==0:
        comment.set_text(msg_opening1)
    elif t>=20 and t<=40:
        k = easing((t-20)/20)
        strike_through.set_xdata([0.29,0.29+0.27*k])
    elif t>=60 and t<=80:
        k = easing((t-60)/20)
        txt_opening1.set_alpha(k)
    elif t==120:
        comment.set_text(msg_opening2)
        for obj in [strike_through,txt_opening1]:
            obj.set_visible(False)
    elif t==160:
        comment.set_visible(False)
    elif t==200:
        comment.set_text(msg_opening3)
        comment.set_visible(True)
        tama.set_offsets(list(zip(l1,[-3]*12)))
        tama.set_facecolors([col_r,col_k,col_k,col_r,col_w,col_w,col_r,col_k,col_w,col_r,col_w,col_w])
    elif t==240:
        comment.set_visible(False)
    elif t==280:
        comment.set_text(msg_opening4)
        comment.set_visible(True)
        for obj in [batsu1,batsu2]:
            obj.set_visible(True)
    elif t==320:
        comment.set_visible(False)
    elif t==360:
        comment.set_text(msg_opening5)
        comment.set_visible(True)
        for obj in [batsu1,batsu2]:
            obj.set_visible(False)
        tama.set_facecolors([col_r,col_k,col_w,col_r,col_k,col_w,col_r,col_k,col_w,col_r,col_w,col_w])
        txok.set_visible(True)
    elif t==400:
        comment.set_visible(False)
    elif t==440:
        comment.set_text(msg_opening6)
        comment.set_visible(True)
        tama.set_offsets(list(zip(l1,[0]*12)))
        for obj in objs:
            obj.set_visible(True)
        txok.set_visible(False)
    elif t==480:
        comment.set_text(msg_opening7)
    elif t==499:
        show_case(0)
        comment.set_visible(False)

#エンディング
def ending(t):
    if t<40:
        alpha = easing(t/39)
        for obj in endings:
            obj.set_alpha(alpha)
    elif t<80:
        pass
    elif t==80:
        comment.set_text(msg_ending1)
        comment.set_visible(True)
    elif t==120:
        comment.set_text(msg_ending2)
    elif t==160:
        comment.set_text(msg_ending3)

#上演
def update(i):
    if i<500:
        opening(i)
    elif i<7600:
        k = i-500
        show_case(k)
    else:
        k = i-7600
        ending(k)

mov = ani.FuncAnimation(fig,update,7800,interval=100)
plt.show()
解説になっているのか?甚だギモンな動画
「高校数学のエアポケット」に戻る