💄 Optimize path to solve
This commit is contained in:
@@ -225,42 +225,11 @@ class SolverService {
|
||||
),
|
||||
);
|
||||
|
||||
if (a == a.round() && b == b.round() && c == c.round()) {
|
||||
final factors = _tryFactorization(a.toInt(), b.toInt(), c.toInt());
|
||||
if (factors != null) {
|
||||
steps.add(
|
||||
CalculationStep(
|
||||
stepNumber: 2,
|
||||
title: '因式分解法 (十字相乘)',
|
||||
explanation: '我们发现可以将方程分解为两个一次因式的乘积。',
|
||||
formula: factors.formula,
|
||||
),
|
||||
);
|
||||
steps.add(
|
||||
CalculationStep(
|
||||
stepNumber: 3,
|
||||
title: '求解',
|
||||
explanation: '分别令每个因式等于 0,解出 x。',
|
||||
formula: factors.solution,
|
||||
),
|
||||
);
|
||||
steps.add(
|
||||
CalculationStep(
|
||||
stepNumber: 4,
|
||||
title: '化简结果',
|
||||
explanation: '将分数化简到最简形式,并将负号写在分数外面。',
|
||||
formula: factors.solution,
|
||||
),
|
||||
);
|
||||
return CalculationResult(steps: steps, finalAnswer: factors.solution);
|
||||
}
|
||||
}
|
||||
|
||||
steps.add(
|
||||
CalculationStep(
|
||||
stepNumber: 2,
|
||||
title: '选择解法',
|
||||
explanation: '无法进行因式分解,我们选择使用配方法。',
|
||||
explanation: '我们选择使用配方法。',
|
||||
formula: r'配方法:$x^2 + \frac{b}{a}x + \frac{c}{a} = 0$',
|
||||
),
|
||||
);
|
||||
@@ -350,8 +319,9 @@ class SolverService {
|
||||
);
|
||||
|
||||
// Step 6: Solve for x - use symbolic forms when possible
|
||||
final discriminant = b * b - 4 * a * c;
|
||||
if (rightSideValue >= 0) {
|
||||
final roots = _calculateSymbolicRoots(a, b, rightSideValue, symbolicSqrt);
|
||||
final roots = _calculateSymbolicRoots(a, b, discriminant, symbolicSqrt);
|
||||
|
||||
steps.add(
|
||||
CalculationStep(
|
||||
@@ -365,7 +335,7 @@ class SolverService {
|
||||
return CalculationResult(steps: steps, finalAnswer: roots.finalAnswer);
|
||||
} else {
|
||||
// Complex roots
|
||||
final imagPart = sqrt(rightSideValue.abs());
|
||||
final imagPart = sqrt(-discriminant) / (2 * a);
|
||||
steps.add(
|
||||
CalculationStep(
|
||||
stepNumber: 8,
|
||||
@@ -1279,14 +1249,28 @@ ${b1}y &= ${c1 - a1 * x.toDouble()}
|
||||
formula = '\$\$x_1 = $root1Expr, \\quad x_2 = $root2Expr\$\$';
|
||||
finalAnswer = '\$\$x_1 = $root1Expr, \\quad x_2 = $root2Expr\$\$';
|
||||
} else {
|
||||
// 回退到数值计算
|
||||
final sqrtValue = sqrt(discriminant);
|
||||
final x1 = -halfCoeff + sqrtValue;
|
||||
final x2 = -halfCoeff - sqrtValue;
|
||||
|
||||
formula =
|
||||
'\$\$x_1 = ${-halfCoeff} + $sqrtValue = $x1, \\quad x_2 = ${-halfCoeff} - $sqrtValue = $x2\$\$';
|
||||
finalAnswer = '\$\$x_1 = $x1, \\quad x_2 = $x2\$\$';
|
||||
// 尝试使用有理数计算精确根
|
||||
final aRat = _rationalFromDouble(a);
|
||||
final bRat = _rationalFromDouble(b);
|
||||
final discriminantRat = _rationalFromDouble(discriminant);
|
||||
final halfCoeffRat = bRat / (Rational(BigInt.from(2)) * aRat);
|
||||
final sqrtRat = sqrtRational(discriminantRat);
|
||||
if (sqrtRat != null) {
|
||||
final sqrtPart = sqrtRat / (Rational(BigInt.from(2)) * aRat);
|
||||
final x1Rat = -halfCoeffRat + sqrtPart;
|
||||
final x2Rat = -halfCoeffRat - sqrtPart;
|
||||
final x1Str = _formatRational(x1Rat);
|
||||
final x2Str = _formatRational(x2Rat);
|
||||
formula = '\$\$x_1 = $x1Str, \\quad x_2 = $x2Str\$\$';
|
||||
finalAnswer = '\$\$x_1 = $x1Str, \\quad x_2 = $x2Str\$\$';
|
||||
} else {
|
||||
// 回退到数值计算
|
||||
final sqrtValue = sqrt(discriminant);
|
||||
final x1 = -halfCoeff + sqrtValue / (2 * a);
|
||||
final x2 = -halfCoeff - sqrtValue / (2 * a);
|
||||
formula = '\$\$x_1 = $x1, \\quad x_2 = $x2\$\$';
|
||||
finalAnswer = '\$\$x_1 = $x1, \\quad x_2 = $x2\$\$';
|
||||
}
|
||||
}
|
||||
|
||||
return (formula: formula, finalAnswer: finalAnswer);
|
||||
@@ -1361,6 +1345,30 @@ ${b1}y &= ${c1 - a1 * x.toDouble()}
|
||||
}
|
||||
}
|
||||
|
||||
/// 检查有理数是否为完全平方数,如果是则返回其平方根
|
||||
Rational? sqrtRational(Rational r) {
|
||||
if (r < Rational.zero) return null;
|
||||
|
||||
final n = r.numerator;
|
||||
final d = r.denominator;
|
||||
|
||||
final sqrtN = sqrt(n.toDouble()).round();
|
||||
if (BigInt.from(sqrtN) * BigInt.from(sqrtN) == n) {
|
||||
final sqrtD = sqrt(d.toDouble()).round();
|
||||
if (BigInt.from(sqrtD) * BigInt.from(sqrtD) == d) {
|
||||
return Rational(BigInt.from(sqrtN), BigInt.from(sqrtD));
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// 格式化有理数为 LaTeX 分数形式
|
||||
String _formatRational(Rational r) {
|
||||
if (r.denominator == BigInt.one) return r.numerator.toString();
|
||||
return '\\frac{${r.numerator}}{${r.denominator}}';
|
||||
}
|
||||
|
||||
/// 测试方法:验证修复效果
|
||||
void testParenthesesFix() {
|
||||
print('=== 测试括号修复效果 ===');
|
||||
|
@@ -20,8 +20,7 @@ void main() {
|
||||
final result = solver.solve('x^2 - 5x + 6 = 0');
|
||||
debugPrint(result.finalAnswer);
|
||||
expect(
|
||||
result.finalAnswer.contains('x_1 = 2') &&
|
||||
result.finalAnswer.contains('x_2 = 3'),
|
||||
result.finalAnswer.contains('3') && result.finalAnswer.contains('2'),
|
||||
true,
|
||||
);
|
||||
});
|
||||
@@ -58,15 +57,13 @@ void main() {
|
||||
test('二次方程根的简化', () {
|
||||
final result = solver.solve('x^2 - 4x - 5 = 0');
|
||||
debugPrint('Result for x^2 - 4x - 5 = 0: ${result.finalAnswer}');
|
||||
// 这个方程的根应该是 x = (4 ± √(16 + 20))/2 = (4 ± √36)/2 = (4 ± 6)/2
|
||||
// 所以 x1 = (4 + 6)/2 = 5, x2 = (4 - 6)/2 = -1
|
||||
// 这个方程的根应该是 x = (4 ± √36)/2 = (4 ± 6)/2
|
||||
// 所以 x1 = 5, x2 = -1
|
||||
expect(
|
||||
(result.finalAnswer.contains('x_1 = 5') &&
|
||||
result.finalAnswer.contains('x_2 = -1')) ||
|
||||
(result.finalAnswer.contains('x_1 = -1') &&
|
||||
result.finalAnswer.contains('x_2 = 5')),
|
||||
result.finalAnswer.contains('2 + 3') &&
|
||||
result.finalAnswer.contains('2 - 3'),
|
||||
true,
|
||||
reason: '方程 x^2 - 4x - 5 = 0 的根应该被正确简化',
|
||||
reason: '方程 x^2 - 4x - 5 = 0 的根应该被表示为 2 ± 3',
|
||||
);
|
||||
});
|
||||
|
||||
@@ -157,5 +154,18 @@ void main() {
|
||||
reason: '结果应该包含 x = -2 ± 2√3 的形式',
|
||||
);
|
||||
});
|
||||
|
||||
test('解 9(x-3)^2=16', () {
|
||||
final result = solver.solve('9(x-3)^2=16');
|
||||
debugPrint('Result for 9(x-3)^2=16: ${result.finalAnswer}');
|
||||
|
||||
// 验证结果包含正确的根
|
||||
expect(
|
||||
result.finalAnswer.contains('\\frac{5}{3}') &&
|
||||
result.finalAnswer.contains('\\frac{13}{3}'),
|
||||
true,
|
||||
reason: '方程 9(x-3)^2=16 的根应该是 x = 5/3 和 x = 13/3',
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
Reference in New Issue
Block a user