Compare commits

...

2 Commits

Author SHA1 Message Date
0b2e7242b7 Simplify Result 2025-09-13 13:35:01 +08:00
b420ccca47 🐛 Fix solver issue on (x+3)^2-(1-2x)^2=0 2025-09-13 13:32:53 +08:00
2 changed files with 90 additions and 27 deletions

View File

@@ -300,6 +300,15 @@ class _CalculatorHomePageState extends State<CalculatorHomePage> {
), ),
), ),
), ),
Expanded(
child: Tooltip(
message: '未知数二号',
child: FilledButton.tonal(
onPressed: () => _insertSymbol('y'),
child: Text('y', style: GoogleFonts.robotoMono()),
),
),
),
], ],
), ),
const SizedBox(height: 8), const SizedBox(height: 8),

View File

@@ -120,7 +120,7 @@ class SolverService {
stepNumber: 3, stepNumber: 3,
title: '求解 x', title: '求解 x',
explanation: '两边同时除以 x 的系数 ($newA)。', explanation: '两边同时除以 x 的系数 ($newA)。',
formula: '\$\$x = \frac{$newD}{$newA}\$\$', formula: '\$\$x = \\frac{$newD}{$newA}\$\$',
), ),
); );
@@ -174,6 +174,14 @@ class SolverService {
formula: factors.solution, formula: factors.solution,
), ),
); );
steps.add(
CalculationStep(
stepNumber: 4,
title: '化简结果',
explanation: '将分数化简到最简形式,并将负号写在分数外面。',
formula: factors.solution,
),
);
return CalculationResult(steps: steps, finalAnswer: factors.solution); return CalculationResult(steps: steps, finalAnswer: factors.solution);
} }
} }
@@ -529,13 +537,29 @@ ${b1}y &= ${c1 - a1 * x}
({String formula, String solution})? _tryFactorization(int a, int b, int c) { ({String formula, String solution})? _tryFactorization(int a, int b, int c) {
if (a == 0) return null; if (a == 0) return null;
int ac = a * c; int ac = a * c;
for (int i = 1; i <= sqrt(ac.abs()); i++) { int absAc = ac.abs();
if (ac % i == 0) { for (int d = 1; d <= sqrt(absAc).toInt(); d++) {
int j = ac ~/ i; if (absAc % d == 0) {
if (check(i, j, b)) return formatFactor(i, j, a); int d1 = d;
if (check(-i, -j, b)) return formatFactor(-i, -j, a); int d2 = absAc ~/ d;
if (check(i, -j, b)) return formatFactor(i, -j, a); List<int> signs1 = ac >= 0 ? [1, -1] : [1, -1];
if (check(-i, j, b)) return formatFactor(-i, j, a); List<int> signs2 = ac >= 0 ? [1, -1] : [1, -1];
for (int s1 in signs1) {
for (int s2 in signs2) {
int m = s1 * d1;
int n = s2 * d2;
if (check(m, n, b)) return formatFactor(m, n, a);
m = s1 * d1;
n = s2 * (-d2);
if (check(m, n, b)) return formatFactor(m, n, a);
m = s1 * (-d1);
n = s2 * d2;
if (check(m, n, b)) return formatFactor(m, n, a);
m = s1 * (-d1);
n = s2 * (-d2);
if (check(m, n, b)) return formatFactor(m, n, a);
}
}
} }
} }
return null; return null;
@@ -544,32 +568,62 @@ ${b1}y &= ${c1 - a1 * x}
bool check(int m, int n, int b) => m + n == b; bool check(int m, int n, int b) => m + n == b;
({String formula, String solution}) formatFactor(int m, int n, int a) { ({String formula, String solution}) formatFactor(int m, int n, int a) {
int common = gcd(n.abs(), a.abs()); // Roots are -m/a and -n/a
int num = n ~/ common; int g1 = gcd(m.abs(), a.abs());
int den = a ~/ common; int root1Num = -m ~/ g1;
int root1Den = a ~/ g1;
final a1 = den; int g2 = gcd(n.abs(), a.abs());
final c1 = num; int root2Num = -n ~/ g2;
final a2 = a ~/ den; int root2Den = a ~/ g2;
final c2 = m ~/ a2;
final f1Part1 = a1 == 1 ? 'x' : '${a1}x'; String sol1 = _formatFraction(root1Num, root1Den);
final f1 = c1 == 0 ? f1Part1 : '$f1Part1 ${c1 >= 0 ? '+' : ''} $c1'; String sol2 = _formatFraction(root2Num, root2Den);
final f2Part1 = a2 == 1 ? 'x' : '${a2}x'; // For formula, show (a x + m)(x + n/a) or simplified
final f2 = c2 == 0 ? f2Part1 : '$f2Part1 ${c2 >= 0 ? '+' : ''} $c2'; String f1 = a == 1 ? 'x' : '${a}x';
f1 = m == 0 ? f1 : '$f1 ${m >= 0 ? '+' : ''} $m';
final int x1Num = -c1, x1Den = a1; String f2;
final int x2Num = -c2, x2Den = a2; if (n % a == 0) {
int coeff = n ~/ a;
f2 = 'x ${coeff >= 0 ? '+' : ''} $coeff';
if (coeff == 0) f2 = 'x';
} else {
f2 = 'x ${n >= 0 ? '+' : ''} \\frac{$n}{$a}';
}
final sol1 = x1Den == 1 ? '$x1Num' : '\\frac{$x1Num}{$x1Den}'; String formula = '\$\$($f1)($f2) = 0\$\$';
final sol2 = x2Den == 1 ? '$x2Num' : '\\frac{$x2Num}{$x2Den}';
final solution = x1Num * x2Den == x2Num * x1Den String solution;
? 'x_1 = x_2 = $sol1' if (root1Num * root2Den == root2Num * root1Den) {
: 'x_1 = $sol1, \\quad x_2 = $sol2'; solution = '\$\$x_1 = x_2 = $sol1\$\$';
} else {
solution = '\$\$x_1 = $sol1, \\quad x_2 = $sol2\$\$';
}
return (formula: '\$\$($f1)($f2) = 0\$\$', solution: '\$\$$solution\$\$'); return (formula: formula, solution: solution);
}
String _formatFraction(int num, int den) {
if (den == 0) return 'undefined';
// Handle sign: make numerator positive, put sign outside
bool isNegative = (num < 0) != (den < 0);
int absNum = num.abs();
int absDen = den.abs();
// Simplify fraction
int g = gcd(absNum, absDen);
absNum ~/= g;
absDen ~/= g;
if (absDen == 1) {
return isNegative ? '-$absNum' : '$absNum';
} else {
String fraction = '\\frac{$absNum}{$absDen}';
return isNegative ? '-$fraction' : fraction;
}
} }
int gcd(int a, int b) => b == 0 ? a : gcd(b, a % b); int gcd(int a, int b) => b == 0 ? a : gcd(b, a % b);