問題文
整数 $a,b$ は等式 $$3^a-2^b=1\quad\cdots\,\textstyle\unicode{x2780}$$ を満たしているとする。
- $a,b$ はともに正となることを示せ。
- $b\gt1$ ならば、 $a$ は偶数であることを示せ。
- ➀ を満たす整数の組 $(a,b)$ をすべてあげよ。
(2018 東北大学 理系第3問)
- 略
- 略
- $(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()