漢字プリント 数学プリント
問題文
座標平面上に8本の直線 $$x=a\,(a=1,2,3,4),\quad y=b\,(b=1,2,3,4)$$ がある。以下、16個の点 $$(a,b)\quad(a=1,2,3,4,\quad b=1,2,3,4)$$ から異なる5個の点を選ぶことを考える。
  1. 次の条件を満たす5個の点の選び方は何通りあるか。

    上の8本の直線のうち、選んだ点を1個も含まないものがちょうど2本ある。

  2. 次の条件を満たす5個の点の選び方は何通りあるか。

    上の8本の直線のうち、いずれも選んだ点を少なくとも1個も含む。

(2020 東京大学 文系第2問)
  1. $1824$ 通り
  2. $432$ 通り
※ この答えは学校側が公表したものではありません。個人が作成した非公式の答えです。
コード
import itertools
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.lines as lines
import matplotlib.animation as ani

#紙の準備
fig = plt.figure(facecolor="wheat")
fig.suptitle("2020東大数学 文系第2問",
             color="0.5",x=0.97,y=0.05,
             ha="right",va="center")
ax = fig.add_subplot(111)
ax.set_xlim(0.5,4.5)
ax.set_ylim(0.5,4.5)
ax.set_aspect("equal")
ax.axis("off")

#碁盤の目を描く
for i in range(1,5):
    exec('H{},=ax.plot([1,4],[i,i],color="k",zorder=-10)'.format(i))
    exec('V{},=ax.plot([i,i],[1,4],color="k",zorder=-10)'.format(i))

#各マス目の番号(16進数)
l = ["0","1","2","3",
     "4","5","6","7",
     "8","9","a","b",
     "c","d","e","f"]

#16進数を座標に変換
def hex2ab(v):
    A = []
    B = []
    for i in range(5):
        n = int(v[i],16)
        a = 1+n%4
        b = 4-n//4
        A.append(a)
        B.append(b)
    return A,B

#(1)の全通りを列挙
c_q1 = []
for v in itertools.combinations(l,5):
    A,B = hex2ab(v)
    condition =\
        len(set(A))+len(set(B))==6
    if condition:
        c_q1.append(v)

#(2)の全通りを列挙
c_q2 = []
for v in itertools.combinations(l,5):
    A,B = hex2ab(v)
    condition =\
        len(set(A))+len(set(B))==8
    if condition:
        c_q2.append(v)

#ばらばらに置かれた碁石
Title = ax.text(2.0,4.6,"n =",color="saddlebrown",
                fontsize=20,fontfamily="fantasy")
Count = ax.text(2.5,4.6,"{:>4}".format(0),color="saddlebrown",
                fontsize=20,fontfamily="fantasy")
Fives = ax.scatter([-0.1,0.4,4.2,4.5,4.7],[1.7,2.6,3.4,1.3,2.7],
                   c="k",s=1800,clip_on=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  = "これから始めるのは\n4行$\\,\\times$4列の碁盤の目に\n5個の碁石を並べていく\n無味乾燥なゲームである"
msg_before_q1 = "(1)\n碁石の置かれていない線が\nちょうど2本ある場合は?"
msg_answer_q1 = "(1) の答え\n{} 通り".format(len(c_q1))
msg_before_q2 = "(2)\n碁石の置かれていない線が\n1本もない場合は?"
msg_answer_q2 = "(2) の答え\n{} 通り".format(len(c_q2))
msg_ending1   = "ここまで見てくださった\nあなたは\nものすごい忍耐力\nの持ち主です!"
msg_ending2   = "きっと\n良いことがあるでしょう\n\nGOOD LUCK !!"
comment = fig.text(0.5,0.5,"",
                   fontdict=commentdic,bbox=commentbgdic)

#訂正線
strike_through = lines.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)

#ひとつひとつの場合を見せる
def show_case(k,v):
    A,B = hex2ab(v)
    Fives.set_offsets(list(zip(A,B)))
    str_count = "{:>4}".format(k+1)
    Count.set_text(str_count)
    return A,B

#問題(1)
def q1(t):
    if t==0:
        comment.set_text(msg_before_q1)
        comment.set_visible(True)
    if t==40:
        comment.set_visible(False)
    k = min(max(t-80,0),len(c_q1)-1)
    v = c_q1[k]
    A,B = show_case(k,v)
    for i in range(1,5):
        if i in A:
            exec('V{}.set_linestyle("solid")'.format(i))
        else:
            exec('V{}.set_linestyle("dashed")'.format(i))
        if i in B:
            exec('H{}.set_linestyle("solid")'.format(i))
        else:
            exec('H{}.set_linestyle("dashed")'.format(i))
    if t==1950:
        comment.set_text(msg_answer_q1)
        comment.set_visible(True)

#問題(2)
def q2(t):
    if t==0:
        comment.set_text(msg_before_q2)
        for i in range(1,5):
            exec('V{}.set_linestyle("solid")'.format(i))
            exec('H{}.set_linestyle("solid")'.format(i))
    if t==40:
        comment.set_visible(False)
    k = min(max(t-80,0),len(c_q2)-1)
    v = c_q2[k]
    show_case(k,v)
    if t==550:
        comment.set_text(msg_answer_q2)
        comment.set_visible(True)

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

#オープニング
def opening(t):
    if t==0:
        comment.set_text(msg_opening1)
    if t>=20 and t<=40:
        k = easing((t-20)/20)
        strike_through.set_xdata([0.29,0.29+0.27*k])
    if t>=60 and t<=80:
        k = easing((t-60)/20)
        txt_opening1.set_alpha(k)
    if t==120:
        comment.set_text(msg_opening2)
        for obj in [strike_through,txt_opening1]:
            obj.set_visible(False)
    if t==170:
        comment.set_visible(False)

#エンディング
def ending(t):
    if t==0:
        comment.set_text(msg_ending1)
    if t==50:
        comment.set_text(msg_ending2)

#上演
def update(i):
    if   i<220:
        opening(i)
    elif i<2220:
        q1(i-220)
    elif i<2820:
        q2(i-2220)
    else:
        ending(i-2820)

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