漢字プリント 数学プリント
問題文
  1. $\cos2\theta$ と $\cos3\theta$ を $\cos\theta$ の式として表せ。
  2. 半径 $1$ の円に内接する正五角形の一辺の長さが $1.15$ より大きいか否かを理由を付けて判定せよ。
(2023 京都大学 文系第3問)
  1. $\cos2\theta=2\cos^2\theta-1$
    $\cos3\theta=4\cos^3\theta-3\cos\theta$
  2. $1.15$ より大きい
※ この答えは学校側が公表したものではありません。個人が作成した非公式の答えです。
コード
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as ani
import matplotlib.patches as patches
from matplotlib.gridspec import GridSpec
from matplotlib.colors import ListedColormap

#フォント辞書たち
plt.rcParams["mathtext.fontset"]="cm"
mathdic={
"fontsize" : 18,
}
linedic={
"fontsize" : 12,
"fontfamily": "Meiryo",
}
phrasedic={
"ha" : "center",
"va" : "center",
"size" : 20,
"zorder" : 100,
"color" : "white",
"visible" : False,
"linespacing": 2.4,
"fontfamily": "Meiryo",
}

#紙の準備
fig = plt.figure()
fig.canvas.draw()
fig.suptitle("2023京大数学 文系第3問",
             color="0.5",ha="right",x=0.96,y=0.96)
gs = GridSpec(2,2,wspace=0.0,width_ratios=[3,4],
              hspace=-0.3,height_ratios=[2,1])
ax1 = fig.add_subplot(gs[0,0])
ax1.set_xlim(-1.1,1.1)
ax1.set_ylim(-1.1,1.1)
ax2 = fig.add_subplot(gs[1,0])
ax2.set_xlim(0,8)
ax2.set_ylim(0,3)
ax3 = fig.add_subplot(gs[:,1])
ax3.set_xlim(0,8)
ax3.set_ylim(0,7.5)
for ax in [ax1,ax2,ax3]:
    ax.set_aspect("equal")
    ax.axis("off")

#正五角形を描きます
verts = [(np.cos(2/5*np.pi*i),np.sin(2/5*np.pi*i)) for i in range(5)]
pg = patches.Polygon(verts,fill=False,ec="0.4",lw=2)
w1 = patches.Wedge((0,0),0.2,0, 72,fc="0.6")
w2 = patches.Wedge((0,0),0.2,0,144,fc="pink")
w3 = patches.Wedge((0,0),0.2,0,216,fc="lightblue")
for obj in [pg,w1,w2,w3]:
    ax1.add_patch(obj)
for i in range(5):
    ax1.plot([0,verts[i][0]],[0,verts[i][1]],c="0.4",lw=1,ls="--")
P2,= ax1.plot(verts[2][0],verts[2][1],marker="o",color="orangered")
P3,= ax1.plot(verts[3][0],verts[3][1],marker="o",color="dodgerblue")
a1 = ax1.text(0.20,0.12,"$\\theta$",fontdict=mathdic)
a2 = ax1.text(0.45,-.20,"$1$",fontdict=linedic)
a3 = ax1.text(0.00,0.50,"$1$",fontdict=linedic)
a4 = ax1.text(0.70,0.60,"$x$",fontdict=mathdic)
for obj in [w1,w2,w3,P2,P3,a1,a2,a3,a4]:
    obj.set_alpha(0.0)

#数式たち
lines1 = [
(0.8,"$t=\\cos\\,\\theta$","とおくと"),
(0.2,"$\\cos\\,2\\theta\\,=\\,2\\,\\cos^2\\theta-1$"),
(2.0,"$=\\,2\\,t^2-1$"),
(0.2,"$\\cos\\,3\\theta\\,=\\,4\\,\\cos^3\\theta-3\\,\\cos\\,\\theta$"),
(2.0,"$=\\,4\\,t^3-3\\,t$")
]
lines2 = [
(1.0,"$\\cos\\,2\\theta\\,=\\,\\cos\\,3\\theta$","なので"),
(1.1,"$2\\,t^2-1\\,=\\,4\\,t^3-3\\,t$"),
(0.5,"$4\\,t^3-2\\,t^2-3\\,t+1\\,=\\,0$"),
(0.0,"$(t-1)(4\\,t^2+2\\,t^2-1)\\,=\\,0$"),
(2.0,"$t\\,=\\,1,\\,\\frac{-1\\pm\\sqrt{5}}{4}$")
]
lines3 = [
(0.1,"正五角形の1辺の長さを","$x$","とすると"),
(0.1,"余弦定理より"),
(0.0,"$x^2\\!=1^2\\!+1^2\\!-2\\cdot1\\cdot1\\cdot\\cos\\,\\theta$"),
(0.6,"$=\\,2\\,-\\,\\frac{-1+\\sqrt{5}}{2}$"),
(0.6,"$=\\;\\frac{5-\\sqrt{5}}{2}$")
]
lines4 = [
(1.0,"$x^2-1.15^2$"),
(0.0,"$=\\,\\frac{5-\\sqrt{5}}{2}-\\left(\\,\\frac{23}{20}\\right)^2$"),
(0.0,"$=\\,\\frac{1000-200\\sqrt{5}}{400}-\\,\\frac{529}{400}$"),
(0.0,"$=\\,\\frac{471-200\\sqrt{5}}{400}>\\frac{471-200\\times2.3}{400}$"),
(0.0,"$=\\,\\frac{11}{400}>\\,0$")
]
Lines = [lines1,lines2,lines3,lines4]

#数式を準備する関数
def prepare_lines(lines):
    Texts,Lends,Rends,Times = [],[],[],[]
    for i,line in enumerate(lines):
        x = line[0]
        L = int(x//0.2)
        Lends.append(L)
        mojis = line[1:]
        for moji in mojis :
            if moji[0]=="$":
                fd = mathdic
            else:
                fd = linedic
            text = ax.text(x,6-1.5*i+0.5,moji,fontdict=fd)
            Texts.append(text)
            bbox = text.get_window_extent().transformed(ax3.transData.inverted())
            x = bbox.x1+0.2
        R = int(x//0.2)+10
        Rends.append(R)
        T = R-L
        Times.append(T)
    Times = np.cumsum(Times)
    return (Texts,Lends,Times)

#数式たちを準備
TLTs,Texts,Ts = [],[],[]
for lines in Lines:
    TLT = prepare_lines(lines)
    TLTs.append(TLT)
    Texts.append(TLT[0])
    Ts.append(TLT[2][-1])
for text in ax3.texts:
    text.set_visible(False)

#数式隠しバーの準備
colors = [(1,1,1,alpha) for alpha in np.arange(0,11)/10]
cmap = ListedColormap(colors)
seq_pcm = []
for i in range(5):
    X,Y = np.mgrid[-2:10:0.1,6.0-1.5*i:7.5-1.5*i+0.1:1.5]
    C = np.ones((len(X)-1,1))
    C[0] = 0
    pcm = ax3.pcolormesh(X,Y,C,cmap=cmap,zorder=10)
    seq_pcm.append(pcm)

#補足説明たち
t1 = ax2.text(1.0,2.0,"$\\theta\\,=\\,72\\degree$",fontdict=mathdic)
t2 = ax2.text(4.4,2.0,"とおくと",fontdict=linedic)
t3 = ax2.text(1.0,0.5,"$\\cos$",fontdict=mathdic)
t4 = ax2.text(2.4,0.5,"$2\\theta$",color="orangered",fontdict=mathdic)
t5 = ax2.text(3.4,0.5,"$=$",fontdict=mathdic)
t6 = ax2.text(4.6,0.5,"$\\cos$",fontdict=mathdic)
t7 = ax2.text(6.0,0.5,"$3\\theta$",color="dodgerblue",fontdict=mathdic)
t8 = ax2.text(0.1,2.0,"$72\\degree\\,$は鈍角で$\\,0\\!<\\!\\cos\\,\\theta\\!<\\!1\\,$より",fontdict=linedic)
t9 = ax2.text(0.4,0.5,"$t=\\cos\\,\\theta=\\frac{-1+\\sqrt{5}}{4}$",fontdict=mathdic)
for obj in [t1,t2,t3,t4,t5,t6,t7,t8,t9]:
    obj.set_alpha(0.0)

#減らずグチたち
seq_prs = []
phrases = []
phrases.append("""
cos 72°
ってナニ?
""")
phrases.append("""
ダジャレかっ!
""")
phrases.append("""
こうやって計算するのです
""")
phrases.append("""
~ 結論 ~
正五角形の1辺の長さは
1.15 より大きい
""")
phrases.append("""
おしまい
""")
for phrase in phrases:
    prs = fig.text(0.5,0.5,phrase,fontdict=phrasedic,
                   bbox=dict(color="black",pad=300))
    seq_prs.append(prs)

#単一行を徐々に見せていく関数
def appear_line(i,pcm):
    C = np.ones(len(pcm.get_array()))
    C[:2*i+1] = 0
    C[2*i+1:2*i+20] = np.arange(0.05,1.00,0.05)
    pcm.set_array(C)

#複数行を徐々に見せていく関数
def appear_lines(i,lines,TLT):
    Text,L,T = TLT
    n = np.argmin(~(i<T))
    T = np.append(0,T)
    appear_line(L[n]+i-T[n],seq_pcm[n])

#イージング関数
def easing(x):
    if x<0.0:
        return 0
    elif x<0.5:
        return 2*x**2
    elif x<1.0:
        return 1-(-2*x+2)**2/2
    else:
        return 1
    
#いろんなものを見せたり消したりする関数
def set_objs_alpha(k,objs,disappear=False):
    if disappear == False:
        alpha = easing(k/39)
    else:
        alpha = 1-easing(k/39)
    for obj in objs:
        obj.set_alpha(alpha)

#第一補足
def group1(i):
    if i<40:
        set_objs_alpha(i,[w1,a1,t1,t2])
    elif i<80:
        set_objs_alpha(i-40,[w1,a1],disappear=True)
        set_objs_alpha(i-40,[w2,P2,t3,t4])
    elif i<120:
        set_objs_alpha(i-80,[w2],disappear=True)
        set_objs_alpha(i-80,[w3,P3,t6,t7])
    else:
        set_objs_alpha(i-120,[w3],disappear=True)
        set_objs_alpha(i-120,[t5])

#第二補足
def group2(i):
    if i<40:
        set_objs_alpha(i,[P2,P3,t1,t2,t3,t4,t5,t6,t7],disappear=True)
        set_objs_alpha(i,[w1,a1])
    elif i<80:
        set_objs_alpha(i-40,[t8])
    elif i<120:
        set_objs_alpha(i-80,[t9])
    else:
        set_objs_alpha(i-120,[a2,a3,a4])
        
#セクションを判定する関数
def section(i): 
    n = np.argmin(~(i<endings[1:]))
    k = i-endings[n]
    keys = list(periods.keys())
    key = keys[n]
    return key,k

#台本の構成
periods = {"P1":50,"P2":10,"P3":20,
           "G1":160,"L1":Ts[0],"N1":40,"L2":Ts[1],"N2":40,
           "G2":160,"L3":Ts[2],"N3":40,"L4":Ts[3],"N4":40,
           "P4":60,"P5":20}
endings = np.cumsum(list(periods.values()))
endings = np.append(0,endings)

#上演
def update(i):
    
    key,k = section(i)
    index = int(key[1])-1
    
    if "L" in key:
        appear_lines(k,Lines[index],TLTs[index])
    elif "G1" == key:
        group1(k)
    elif "G2" == key:
        group2(k)
        
    if k==0:
        if "L" in key:
            for pcm in seq_pcm:
                pcm.set_array(np.ones_like(C))
            for text in Texts[index-1]:
                text.set_visible(False)
            for text in Texts[index]:
                text.set_visible(True)
        if "P1" == key:
            seq_prs[0].set_visible(True)
        elif "P2" == key:
            seq_prs[1].set_visible(True)
            seq_prs[0].set_visible(False)
        elif "P3" == key:
            seq_prs[2].set_visible(True)
            seq_prs[1].set_visible(False)
        elif "G1" == key:
            seq_prs[2].set_visible(False)
        elif "P4" == key:
            seq_prs[3].set_visible(True)
        elif "P5" == key:
            seq_prs[4].set_visible(True)
            seq_prs[3].set_visible(False)
  
mov = ani.FuncAnimation(fig,update,endings[-1],interval=100)
plt.show()
解説になっているのか?甚だギモンな動画
「高校数学のエアポケット」に戻る