admin
commited on
Commit
·
cc646d3
1
Parent(s):
5e217aa
upl base
Browse files- .gitignore +10 -0
- app.py +164 -0
- output_util.py +14 -0
- requirements.txt +4 -0
- sgntools.py +35 -0
- solution.py +148 -0
- solutions/e.py +70 -0
- solutions/eq.py +182 -0
- solutions/pi.py +140 -0
- solutions/pin.py +191 -0
.gitignore
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.idea/
|
2 |
+
.vscode/
|
3 |
+
workdir/mathjax-full/
|
4 |
+
workdir/res.html
|
5 |
+
workdir/pre/mma2sympy_input.txt
|
6 |
+
workdir/pre/mma2sympy_output.py
|
7 |
+
pre.nb
|
8 |
+
*__pycache__*
|
9 |
+
test.*
|
10 |
+
rename.sh
|
app.py
ADDED
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import gradio as gr
|
3 |
+
from sympy.core.numbers import Rational
|
4 |
+
from solution import BadInput, solutions
|
5 |
+
|
6 |
+
|
7 |
+
def generate_md(args_dict, name):
|
8 |
+
try:
|
9 |
+
ans_latex = solutions[name](**args_dict).get_latex_ans()
|
10 |
+
|
11 |
+
except BadInput as e:
|
12 |
+
return f"输入错误, 请输入有效的数字: {e}"
|
13 |
+
|
14 |
+
return f"注意到 $${ans_latex}$$ 证毕!"
|
15 |
+
|
16 |
+
|
17 |
+
def float_to_fraction(x):
|
18 |
+
x_str = "{0:.10f}".format(x).rstrip("0").rstrip(".") # 移除小数点后的无效零
|
19 |
+
|
20 |
+
# 检查是否为整数
|
21 |
+
if "." not in x_str:
|
22 |
+
return Rational(x_str), Rational(1)
|
23 |
+
|
24 |
+
# 分割整数部分和小数部分
|
25 |
+
integer_part, decimal_part = x_str.split(".")
|
26 |
+
decimal_digits = len(decimal_part)
|
27 |
+
|
28 |
+
# 构造分子和分母
|
29 |
+
numerator = int(integer_part + decimal_part)
|
30 |
+
denominator = 10**decimal_digits
|
31 |
+
|
32 |
+
# 简化分数
|
33 |
+
gcd_value = 1
|
34 |
+
a = numerator
|
35 |
+
b = denominator
|
36 |
+
while b != 0:
|
37 |
+
a, b = b, a % b
|
38 |
+
gcd_value = a
|
39 |
+
|
40 |
+
p = Rational(numerator // gcd_value)
|
41 |
+
q = Rational(denominator // gcd_value)
|
42 |
+
return p, q
|
43 |
+
|
44 |
+
|
45 |
+
def infer_pi(p, q):
|
46 |
+
if q == 0:
|
47 |
+
return "分母不能为 0 !"
|
48 |
+
|
49 |
+
p, q = float_to_fraction(p / q)
|
50 |
+
args_dict = {"p": p, "q": q}
|
51 |
+
return generate_md(args_dict, "π")
|
52 |
+
|
53 |
+
|
54 |
+
def infer_e(p, q):
|
55 |
+
if q == 0:
|
56 |
+
return "分母不能为 0 !"
|
57 |
+
|
58 |
+
p, q = float_to_fraction(p / q)
|
59 |
+
args_dict = {"p": p, "q": q}
|
60 |
+
return generate_md(args_dict, "e")
|
61 |
+
|
62 |
+
|
63 |
+
def infer_eq(q1, q2, u, v):
|
64 |
+
if q2 == 0 or v == 0:
|
65 |
+
return "分母不能为 0 !"
|
66 |
+
|
67 |
+
q1, q2 = float_to_fraction(q1 / q2)
|
68 |
+
u, v = float_to_fraction(u / v)
|
69 |
+
args_dict = {"q1": q1, "q2": q2, "u": u, "v": v}
|
70 |
+
return generate_md(args_dict, "e^q")
|
71 |
+
|
72 |
+
|
73 |
+
def infer_pin(n: int, p, q):
|
74 |
+
if q == 0:
|
75 |
+
return "分母不能为 0 !"
|
76 |
+
|
77 |
+
p, q = float_to_fraction(p / q)
|
78 |
+
args_dict = {"n": n, "p": p, "q": q}
|
79 |
+
return generate_md(args_dict, "π^n")
|
80 |
+
|
81 |
+
|
82 |
+
if __name__ == "__main__":
|
83 |
+
os.chdir(os.path.dirname(__file__))
|
84 |
+
for file_name in os.listdir("solutions"):
|
85 |
+
if not file_name.endswith(".py"):
|
86 |
+
continue
|
87 |
+
|
88 |
+
__import__(f"solutions.{file_name[:-3]}")
|
89 |
+
|
90 |
+
with gr.Blocks() as demo:
|
91 |
+
gr.Markdown("# “注意到”证明法比较大小")
|
92 |
+
with gr.Tabs():
|
93 |
+
with gr.TabItem("π"):
|
94 |
+
gr.Interface(
|
95 |
+
fn=infer_pi,
|
96 |
+
inputs=[
|
97 |
+
gr.Number(label="p", value=314),
|
98 |
+
gr.Number(label="q", value=100),
|
99 |
+
],
|
100 |
+
outputs=gr.Markdown(
|
101 |
+
value="#### 证明结果",
|
102 |
+
show_copy_button=True,
|
103 |
+
container=True,
|
104 |
+
min_height=122,
|
105 |
+
),
|
106 |
+
title="比较 π 与 p/q 大小",
|
107 |
+
allow_flagging="never",
|
108 |
+
)
|
109 |
+
|
110 |
+
with gr.TabItem("e"):
|
111 |
+
gr.Interface(
|
112 |
+
fn=infer_e,
|
113 |
+
inputs=[
|
114 |
+
gr.Number(label="p", value=2718),
|
115 |
+
gr.Number(label="q", value=1000),
|
116 |
+
],
|
117 |
+
outputs=gr.Markdown(
|
118 |
+
value="#### 证明结果",
|
119 |
+
show_copy_button=True,
|
120 |
+
container=True,
|
121 |
+
min_height=122,
|
122 |
+
),
|
123 |
+
title="比较 e 与 p/q 大小",
|
124 |
+
allow_flagging="never",
|
125 |
+
)
|
126 |
+
|
127 |
+
with gr.TabItem("e^q"):
|
128 |
+
gr.Interface(
|
129 |
+
fn=infer_eq,
|
130 |
+
inputs=[
|
131 |
+
gr.Number(label="p", value=3),
|
132 |
+
gr.Number(label="q", value=4),
|
133 |
+
gr.Number(label="u", value=2117),
|
134 |
+
gr.Number(label="v", value=1000),
|
135 |
+
],
|
136 |
+
outputs=gr.Markdown(
|
137 |
+
value="#### 证明结果",
|
138 |
+
show_copy_button=True,
|
139 |
+
container=True,
|
140 |
+
min_height=122,
|
141 |
+
),
|
142 |
+
title="比较 e^(p/q) 与 u/v 大小",
|
143 |
+
allow_flagging="never",
|
144 |
+
)
|
145 |
+
|
146 |
+
with gr.TabItem("π^n"):
|
147 |
+
gr.Interface(
|
148 |
+
fn=infer_pin,
|
149 |
+
inputs=[
|
150 |
+
gr.Number(label="n", value=3, step=1),
|
151 |
+
gr.Number(label="p", value=31),
|
152 |
+
gr.Number(label="q", value=1),
|
153 |
+
],
|
154 |
+
outputs=gr.Markdown(
|
155 |
+
value="#### 证明结果",
|
156 |
+
show_copy_button=True,
|
157 |
+
container=True,
|
158 |
+
min_height=122,
|
159 |
+
),
|
160 |
+
title="比较 π^n 与 p/q 大小",
|
161 |
+
allow_flagging="never",
|
162 |
+
)
|
163 |
+
|
164 |
+
demo.launch()
|
output_util.py
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from sympy import latex
|
2 |
+
|
3 |
+
|
4 |
+
def to_latex(expr, is_coeff=False):
|
5 |
+
return "" if is_coeff and expr == 1 else f"{{{latex(expr)}}}"
|
6 |
+
|
7 |
+
|
8 |
+
def to_latexes(*args, is_coeff=False):
|
9 |
+
return [to_latex(i, is_coeff=is_coeff) for i in args]
|
10 |
+
|
11 |
+
|
12 |
+
sign2cmp = {1: ">", -1: "<"}
|
13 |
+
|
14 |
+
sign2cmp_inv = {1: "<", -1: ">"}
|
requirements.txt
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
sympy~=1.12
|
2 |
+
pywebview~=5.3.2
|
3 |
+
ttkbootstrap~=1.10.1
|
4 |
+
gradio
|
sgntools.py
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
def sgns(*args):
|
2 |
+
for i in args:
|
3 |
+
if i < 0:
|
4 |
+
break
|
5 |
+
else:
|
6 |
+
return 1
|
7 |
+
|
8 |
+
for i in args:
|
9 |
+
if i > 0:
|
10 |
+
break
|
11 |
+
else:
|
12 |
+
return -1
|
13 |
+
|
14 |
+
return 0
|
15 |
+
|
16 |
+
|
17 |
+
def sq_func_sgn(a, b, c):
|
18 |
+
r"""
|
19 |
+
let f(x) = a+bx+cx^2, x \in [0, 1]
|
20 |
+
:return: f(x)>=0? 1; f(x)<=0? -1; 0
|
21 |
+
"""
|
22 |
+
f0 = a
|
23 |
+
f1 = a + b + c
|
24 |
+
fm = 0
|
25 |
+
|
26 |
+
if c != 0:
|
27 |
+
x_m = -b / (2 * c)
|
28 |
+
if 0 <= x_m <= 1:
|
29 |
+
fm = a + b * x_m + c * x_m**2
|
30 |
+
|
31 |
+
return sgns(f0, f1, fm)
|
32 |
+
|
33 |
+
|
34 |
+
def lin_func_sgn(a, b):
|
35 |
+
return sgns(a, a + b)
|
solution.py
ADDED
@@ -0,0 +1,148 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from typing import Iterable, Callable
|
2 |
+
from sympy import Eq, linsolve, simplify, latex, Expr, Symbol
|
3 |
+
|
4 |
+
|
5 |
+
class CannotCalculate(Exception):
|
6 |
+
pass
|
7 |
+
|
8 |
+
|
9 |
+
class BadInput(Exception):
|
10 |
+
pass
|
11 |
+
|
12 |
+
|
13 |
+
CONSTANT_TERM_KEY = "constant_term"
|
14 |
+
|
15 |
+
|
16 |
+
class GetIntegrate:
|
17 |
+
integrate_result_classes: dict[str, Expr | None]
|
18 |
+
|
19 |
+
def integrate_and_separate(
|
20 |
+
self, integrate_formula: Expr, integrate_args: tuple
|
21 |
+
) -> dict[str, Expr]:
|
22 |
+
"""
|
23 |
+
解积分,分离各项
|
24 |
+
"""
|
25 |
+
raise NotImplementedError(
|
26 |
+
"该函数已弃用,请使用 GetIntegrateFromData 类。如果想要使用它预处理,见 pre/old_solution.py"
|
27 |
+
)
|
28 |
+
# # 解积分
|
29 |
+
# res = integrate(integrate_formula, integrate_args)
|
30 |
+
# res = expand(expand(res))
|
31 |
+
# print(f'integrate[0,1] {integrate_formula}={res}')
|
32 |
+
#
|
33 |
+
# # 分离各项
|
34 |
+
# di = {}
|
35 |
+
# exprs = []
|
36 |
+
# for key, expr in self.integrate_result_classes.items():
|
37 |
+
# if key == CONSTANT_TERM_KEY:
|
38 |
+
# continue
|
39 |
+
# exprs.append(expr)
|
40 |
+
# di[key] = res.coeff(expr)
|
41 |
+
#
|
42 |
+
# constant_term, _ = res.as_independent(*exprs)
|
43 |
+
# return {**di, CONSTANT_TERM_KEY: constant_term}
|
44 |
+
|
45 |
+
def get_integrate_args(self, try_arg):
|
46 |
+
"""
|
47 |
+
:return: integrand_function, (independent_variable, lower_limit, upper_limit)
|
48 |
+
被积函数, (自变量, 下限, 上限)
|
49 |
+
"""
|
50 |
+
raise NotImplementedError()
|
51 |
+
|
52 |
+
def tries(self, try_arg):
|
53 |
+
"""
|
54 |
+
:return: {term_name: coefficient_of_the_term}
|
55 |
+
{该项的名称: 该项系数}
|
56 |
+
"""
|
57 |
+
return self.integrate_and_separate(*self.get_integrate_args(try_arg))
|
58 |
+
|
59 |
+
def get_latex(self, try_arg, subs):
|
60 |
+
expr, args = self.get_integrate_args(try_arg)
|
61 |
+
expr = simplify(expr).subs(subs)
|
62 |
+
sym, low, high = args
|
63 |
+
return r"\int_{%s}^{%s} {%s} \mathrm{d} {%s}" % (
|
64 |
+
low,
|
65 |
+
high,
|
66 |
+
latex(simplify(expr)),
|
67 |
+
sym,
|
68 |
+
)
|
69 |
+
|
70 |
+
|
71 |
+
class GetIntegrateFromData(GetIntegrate):
|
72 |
+
data: dict[object, dict[str, Expr]]
|
73 |
+
|
74 |
+
def tries(self, try_arg):
|
75 |
+
return self.data[try_arg]
|
76 |
+
|
77 |
+
|
78 |
+
class Solution:
|
79 |
+
get_integrate: GetIntegrate
|
80 |
+
# gui: Pattern
|
81 |
+
|
82 |
+
get_tries_args: Callable[[], Iterable[Expr]]
|
83 |
+
"""
|
84 |
+
Generate try_arg for each trial
|
85 |
+
生成每一次尝试的 try_arg
|
86 |
+
"""
|
87 |
+
|
88 |
+
symbols: tuple[Symbol, ...]
|
89 |
+
"""
|
90 |
+
The undetermined variable to solve.
|
91 |
+
要求的待定系数
|
92 |
+
"""
|
93 |
+
|
94 |
+
integrate_result_classes_eq: dict[str, Expr]
|
95 |
+
"""
|
96 |
+
{term_name: coefficient}
|
97 |
+
The value to which each term's coefficient is equal.
|
98 |
+
每个项系数分别要等于的值
|
99 |
+
"""
|
100 |
+
|
101 |
+
check_sgn: Callable
|
102 |
+
"""
|
103 |
+
Input: unpacked solution of undetermined variables;
|
104 |
+
Output: 0 (cannot determine), 1 or -1 (can determine; 1 and -1 are interchangeable for greater or less than).
|
105 |
+
Module sgntools provides lin_func_sgn and sq_func_sgn. Call help() for further details.
|
106 |
+
|
107 |
+
输入:解包的待定系数的值列表;
|
108 |
+
输出: 0(无法确定), 1或-1(可以确定, 1和-1哪个代表大于、哪个代表小于, 是可以互换的)
|
109 |
+
sgntools 模块提供了 lin_func_sgn 和 sq_func_sgn 函数,详见 help()
|
110 |
+
"""
|
111 |
+
# check_sgn: Callable[?, 1 | 0 | -1]
|
112 |
+
|
113 |
+
def get_symbols(self, separate_result):
|
114 |
+
"""凑积分结果系数"""
|
115 |
+
system = [
|
116 |
+
Eq(int_term, self.integrate_result_classes_eq[key])
|
117 |
+
for key, int_term in separate_result.items()
|
118 |
+
]
|
119 |
+
print(f"{system=}")
|
120 |
+
return linsolve(system, *self.symbols)
|
121 |
+
|
122 |
+
def try_times(self) -> tuple[Expr, dict, int] | tuple[None, None, None]:
|
123 |
+
for try_arg in self.get_tries_args():
|
124 |
+
separate = self.get_integrate.tries(try_arg)
|
125 |
+
for symbol_solution in self.get_symbols(separate):
|
126 |
+
if sgn := self.check_sgn(*symbol_solution):
|
127 |
+
return try_arg, dict(zip(self.symbols, symbol_solution)), sgn
|
128 |
+
|
129 |
+
return None, None, None
|
130 |
+
|
131 |
+
def get_latex_ans(self):
|
132 |
+
"""
|
133 |
+
:return: None if it can't be solved; Otherwise, LaTeX (without "$$")
|
134 |
+
"""
|
135 |
+
raise NotImplementedError()
|
136 |
+
|
137 |
+
|
138 |
+
# 插件注册(历史遗留问题)
|
139 |
+
solutions = {}
|
140 |
+
solution_sort = []
|
141 |
+
|
142 |
+
|
143 |
+
def register(name, solution, top=False):
|
144 |
+
solutions[name] = solution
|
145 |
+
if top:
|
146 |
+
solution_sort.insert(0, name)
|
147 |
+
else:
|
148 |
+
solution_sort.append(name)
|
solutions/e.py
ADDED
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from sympy import *
|
2 |
+
from sympy.abc import a, b, x
|
3 |
+
from output_util import to_latex, sign2cmp
|
4 |
+
from sgntools import lin_func_sgn
|
5 |
+
from solution import *
|
6 |
+
|
7 |
+
_data = {
|
8 |
+
1: {"constant_term": 3 * a - 8 * b, "e_term": -a + 3 * b},
|
9 |
+
2: {"constant_term": -38 * a + 174 * b, "e_term": 14 * a - 64 * b},
|
10 |
+
3: {"constant_term": 1158 * a - 7584 * b, "e_term": -426 * a + 2790 * b},
|
11 |
+
4: {"constant_term": -65304 * a + 557400 * b, "e_term": 24024 * a - 205056 * b},
|
12 |
+
5: {
|
13 |
+
"constant_term": 5900520 * a - 62118720 * b,
|
14 |
+
"e_term": -2170680 * a + 22852200 * b,
|
15 |
+
},
|
16 |
+
6: {
|
17 |
+
"constant_term": -780827760 * a + 9778048560 * b,
|
18 |
+
"e_term": 287250480 * a - 3597143040 * b,
|
19 |
+
},
|
20 |
+
}
|
21 |
+
|
22 |
+
|
23 |
+
class EIntegrate(GetIntegrateFromData):
|
24 |
+
# sympy 算力不够,以下由 MMA 算出
|
25 |
+
data = _data
|
26 |
+
|
27 |
+
def get_integrate_args(self, n):
|
28 |
+
return x**n * (1 - x) ** n * (a + b * x) * exp(x), (x, 0, 1)
|
29 |
+
|
30 |
+
|
31 |
+
class ESolution(Solution):
|
32 |
+
def __init__(self, p, q):
|
33 |
+
self.p = p
|
34 |
+
self.q = q
|
35 |
+
|
36 |
+
if self.q == 0:
|
37 |
+
raise BadInput()
|
38 |
+
|
39 |
+
self.get_integrate = EIntegrate()
|
40 |
+
self.symbols = (a, b)
|
41 |
+
|
42 |
+
self.integrate_result_classes_eq = {
|
43 |
+
"e_term": q,
|
44 |
+
CONSTANT_TERM_KEY: -p,
|
45 |
+
}
|
46 |
+
# check
|
47 |
+
self.check_sgn = lin_func_sgn
|
48 |
+
|
49 |
+
@staticmethod
|
50 |
+
def get_tries_args():
|
51 |
+
return EIntegrate.data.keys()
|
52 |
+
|
53 |
+
def get_latex_ans(self):
|
54 |
+
try_arg, symbol_val, sgn = self.try_times()
|
55 |
+
print(f"{(try_arg, symbol_val, sgn)=}")
|
56 |
+
|
57 |
+
if try_arg is None:
|
58 |
+
return None
|
59 |
+
|
60 |
+
p = to_latex(self.p)
|
61 |
+
q = to_latex(self.q, is_coeff=True)
|
62 |
+
I = self.get_integrate.get_latex(try_arg, symbol_val)
|
63 |
+
return rf"{q}e-{p} = {I} {sign2cmp[sgn]} 0"
|
64 |
+
|
65 |
+
|
66 |
+
register("e", ESolution)
|
67 |
+
|
68 |
+
|
69 |
+
if __name__ == "__main__":
|
70 |
+
print(ESolution(25, 9))
|
solutions/eq.py
ADDED
@@ -0,0 +1,182 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from sympy import *
|
2 |
+
from sympy.abc import *
|
3 |
+
from output_util import to_latex, sign2cmp, to_latexes
|
4 |
+
from sgntools import lin_func_sgn
|
5 |
+
from solution import *
|
6 |
+
|
7 |
+
_data = {
|
8 |
+
(1,): {
|
9 |
+
"constant_term": a / q**2 + 2 * a / q**3 - 2 * b / q**3 - 6 * b / q**4,
|
10 |
+
"eq_term": a / q**2 - 2 * a / q**3 + b / q**2 - 4 * b / q**3 + 6 * b / q**4,
|
11 |
+
},
|
12 |
+
(2,): {
|
13 |
+
"constant_term": -2 * a / q**3
|
14 |
+
- 12 * a / q**4
|
15 |
+
- 24 * a / q**5
|
16 |
+
+ 6 * b / q**4
|
17 |
+
+ 48 * b / q**5
|
18 |
+
+ 120 * b / q**6,
|
19 |
+
"eq_term": 2 * a / q**3
|
20 |
+
- 12 * a / q**4
|
21 |
+
+ 24 * a / q**5
|
22 |
+
+ 2 * b / q**3
|
23 |
+
- 18 * b / q**4
|
24 |
+
+ 72 * b / q**5
|
25 |
+
- 120 * b / q**6,
|
26 |
+
},
|
27 |
+
(3,): {
|
28 |
+
"constant_term": 6 * a / q**4
|
29 |
+
+ 72 * a / q**5
|
30 |
+
+ 360 * a / q**6
|
31 |
+
+ 720 * a / q**7
|
32 |
+
- 24 * b / q**5
|
33 |
+
- 360 * b / q**6
|
34 |
+
- 2160 * b / q**7
|
35 |
+
- 5040 * b / q**8,
|
36 |
+
"eq_term": 6 * a / q**4
|
37 |
+
- 72 * a / q**5
|
38 |
+
+ 360 * a / q**6
|
39 |
+
- 720 * a / q**7
|
40 |
+
+ 6 * b / q**4
|
41 |
+
- 96 * b / q**5
|
42 |
+
+ 720 * b / q**6
|
43 |
+
- 2880 * b / q**7
|
44 |
+
+ 5040 * b / q**8,
|
45 |
+
},
|
46 |
+
(4,): {
|
47 |
+
"constant_term": -24 * a / q**5
|
48 |
+
- 480 * a / q**6
|
49 |
+
- 4320 * a / q**7
|
50 |
+
- 20160 * a / q**8
|
51 |
+
- 40320 * a / q**9
|
52 |
+
+ 120 * b / q**6
|
53 |
+
+ 2880 * b / q**7
|
54 |
+
+ 30240 * b / q**8
|
55 |
+
+ 161280 * b / q**9
|
56 |
+
+ 362880 * b / q**10,
|
57 |
+
"eq_term": 24 * a / q**5
|
58 |
+
- 480 * a / q**6
|
59 |
+
+ 4320 * a / q**7
|
60 |
+
- 20160 * a / q**8
|
61 |
+
+ 40320 * a / q**9
|
62 |
+
+ 24 * b / q**5
|
63 |
+
- 600 * b / q**6
|
64 |
+
+ 7200 * b / q**7
|
65 |
+
- 50400 * b / q**8
|
66 |
+
+ 201600 * b / q**9
|
67 |
+
- 362880 * b / q**10,
|
68 |
+
},
|
69 |
+
(5,): {
|
70 |
+
"constant_term": 120 * a / q**6
|
71 |
+
+ 3600 * a / q**7
|
72 |
+
+ 50400 * a / q**8
|
73 |
+
+ 403200 * a / q**9
|
74 |
+
+ 1814400 * a / q**10
|
75 |
+
+ 3628800 * a / q**11
|
76 |
+
- 720 * b / q**7
|
77 |
+
- 25200 * b / q**8
|
78 |
+
- 403200 * b / q**9
|
79 |
+
- 3628800 * b / q**10
|
80 |
+
- 18144000 * b / q**11
|
81 |
+
- 39916800 * b / q**12,
|
82 |
+
"eq_term": 120 * a / q**6
|
83 |
+
- 3600 * a / q**7
|
84 |
+
+ 50400 * a / q**8
|
85 |
+
- 403200 * a / q**9
|
86 |
+
+ 1814400 * a / q**10
|
87 |
+
- 3628800 * a / q**11
|
88 |
+
+ 120 * b / q**6
|
89 |
+
- 4320 * b / q**7
|
90 |
+
+ 75600 * b / q**8
|
91 |
+
- 806400 * b / q**9
|
92 |
+
+ 5443200 * b / q**10
|
93 |
+
- 21772800 * b / q**11
|
94 |
+
+ 39916800 * b / q**12,
|
95 |
+
},
|
96 |
+
(6,): {
|
97 |
+
"constant_term": -720 * a / q**7
|
98 |
+
- 30240 * a / q**8
|
99 |
+
- 604800 * a / q**9
|
100 |
+
- 7257600 * a / q**10
|
101 |
+
- 54432000 * a / q**11
|
102 |
+
- 239500800 * a / q**12
|
103 |
+
- 479001600 * a / q**13
|
104 |
+
+ 5040 * b / q**8
|
105 |
+
+ 241920 * b / q**9
|
106 |
+
+ 5443200 * b / q**10
|
107 |
+
+ 72576000 * b / q**11
|
108 |
+
+ 598752000 * b / q**12
|
109 |
+
+ 2874009600 * b / q**13
|
110 |
+
+ 6227020800 * b / q**14,
|
111 |
+
"eq_term": 720 * a / q**7
|
112 |
+
- 30240 * a / q**8
|
113 |
+
+ 604800 * a / q**9
|
114 |
+
- 7257600 * a / q**10
|
115 |
+
+ 54432000 * a / q**11
|
116 |
+
- 239500800 * a / q**12
|
117 |
+
+ 479001600 * a / q**13
|
118 |
+
+ 720 * b / q**7
|
119 |
+
- 35280 * b / q**8
|
120 |
+
+ 846720 * b / q**9
|
121 |
+
- 12700800 * b / q**10
|
122 |
+
+ 127008000 * b / q**11
|
123 |
+
- 838252800 * b / q**12
|
124 |
+
+ 3353011200 * b / q**13
|
125 |
+
- 6227020800 * b / q**14,
|
126 |
+
},
|
127 |
+
}
|
128 |
+
|
129 |
+
|
130 |
+
class EQIntegrate(GetIntegrateFromData):
|
131 |
+
data = _data
|
132 |
+
|
133 |
+
def get_integrate_args(self, try_arg):
|
134 |
+
n, q = try_arg
|
135 |
+
return x**n * (1 - x) ** n * (a + b * x) * e ** (q * x), (x, 0, 1)
|
136 |
+
|
137 |
+
def tries(self, try_arg):
|
138 |
+
n, q_value = try_arg
|
139 |
+
return {key: expr.subs(q, q_value) for key, expr in self.data[(n,)].items()}
|
140 |
+
|
141 |
+
|
142 |
+
class EQSolution(Solution):
|
143 |
+
def __init__(self, q1, q2, u, v):
|
144 |
+
if q2 == 0 or v == 0:
|
145 |
+
raise BadInput()
|
146 |
+
|
147 |
+
self.q = q1 / q2 # 输入都是 Rational 类型的,可以不损失精度相除
|
148 |
+
self.u = u
|
149 |
+
self.v = v
|
150 |
+
|
151 |
+
self.get_integrate = EQIntegrate()
|
152 |
+
self.symbols = (a, b)
|
153 |
+
|
154 |
+
self.integrate_result_classes_eq = {
|
155 |
+
"eq_term": v,
|
156 |
+
CONSTANT_TERM_KEY: -u,
|
157 |
+
}
|
158 |
+
# check
|
159 |
+
self.check_sgn = lin_func_sgn
|
160 |
+
|
161 |
+
def get_tries_args(self):
|
162 |
+
for (n,) in EQIntegrate.data.keys():
|
163 |
+
yield n, self.q
|
164 |
+
|
165 |
+
def get_latex_ans(self):
|
166 |
+
try_arg, symbol_val, sgn = self.try_times()
|
167 |
+
print(f"{(try_arg, symbol_val, sgn)=}")
|
168 |
+
|
169 |
+
if try_arg is None:
|
170 |
+
return None
|
171 |
+
|
172 |
+
u, q = to_latexes(self.u, self.q)
|
173 |
+
v = to_latex(self.v, is_coeff=True)
|
174 |
+
I = self.get_integrate.get_latex(try_arg, symbol_val)
|
175 |
+
return rf"{v}e^{q}-{u} = {I} {sign2cmp[sgn]} 0"
|
176 |
+
|
177 |
+
|
178 |
+
register("e^q", EQSolution)
|
179 |
+
|
180 |
+
|
181 |
+
if __name__ == "__main__":
|
182 |
+
print(EQSolution(Rational(2), 1, 7, 1).get_latex_ans())
|
solutions/pi.py
ADDED
@@ -0,0 +1,140 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from sympy.abc import a, b, c, x
|
2 |
+
from output_util import to_latex, sign2cmp
|
3 |
+
from sgntools import sq_func_sgn
|
4 |
+
from solution import *
|
5 |
+
|
6 |
+
|
7 |
+
class PiIntegrate(GetIntegrateFromData):
|
8 |
+
# sympy 算力不够,以下由 MMA 算出
|
9 |
+
# PiIF[n_] :=
|
10 |
+
# Collect[ Collect[
|
11 |
+
# PowerExpand[ Expand[
|
12 |
+
# Integrate[x^n*(1 - x)^n*(a + b x + c x^2)/(x^2 + 1),
|
13 |
+
# {x, 0, 1}]
|
14 |
+
# ]],
|
15 |
+
# Log[2]], Pi]
|
16 |
+
|
17 |
+
data = {
|
18 |
+
1: {
|
19 |
+
"pi_term": (a - b - c) / 4,
|
20 |
+
"log2_term": (a + b - c) / 2,
|
21 |
+
CONSTANT_TERM_KEY: -a + b / 2 + 7 * c / 6,
|
22 |
+
},
|
23 |
+
2: {
|
24 |
+
"pi_term": -b / 2,
|
25 |
+
"log2_term": a - c,
|
26 |
+
CONSTANT_TERM_KEY: (-2 * a / 3 + 19 * b / 12 + 7 * c / 10),
|
27 |
+
},
|
28 |
+
3: {
|
29 |
+
"pi_term": (-a - b + c) / 2,
|
30 |
+
"log2_term": a - b - c,
|
31 |
+
CONSTANT_TERM_KEY: 53 * a / 60 + 34 * b / 15 - 92 * c / 105,
|
32 |
+
},
|
33 |
+
4: {
|
34 |
+
"pi_term": -a + c,
|
35 |
+
"log2_term": 2 * b,
|
36 |
+
CONSTANT_TERM_KEY: 22 * a / 7 + 233 * b / 168 - 1979 * c / 630,
|
37 |
+
},
|
38 |
+
5: {
|
39 |
+
"pi_term": -a + b + c,
|
40 |
+
"log2_term": 2 * (-a - b + c),
|
41 |
+
CONSTANT_TERM_KEY: 11411 * a / 2520 - 4423 * b / 2520 - 41837 * c / 9240,
|
42 |
+
},
|
43 |
+
6: {
|
44 |
+
"pi_term": 2 * b,
|
45 |
+
"log2_term": -4 * a + 4 * c,
|
46 |
+
CONSTANT_TERM_KEY: (38429 * a) / 13860
|
47 |
+
- (174169 * b) / 27720
|
48 |
+
- (35683 * c) / 12870,
|
49 |
+
},
|
50 |
+
7: {
|
51 |
+
"pi_term": 2 * (a + b - c),
|
52 |
+
"log2_term": 4 * (-a + b + c),
|
53 |
+
CONSTANT_TERM_KEY: -((421691 * a) / 120120)
|
54 |
+
- (407917 * b) / 45045
|
55 |
+
+ (31627 * c) / 9009,
|
56 |
+
},
|
57 |
+
8: {
|
58 |
+
"pi_term": 4 * (a - c),
|
59 |
+
"log2_term": 8 * b,
|
60 |
+
CONSTANT_TERM_KEY: -(188684 * a) / 15015
|
61 |
+
- (1332173 * b) / 240240
|
62 |
+
+ (3849155 * c) / 306306,
|
63 |
+
},
|
64 |
+
9: {
|
65 |
+
"pi_term": 4 * (a - b - c),
|
66 |
+
"log2_term": 8 * (-c + a + b),
|
67 |
+
CONSTANT_TERM_KEY: -((17069771 * a) / 942480)
|
68 |
+
+ (86025349 * b) / 12252240
|
69 |
+
+ (4216233689 * c) / 232792560,
|
70 |
+
},
|
71 |
+
10: {
|
72 |
+
"pi_term": -8 * b,
|
73 |
+
"log2_term": 16 * (a - c),
|
74 |
+
CONSTANT_TERM_KEY: -((1290876029 * a) / 116396280)
|
75 |
+
+ (325039733 * b) / 12932920
|
76 |
+
+ (117352369 * c) / 10581480,
|
77 |
+
},
|
78 |
+
11: {
|
79 |
+
"pi_term": 8 * (-a - b + c),
|
80 |
+
"log2_term": 16 * (a - b - c),
|
81 |
+
CONSTANT_TERM_KEY: (817240769 * a) / 58198140
|
82 |
+
+ (4216233641 * b) / 116396280
|
83 |
+
- (37593075209 * c) / 2677114440,
|
84 |
+
},
|
85 |
+
12: {
|
86 |
+
"pi_term": -16 * a + 16 * c,
|
87 |
+
"log2_term": -32 * b,
|
88 |
+
CONSTANT_TERM_KEY: (431302721 * a) / 8580495
|
89 |
+
+ (9135430531 * b) / 411863760
|
90 |
+
- (5902037233 * c) / 117417300,
|
91 |
+
},
|
92 |
+
}
|
93 |
+
|
94 |
+
def get_integrate_args(self, n):
|
95 |
+
return x**n * (1 - x) ** n * (a + b * x + c * x**2) / (1 + x**2), (x, 0, 1)
|
96 |
+
|
97 |
+
|
98 |
+
class PiSolution(Solution):
|
99 |
+
def __init__(self, p, q):
|
100 |
+
self.p = p
|
101 |
+
self.q = q
|
102 |
+
|
103 |
+
if self.q == 0:
|
104 |
+
raise BadInput()
|
105 |
+
|
106 |
+
self.get_integrate = PiIntegrate()
|
107 |
+
self.symbols = (a, b, c)
|
108 |
+
|
109 |
+
self.integrate_result_classes_eq = {
|
110 |
+
"pi_term": q,
|
111 |
+
"log2_term": 0,
|
112 |
+
CONSTANT_TERM_KEY: -p,
|
113 |
+
}
|
114 |
+
# check
|
115 |
+
self.check_sgn = sq_func_sgn
|
116 |
+
|
117 |
+
@staticmethod
|
118 |
+
def get_tries_args():
|
119 |
+
return PiIntegrate.data.keys()
|
120 |
+
|
121 |
+
def get_latex_ans(self):
|
122 |
+
try_arg, symbol_val, sgn = self.try_times()
|
123 |
+
print(f"{(try_arg, symbol_val, sgn)=}")
|
124 |
+
|
125 |
+
if try_arg is None:
|
126 |
+
return None
|
127 |
+
|
128 |
+
p = to_latex(self.p)
|
129 |
+
q = to_latex(self.q, is_coeff=True)
|
130 |
+
I = self.get_integrate.get_latex(try_arg, symbol_val)
|
131 |
+
return rf"{q}\pi-{p} = {I} {sign2cmp[sgn]} 0"
|
132 |
+
|
133 |
+
|
134 |
+
register("π", PiSolution, top=True)
|
135 |
+
|
136 |
+
if __name__ == "__main__":
|
137 |
+
while True:
|
138 |
+
p = int(input(">>> "))
|
139 |
+
q = int(input(" / "))
|
140 |
+
print(PiSolution(p, q).get_latex_ans())
|
solutions/pin.py
ADDED
@@ -0,0 +1,191 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from sympy import *
|
2 |
+
from sympy.abc import a, b, x
|
3 |
+
from output_util import to_latex, sign2cmp, to_latexes
|
4 |
+
from sgntools import lin_func_sgn
|
5 |
+
from solution import *
|
6 |
+
|
7 |
+
_data = {
|
8 |
+
(1, 2): {"constant_term": a - 2 * b / 3, "pin_term": -a / 4 + b / 4},
|
9 |
+
(1, 4): {"constant_term": -2 * a / 3 + 13 * b / 15, "pin_term": a / 4 - b / 4},
|
10 |
+
(1, 6): {"constant_term": 13 * a / 15 - 76 * b / 105, "pin_term": -a / 4 + b / 4},
|
11 |
+
(1, 8): {"constant_term": -76 * a / 105 + 263 * b / 315, "pin_term": a / 4 - b / 4},
|
12 |
+
(1, 10): {
|
13 |
+
"constant_term": 263 * a / 315 - 2578 * b / 3465,
|
14 |
+
"pin_term": -a / 4 + b / 4,
|
15 |
+
},
|
16 |
+
(1, 12): {
|
17 |
+
"constant_term": -2578 * a / 3465 + 36979 * b / 45045,
|
18 |
+
"pin_term": a / 4 - b / 4,
|
19 |
+
},
|
20 |
+
(2, 3): {"constant_term": a / 4 - 3 * b / 16, "pin_term": -a / 48 + b / 48},
|
21 |
+
(2, 5): {"constant_term": -3 * a / 16 + 31 * b / 144, "pin_term": a / 48 - b / 48},
|
22 |
+
(2, 7): {
|
23 |
+
"constant_term": 31 * a / 144 - 115 * b / 576,
|
24 |
+
"pin_term": -a / 48 + b / 48,
|
25 |
+
},
|
26 |
+
(2, 9): {
|
27 |
+
"constant_term": -115 * a / 576 + 3019 * b / 14400,
|
28 |
+
"pin_term": a / 48 - b / 48,
|
29 |
+
},
|
30 |
+
(2, 11): {
|
31 |
+
"constant_term": 3019 * a / 14400 - 973 * b / 4800,
|
32 |
+
"pin_term": -a / 48 + b / 48,
|
33 |
+
},
|
34 |
+
(2, 13): {
|
35 |
+
"constant_term": -973 * a / 4800 + 48877 * b / 235200,
|
36 |
+
"pin_term": a / 48 - b / 48,
|
37 |
+
},
|
38 |
+
(3, 2): {"constant_term": 2 * a - 52 * b / 27, "pin_term": -a / 16 + b / 16},
|
39 |
+
(3, 4): {
|
40 |
+
"constant_term": -52 * a / 27 + 6554 * b / 3375,
|
41 |
+
"pin_term": a / 16 - b / 16,
|
42 |
+
},
|
43 |
+
(3, 6): {
|
44 |
+
"constant_term": 6554 * a / 3375 - 2241272 * b / 1157625,
|
45 |
+
"pin_term": -a / 16 + b / 16,
|
46 |
+
},
|
47 |
+
(3, 8): {
|
48 |
+
"constant_term": -2241272 * a / 1157625 + 60600094 * b / 31255875,
|
49 |
+
"pin_term": a / 16 - b / 16,
|
50 |
+
},
|
51 |
+
(3, 10): {
|
52 |
+
"constant_term": 60600094 * a / 31255875 - 80596213364 * b / 41601569625,
|
53 |
+
"pin_term": -a / 16 + b / 16,
|
54 |
+
},
|
55 |
+
(3, 12): {
|
56 |
+
"constant_term": -80596213364 * a / 41601569625
|
57 |
+
+ 177153083899958 * b / 91398648466125,
|
58 |
+
"pin_term": a / 16 - b / 16,
|
59 |
+
},
|
60 |
+
(4, 3): {
|
61 |
+
"constant_term": 3 * a / 8 - 45 * b / 128,
|
62 |
+
"pin_term": -7 * a / 1920 + 7 * b / 1920,
|
63 |
+
},
|
64 |
+
(4, 5): {
|
65 |
+
"constant_term": -45 * a / 128 + 1231 * b / 3456,
|
66 |
+
"pin_term": 7 * a / 1920 - 7 * b / 1920,
|
67 |
+
},
|
68 |
+
(4, 7): {
|
69 |
+
"constant_term": 1231 * a / 3456 - 19615 * b / 55296,
|
70 |
+
"pin_term": -7 * a / 1920 + 7 * b / 1920,
|
71 |
+
},
|
72 |
+
(4, 9): {
|
73 |
+
"constant_term": -19615 * a / 55296 + 12280111 * b / 34560000,
|
74 |
+
"pin_term": 7 * a / 1920 - 7 * b / 1920,
|
75 |
+
},
|
76 |
+
(4, 11): {
|
77 |
+
"constant_term": 12280111 * a / 34560000 - 4090037 * b / 11520000,
|
78 |
+
"pin_term": -7 * a / 1920 + 7 * b / 1920,
|
79 |
+
},
|
80 |
+
(4, 13): {
|
81 |
+
"constant_term": -4090037 * a / 11520000 + 9824498837 * b / 27659520000,
|
82 |
+
"pin_term": 7 * a / 1920 - 7 * b / 1920,
|
83 |
+
},
|
84 |
+
(5, 2): {
|
85 |
+
"constant_term": 24 * a - 1936 * b / 81,
|
86 |
+
"pin_term": -5 * a / 64 + 5 * b / 64,
|
87 |
+
},
|
88 |
+
(5, 4): {
|
89 |
+
"constant_term": -1936 * a / 81 + 6051944 * b / 253125,
|
90 |
+
"pin_term": 5 * a / 64 - 5 * b / 64,
|
91 |
+
},
|
92 |
+
(5, 6): {
|
93 |
+
"constant_term": 6051944 * a / 253125 - 101708947808 * b / 4254271875,
|
94 |
+
"pin_term": -5 * a / 64 + 5 * b / 64,
|
95 |
+
},
|
96 |
+
(5, 8): {
|
97 |
+
"constant_term": -101708947808 * a / 4254271875
|
98 |
+
+ 24715694492344 * b / 1033788065625,
|
99 |
+
"pin_term": 5 * a / 64 - 5 * b / 64,
|
100 |
+
},
|
101 |
+
(5, 10): {
|
102 |
+
"constant_term": 24715694492344 * a / 1033788065625
|
103 |
+
- 3980462502772918544 * b / 166492601756971875,
|
104 |
+
"pin_term": -5 * a / 64 + 5 * b / 64,
|
105 |
+
},
|
106 |
+
(5, 12): {
|
107 |
+
"constant_term": -3980462502772918544 * a / 166492601756971875
|
108 |
+
+ 1477921859864507412282392 * b / 61817537584151358384375,
|
109 |
+
"pin_term": 5 * a / 64 - 5 * b / 64,
|
110 |
+
},
|
111 |
+
(6, 3): {
|
112 |
+
"constant_term": 15 * a / 8 - 945 * b / 512,
|
113 |
+
"pin_term": -31 * a / 16128 + 31 * b / 16128,
|
114 |
+
},
|
115 |
+
(6, 5): {
|
116 |
+
"constant_term": -945 * a / 512 + 229955 * b / 124416,
|
117 |
+
"pin_term": 31 * a / 16128 - 31 * b / 16128,
|
118 |
+
},
|
119 |
+
(6, 7): {
|
120 |
+
"constant_term": 229955 * a / 124416 - 14713475 * b / 7962624,
|
121 |
+
"pin_term": -31 * a / 16128 + 31 * b / 16128,
|
122 |
+
},
|
123 |
+
(6, 9): {
|
124 |
+
"constant_term": -14713475 * a / 7962624 + 45982595359 * b / 24883200000,
|
125 |
+
"pin_term": 31 * a / 16128 - 31 * b / 16128,
|
126 |
+
},
|
127 |
+
(6, 11): {
|
128 |
+
"constant_term": 45982595359 * a / 24883200000 - 5109066151 * b / 2764800000,
|
129 |
+
"pin_term": -31 * a / 16128 + 31 * b / 16128,
|
130 |
+
},
|
131 |
+
(6, 13): {
|
132 |
+
"constant_term": -5109066151 * a / 2764800000
|
133 |
+
+ 601081707598999 * b / 325275955200000,
|
134 |
+
"pin_term": 31 * a / 16128 - 31 * b / 16128,
|
135 |
+
},
|
136 |
+
}
|
137 |
+
|
138 |
+
|
139 |
+
class PiNIntegrate(GetIntegrateFromData):
|
140 |
+
data = _data
|
141 |
+
|
142 |
+
def get_integrate_args(self, args):
|
143 |
+
n, m = args
|
144 |
+
return x**m * (a + b * x**2) * (log(1 / x)) ** (n - 1) / (1 + x**2), (x, 0, 1)
|
145 |
+
|
146 |
+
|
147 |
+
class PiNSolution(Solution):
|
148 |
+
def __init__(self, n, p, q):
|
149 |
+
if n < 0:
|
150 |
+
n = -n
|
151 |
+
p, q = q, p
|
152 |
+
self.n = n
|
153 |
+
self.p = p
|
154 |
+
self.q = q
|
155 |
+
|
156 |
+
if self.q == 0:
|
157 |
+
raise BadInput()
|
158 |
+
|
159 |
+
self.get_integrate = PiNIntegrate()
|
160 |
+
self.symbols = (a, b)
|
161 |
+
|
162 |
+
self.integrate_result_classes_eq = {
|
163 |
+
"pin_term": q,
|
164 |
+
CONSTANT_TERM_KEY: -p,
|
165 |
+
}
|
166 |
+
# check
|
167 |
+
self.check_sgn = lin_func_sgn
|
168 |
+
|
169 |
+
def get_tries_args(self):
|
170 |
+
for n, m in PiNIntegrate.data.keys():
|
171 |
+
if n == self.n:
|
172 |
+
yield n, m
|
173 |
+
|
174 |
+
def get_latex_ans(self):
|
175 |
+
try_arg, symbol_val, sgn = self.try_times()
|
176 |
+
print(f"{(try_arg, symbol_val, sgn)=}")
|
177 |
+
|
178 |
+
if try_arg is None:
|
179 |
+
return None
|
180 |
+
|
181 |
+
p, n = to_latexes(self.p, self.n)
|
182 |
+
q = to_latex(self.q, is_coeff=True)
|
183 |
+
I = self.get_integrate.get_latex(try_arg, symbol_val)
|
184 |
+
return rf"{q}\pi^{n}-{p} = {I} {sign2cmp[sgn]} 0"
|
185 |
+
|
186 |
+
|
187 |
+
register("π^n", PiNSolution)
|
188 |
+
|
189 |
+
|
190 |
+
if __name__ == "__main__":
|
191 |
+
print(PiNSolution(3, 31, 1).get_latex_ans())
|