漢字プリント 数学プリント
問題文
整数 $a,b$ は等式 $$3^a-2^b=1\quad\cdots\,\textstyle\unicode{x2780}$$ を満たしているとする。
  1. $a,b$ はともに正となることを示せ。
  2. $b\gt1$ ならば、 $a$ は偶数であることを示せ。
  3. ➀ を満たす整数の組 $(a,b)$ をすべてあげよ。
(2018 東北大学 理系第3問)
  1. $(a,b)=(1,1),(2,3)$
※ この答えは学校側が公表したものではありません。個人が作成した非公式の答えです。
コード
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as ani
from matplotlib.gridspec import GridSpec
from matplotlib.colors import ListedColormap

#フォント辞書たち
mathdic={
"size" : 20,
"clip_on" : True,
"fontfamily": "Meiryo",
}
katadic={
"size" : 10,
"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.subplots_adjust(left=0,right=1,bottom=0.15,top=0.75)
fig.suptitle("2018東北大数学 理系第3問",
             color="0.5",ha="right",x=0.96,y=0.96)
gs = GridSpec(2,8,height_ratios=[1,1])
ax1 = fig.add_subplot(gs[0,2:])
ax2 = fig.add_subplot(gs[1,1:7])
axs = [ax1,ax2]
for ax in axs:
    ax.set_xlim( 0,8)
    ax.set_ylim(-2,0)
    ax.set_aspect("equal")
    ax.axis("off")

#数式たち
lines1 = [
"$\\equiv\\,(-1)\\quad-1$",
"$\\equiv\\,-1-1$",
"$\\equiv\\,-2$",
"$\\equiv\\,2$",
]
lines2 = [
"よって $3^a-1=2^b\\equiv2$ となるが",
"mod4でこれを満たすのは$\\;b=1\\;$のみ",
"このとき $3^a=2^1+1=3=3^1$",
" ∴ $(a,b)=(1,1)$ が必要",
]
lines3 = [
"$=\\,100\\,\\cdots\\cdots\\,00-1$",
"$=\\,22\\,\\cdots\\cdots\\,22$ (桁数は偶数!)",
"$=\\,100\\,\\cdots\\,01\\times22\\,\\cdots\\,22$",
"$=(22\\,\\cdots\\,22+2)\\times22\\,\\cdots\\,22$",
"$=2\\times(11\\,\\cdots\\,11+1)\\times2\\times11\\,\\cdots\\,11$",
"$=2\\times11\\,\\cdots\\,12\\times2\\times11\\,\\cdots\\,11$",
"$=2\\times2\\times11\\,\\cdots\\,11\\times11\\,\\cdots\\,12$",
"$=2^2\\times($連続する2整数の積$)=2^b$",
]
lines4 = [
"よって$\\,($連続する2整数の積$)\\,$の部分は",
"2以外の素因数を含んではいけない",
"したがって $2^b=2^2\\times1\\times2=2^3$",
"このとき $3^a=2^3+1=9=3^2$",
" ∴ $(a,b)=(2,3)$ が必要",
]

#補足オブジェクト
atama = fig.text(0.12,0.80,"mod4で考えます",color="w",fontdict=mathdic,
                 bbox=dict(fc="dodgerblue",lw=0,boxstyle="round,pad=0.5"))
sahen = fig.text(0.10,0.65,"$3\\quad-1$",fontdict=mathdic,clip_on=False)
kata1 = fig.text(0.13,0.68,"奇数",fontdict=katadic,clip_on=False)
kata2 = ax1.text(1.7,-0.45,"奇数",fontdict=katadic,clip_on=True)
kata3 = fig.text(.405,.575,"奇数",color="w",zorder=101,fontdict=katadic,visible=False)

#コメントたち
comments = []
phrases = []
phrases.append("""
$3^a-2^b=1$
をみたす整数の組 $(a,b)$
を求めよう
""")
phrases.append("""
$3\\quad-2^b=1$
のとき
""")
phrases.append("""
$3^1-2^1=1$
""")
phrases.append("""
次
""")
phrases.append("""
$3\\quad-2^b=1$
のとき
""")
phrases.append("""
$3^2-2^3=1$
""")
phrases.append("""
― まとめ ―
$3^1-2^1=1$
$3^2-2^3=1$
""")
phrases.append("""
以上!
""")
for phrase in phrases:
    prs = fig.text(0.5,0.5,phrase,fontdict=phrasedic,
                   bbox=dict(color="black",pad=300))
    comments.append(prs)

#数式準備の定数
colors = [(1,1,1,alpha) for alpha in np.arange(0,11)/10]
cmap   = ListedColormap(colors)
v_show = 2
t_next = 20

#数式を準備する関数
def prepare_lines(ax,lines):
    Texts,Times1,Pcms,Times2 = [],[],[],[]
    for i,line in enumerate(lines):
        text = ax.text(0,-(i+1)+0.3,line,fontdict=mathdic)
        Texts.append(text)
        bbox = text.get_window_extent().transformed(ax.transData.inverted())
        time1 = int(bbox.x1//(v_show/10)+30/v_show)
        Times1.append(time1)
        X,Y = np.mgrid[-2:12:0.1,-i-1:-i+0.1:1]
        C = np.ones((len(X)-1,1))
        C[0] = 0
        pcm = ax.pcolormesh(X,Y,C,cmap=cmap,zorder=10)
        Pcms.append(pcm)
    Times2 = np.insert(Times1,range(2,len(Times1)),t_next)
    Times2 = np.cumsum(Times2)
    return (Texts,Pcms,Times2)

#数式たちを準備
tpt1 = prepare_lines(ax1,lines1)
tpt2 = prepare_lines(ax2,lines2)
tpt3 = prepare_lines(ax1,lines3)
tpt4 = prepare_lines(ax2,lines4)
TPTs = [tpt1,tpt2,tpt3,tpt4]
for obj in TPTs[2][0]+TPTs[2][1]+TPTs[3][0]+TPTs[3][1]:
    obj.set_visible(False)

#イージング関数
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 appear_line(i,pcm):
    C = np.ones(len(pcm.get_array()))
    C[:v_show*i+1] = 0
    C[v_show*i+1:v_show*i+20] = np.arange(0.05,1.00,0.05)
    pcm.set_array(C)

#複数行を徐々に見せていく関数
def show_lines(i,ax,tpt):
    Texts,Pcms,Times2 = tpt
    n = np.argmin(~(i<Times2))
    Times2 = np.append(0,Times2)
    k = i-Times2[n]
    if n==0:
        appear_line(k,Pcms[0])
    elif n%2 == 1:
        appear_line(k,Pcms[n//2+1])
    else:
        alpha = (k+1)/t_next
        Texts[n//2-1].set_alpha(easing(1-alpha))
        top = -(n//2-1)-easing(alpha)
        ax.set_ylim(top-2,top)
        
#セクションを判定する関数
def section(i): 
    n = np.argmin(~(i<endings[1:]))
    k = i-endings[n]
    keys = list(periods.keys())
    key = keys[n]
    pre = keys[n-1]
    return k,key,pre

#台本の構成
periods = {"C1":50,"C2":50,
           "A1":30,"S1":tpt1[2][-1],"P1":20,"S2":tpt2[2][-1],"P2":40,
           "C3":50,"C4":20,"C5":50,
           "A2":30,"S3":tpt3[2][-1],"P3":20,"S4":tpt4[2][-1],"P4":40,
           "C6":50,"C7":50,"C8":20}
endings = np.cumsum(list(periods.values()))
endings = np.append(0,endings)

#上演
def update(i):
    
    k,key,pre = section(i)
    index = int(key[-1])-1
    
    if "A" in key:
        alpha = easing(k/19)
        atama.set_alpha(alpha)
        atama.get_bbox_patch().set_alpha(alpha)
    elif "S" in key:
        show_lines(k,axs[index%2],TPTs[index])
    
    if k == 0:
        if "C" in key:
            comments[index].set_visible(True)
        if "C" in pre:
            pre_index = int(pre[-1])-1
            comments[pre_index].set_visible(False)
        
        if "C2" in key:
            kata3.set_visible(True)
        elif "A1" in key:
            kata3.set_visible(False)
        elif "C5" in key:
            kata3.set_text("偶数")
            kata3.set_visible(True)
        elif "A2" in key:
            kata1.set_text("偶数")
            atama.set_text("3進数で考えます")
            atama.get_bbox_patch().set_facecolor("royalblue")
            for obj in TPTs[0][0]+TPTs[0][1]+TPTs[1][0]+TPTs[1][1]+[kata2,kata3]:
                obj.set_visible(False)
            for obj in TPTs[2][0]+TPTs[2][1]+TPTs[3][0]+TPTs[3][1]:
                obj.set_visible(True)
            for ax in axs:
                ax.set_ylim(-2,0)

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