도호쿠 대학 2020년 전기 수학 시험(이계) 대문 1~3을 Python으로 풀어 보았다
기념해야 할 Qiita 첫 투고입니다, 잘 부탁드립니다!
평소에는 연구에서 Python을 사용하고 있습니다만, 최근에는 다양한 기술에 흥미가 나오고 조금씩 공부하고 있습니다.
본 투고는 전부터 한번 해보고 싶다고 생각하고 있어, GW는 시간도 있어, 좋은 기회라고 하는 것으로 써 보았습니다.
기술 부족·지식 부족 때문에, 효율이 나쁜 코딩이나 잘못된 이해등 있다고 생각합니다만, 초보자가 아웃풋 하기 위해서 쓰고 있으므로, 따뜻한 눈으로 봐 주실 수 있으면 다행입니다.
덧붙여 문제와 해답의 pdf는 이쪽에 있으므로, 적절히 참조해 주세요.
본 기사에서도 기본적으로는 해답의 풀기 방법에 따라 코딩해 갑니다.
문제
답변 1,4,5,6
답변 2,3
첫문
(1) 코사인 정리를 사용하는 것만 같네요.
(2) 3점 A, B, C의 좌표 설정을 잘 잡는 것으로, 변수 $s$의 존재를 점 P의 $y$ 좌표만으로 할 수 있어 약간 계산이 편해지네요.
이하, 해답 이미지입니다.

그럼 코딩해 갑니다.
1.py
# 初期条件
ab = 1
ac = 1
bc = 0.5
import numpy as np
# (1)
# 余弦定理
cos_theta = (ab**2 + ac**2 - bc**2) / (2 * ab * ac)
sin_theta = np.sqrt(1 - cos_theta**2)
print(cos_theta, sin_theta) # 0.875 0.484 = 7/8 (√15)/8
# (2)
# func = AP^2 + BP^2 + CP^2 とする
def func(s):
return 25/32 + 15/64 * ((3 * (s - 2/3)**2) + 2/3)
lis = [] # 変数 s と その時の func の値をタプルとして収納するリスト
# 0<s<1 を 0.01 ずつ変化させ、全探索
for s in np.arange(0,1,0.01):
value = func(s)
lis.append((s, value))
print(lis)
# min_value でソートし、最初の要素を出力
lis_sort = sorted(lis, key=lambda values: values[1])
print(lis_sort[0]) # (s, min_value) = (0.67, 0.9375)
두 번째 질문
(1) 솔직하게 직선 L, M의 교점을 찾아 원 C에 대입군요.
(2) 원 C의 중심과 직선 L의 거리가 원 C의 반경 (a)보다 작을 때 주제를 충족하네요.
(3) (2)와 같이, 점과 직선의 거리와 원C의 반경을 비교하는 것으로 공유점의 개수를 구해, 나머지는 어리석게 조사할 뿐이지요.
이것은 (2)의 부등호를 바꿀 뿐이므로 생략합니다.
이하, 해답 이미지입니다.

그럼 코딩해 갑니다.
2.py
import sympy
x = sympy.Symbol('x')
y = sympy.Symbol('y')
a = sympy.Symbol('a')
# (1)
expr1 = -4 * x + 3 * y + a
expr2 = 3 * x + 4 * y - 7 * a
d = sympy.solve([expr1, expr2], [x,y])
# print(d) # 直線L、Mの交点が (a, a) とわかる
# 円Cに(a, a)を代入
sympy.var('x, y, a')
x = d[x] # xに上で得た交点のx座標代入
y = d[y] # yに上で得た交点のy座標代入
sol = sympy.solve (1 * x**2 - 2 * a * x + y**2 - 4 * y + 4, a)
sympy.init_printing()
print(sol) # 解答のリスト(今回は 1 のみ)取得
# (2)
# 不等号の解はIntervalで区間の型にして、和集合を取ればよいが、今回は等式から境界値を求めて終わる
dis = abs(6 - 3 * a)/5
# dis^2 = abs(a)を両辺二乗して解く
expr3 = 16 * a**2 + 36 * a - 36
d2 = sympy.solve([expr3])
print(d2) # [{a: -3}, {a: 3/4}] 共有店の個数が変化する境界値
# (3)
# 省略
세 번째 질문
(1) 문제문을 보고, 확실히 떠오르는 해법으로서, 이하의 3가지가 있다고 생각합니다.
・수학적 귀납법
・식변형에 의한 부등식의 도출
·함수화: $f(n)=3^n-(2^n+n^2+8)$ 로서, $n≧3$ 로 $f(n)>0$ 인 것을 나타낸다
해답에서는 수학적 귀납법을 이용하고 있습니다만, 프로그래밍으로 해결한다는 관점에서 말하면, 함수화가 가장 간단하다고 생각합니다.
(2) (1)에서 $n≧3$ 에서 $f(n)>0$ 이라는 것을 나타내고 있으므로, $f(n)≤0$ 이 되기 위해서는 적어도 $n<3$ 이어야합니다. 또 이번 $n$ 는 양의 정수라고 하는 조건이 있기 때문에, $n=1,2$ 가 해의 후보인 것을 알 수 있습니다. 여기까지 알면, 나머지는 실제로 대입해 제목이 성립하는지 확인할 뿐이지요.
(3) $a,b,n$ 모두 0 이상이므로, 등식 $2^n+n^2+8=3^n+an+b$ 가 성립하는 것은, $n=1$ or $2 $ 전용.
이하, 해답 이미지입니다.

그럼 코딩해 갑니다.
3.py
# (1)
import math
# f(n)
def func(n):
return 3**n - (2**n + n**2 + 8)
# f'(n)
def func_p1(n):
return 3**n * math.log(3) - (2**n * math.log(2) + 2 * n)
# f''(n)
def func_p2(n):
return 3**n * math.log(3)**2 - 2**n * math.log(2)**2
# print(func_p2(3)) # 28.74 ← 0以上
# かつ n > 3 で func_p2(n) >0 (∵ 3**n >> 2**n)
# よって n > 3 で func_p1(n) は単調増加 ...(1)
# また print(func_p1(3)) # 18.11 ← 0以上 ...(2)
# (1),(2)より n > 3 で func(n)も単調増加 ...(3)
# さらに print(func(3)) # 2 ← 0以上 ...(4)
# したがって、(3),(4)より n >= 3 で func(n) > 0
# Q.E.D
# (2)
print(func(1), func(2)) # -8 -7 よって f(n) < 0 、ゆえに題意を満たす n は 1,2
# (3)
lis = [] # 解リスト
for a in range(9): # n,a,b >= 0 より、a,b は 0~8 で回せば十分
for b in range(9):
# n=1の時
jouken1 = a + b # joken1 = 8
# n=2の時
jouken2 = 2 * a + b # joken2 = 7
if jouken1 == 8:
lis.append((a,b,1))
elif jouken2 == 7:
lis.append((a,b,2))
else:
continue
print(lis)
#[(0, 7, 2), (0, 8, 1), (1, 5, 2), (1, 7, 1), (2, 3, 2), (2, 6, 1), (3, 1, 2), (3, 5, 1), (4, 4, 1), (5, 3, 1), (6, 2, 1), (7, 1, 1), (8, 0, 1)]
이번에는 여기서 끝내고 싶습니다.
남은 문제도 너무 여가해서 죽을 것 같으면 ww
처음으로 Python을 사용하여 연립 방정식을 풀었지만 훌륭합니다.
정말 뭐든지 할 수 있어요, 파이썬 굉장하다!
또 해보고 싶은 것, 재미있을 것 같은 것이 떠오르면, 느긋하게 해 나가려고 생각합니다.
봐 주셔서 감사합니다.
Reference
이 문제에 관하여(도호쿠 대학 2020년 전기 수학 시험(이계) 대문 1~3을 Python으로 풀어 보았다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/MatLaser/items/da6fe50bffdac83897ee
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
# 初期条件
ab = 1
ac = 1
bc = 0.5
import numpy as np
# (1)
# 余弦定理
cos_theta = (ab**2 + ac**2 - bc**2) / (2 * ab * ac)
sin_theta = np.sqrt(1 - cos_theta**2)
print(cos_theta, sin_theta) # 0.875 0.484 = 7/8 (√15)/8
# (2)
# func = AP^2 + BP^2 + CP^2 とする
def func(s):
return 25/32 + 15/64 * ((3 * (s - 2/3)**2) + 2/3)
lis = [] # 変数 s と その時の func の値をタプルとして収納するリスト
# 0<s<1 を 0.01 ずつ変化させ、全探索
for s in np.arange(0,1,0.01):
value = func(s)
lis.append((s, value))
print(lis)
# min_value でソートし、最初の要素を出力
lis_sort = sorted(lis, key=lambda values: values[1])
print(lis_sort[0]) # (s, min_value) = (0.67, 0.9375)
(1) 솔직하게 직선 L, M의 교점을 찾아 원 C에 대입군요.
(2) 원 C의 중심과 직선 L의 거리가 원 C의 반경 (a)보다 작을 때 주제를 충족하네요.
(3) (2)와 같이, 점과 직선의 거리와 원C의 반경을 비교하는 것으로 공유점의 개수를 구해, 나머지는 어리석게 조사할 뿐이지요.
이것은 (2)의 부등호를 바꿀 뿐이므로 생략합니다.
이하, 해답 이미지입니다.

그럼 코딩해 갑니다.
2.py
import sympy
x = sympy.Symbol('x')
y = sympy.Symbol('y')
a = sympy.Symbol('a')
# (1)
expr1 = -4 * x + 3 * y + a
expr2 = 3 * x + 4 * y - 7 * a
d = sympy.solve([expr1, expr2], [x,y])
# print(d) # 直線L、Mの交点が (a, a) とわかる
# 円Cに(a, a)を代入
sympy.var('x, y, a')
x = d[x] # xに上で得た交点のx座標代入
y = d[y] # yに上で得た交点のy座標代入
sol = sympy.solve (1 * x**2 - 2 * a * x + y**2 - 4 * y + 4, a)
sympy.init_printing()
print(sol) # 解答のリスト(今回は 1 のみ)取得
# (2)
# 不等号の解はIntervalで区間の型にして、和集合を取ればよいが、今回は等式から境界値を求めて終わる
dis = abs(6 - 3 * a)/5
# dis^2 = abs(a)を両辺二乗して解く
expr3 = 16 * a**2 + 36 * a - 36
d2 = sympy.solve([expr3])
print(d2) # [{a: -3}, {a: 3/4}] 共有店の個数が変化する境界値
# (3)
# 省略
세 번째 질문
(1) 문제문을 보고, 확실히 떠오르는 해법으로서, 이하의 3가지가 있다고 생각합니다.
・수학적 귀납법
・식변형에 의한 부등식의 도출
·함수화: $f(n)=3^n-(2^n+n^2+8)$ 로서, $n≧3$ 로 $f(n)>0$ 인 것을 나타낸다
해답에서는 수학적 귀납법을 이용하고 있습니다만, 프로그래밍으로 해결한다는 관점에서 말하면, 함수화가 가장 간단하다고 생각합니다.
(2) (1)에서 $n≧3$ 에서 $f(n)>0$ 이라는 것을 나타내고 있으므로, $f(n)≤0$ 이 되기 위해서는 적어도 $n<3$ 이어야합니다. 또 이번 $n$ 는 양의 정수라고 하는 조건이 있기 때문에, $n=1,2$ 가 해의 후보인 것을 알 수 있습니다. 여기까지 알면, 나머지는 실제로 대입해 제목이 성립하는지 확인할 뿐이지요.
(3) $a,b,n$ 모두 0 이상이므로, 등식 $2^n+n^2+8=3^n+an+b$ 가 성립하는 것은, $n=1$ or $2 $ 전용.
이하, 해답 이미지입니다.

그럼 코딩해 갑니다.
3.py
# (1)
import math
# f(n)
def func(n):
return 3**n - (2**n + n**2 + 8)
# f'(n)
def func_p1(n):
return 3**n * math.log(3) - (2**n * math.log(2) + 2 * n)
# f''(n)
def func_p2(n):
return 3**n * math.log(3)**2 - 2**n * math.log(2)**2
# print(func_p2(3)) # 28.74 ← 0以上
# かつ n > 3 で func_p2(n) >0 (∵ 3**n >> 2**n)
# よって n > 3 で func_p1(n) は単調増加 ...(1)
# また print(func_p1(3)) # 18.11 ← 0以上 ...(2)
# (1),(2)より n > 3 で func(n)も単調増加 ...(3)
# さらに print(func(3)) # 2 ← 0以上 ...(4)
# したがって、(3),(4)より n >= 3 で func(n) > 0
# Q.E.D
# (2)
print(func(1), func(2)) # -8 -7 よって f(n) < 0 、ゆえに題意を満たす n は 1,2
# (3)
lis = [] # 解リスト
for a in range(9): # n,a,b >= 0 より、a,b は 0~8 で回せば十分
for b in range(9):
# n=1の時
jouken1 = a + b # joken1 = 8
# n=2の時
jouken2 = 2 * a + b # joken2 = 7
if jouken1 == 8:
lis.append((a,b,1))
elif jouken2 == 7:
lis.append((a,b,2))
else:
continue
print(lis)
#[(0, 7, 2), (0, 8, 1), (1, 5, 2), (1, 7, 1), (2, 3, 2), (2, 6, 1), (3, 1, 2), (3, 5, 1), (4, 4, 1), (5, 3, 1), (6, 2, 1), (7, 1, 1), (8, 0, 1)]
이번에는 여기서 끝내고 싶습니다.
남은 문제도 너무 여가해서 죽을 것 같으면 ww
처음으로 Python을 사용하여 연립 방정식을 풀었지만 훌륭합니다.
정말 뭐든지 할 수 있어요, 파이썬 굉장하다!
또 해보고 싶은 것, 재미있을 것 같은 것이 떠오르면, 느긋하게 해 나가려고 생각합니다.
봐 주셔서 감사합니다.
Reference
이 문제에 관하여(도호쿠 대학 2020년 전기 수학 시험(이계) 대문 1~3을 Python으로 풀어 보았다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/MatLaser/items/da6fe50bffdac83897ee
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
# (1)
import math
# f(n)
def func(n):
return 3**n - (2**n + n**2 + 8)
# f'(n)
def func_p1(n):
return 3**n * math.log(3) - (2**n * math.log(2) + 2 * n)
# f''(n)
def func_p2(n):
return 3**n * math.log(3)**2 - 2**n * math.log(2)**2
# print(func_p2(3)) # 28.74 ← 0以上
# かつ n > 3 で func_p2(n) >0 (∵ 3**n >> 2**n)
# よって n > 3 で func_p1(n) は単調増加 ...(1)
# また print(func_p1(3)) # 18.11 ← 0以上 ...(2)
# (1),(2)より n > 3 で func(n)も単調増加 ...(3)
# さらに print(func(3)) # 2 ← 0以上 ...(4)
# したがって、(3),(4)より n >= 3 で func(n) > 0
# Q.E.D
# (2)
print(func(1), func(2)) # -8 -7 よって f(n) < 0 、ゆえに題意を満たす n は 1,2
# (3)
lis = [] # 解リスト
for a in range(9): # n,a,b >= 0 より、a,b は 0~8 で回せば十分
for b in range(9):
# n=1の時
jouken1 = a + b # joken1 = 8
# n=2の時
jouken2 = 2 * a + b # joken2 = 7
if jouken1 == 8:
lis.append((a,b,1))
elif jouken2 == 7:
lis.append((a,b,2))
else:
continue
print(lis)
#[(0, 7, 2), (0, 8, 1), (1, 5, 2), (1, 7, 1), (2, 3, 2), (2, 6, 1), (3, 1, 2), (3, 5, 1), (4, 4, 1), (5, 3, 1), (6, 2, 1), (7, 1, 1), (8, 0, 1)]
Reference
이 문제에 관하여(도호쿠 대학 2020년 전기 수학 시험(이계) 대문 1~3을 Python으로 풀어 보았다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/MatLaser/items/da6fe50bffdac83897ee텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)