From 5a38c8595e5e20e8cfff94439dc64fa3e81c140b Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Tue, 16 Sep 2025 01:17:34 +0800 Subject: [PATCH] :wastebasket: Clean up code --- lib/solver.dart | 390 ++---------------------------------------------- 1 file changed, 15 insertions(+), 375 deletions(-) diff --git a/lib/solver.dart b/lib/solver.dart index 056bd38..653c75b 100644 --- a/lib/solver.dart +++ b/lib/solver.dart @@ -189,22 +189,21 @@ class SolverService { // Keep original equation for display final originalEquation = _formatOriginalEquation(input); - // Parse coefficients symbolically - final leftCoeffsSymbolic = _parsePolynomialSymbolic(eqParts[0]); - final rightCoeffsSymbolic = _parsePolynomialSymbolic(eqParts[1]); - - final aSymbolic = _subtractCoefficients( - leftCoeffsSymbolic[2] ?? '0', - rightCoeffsSymbolic[2] ?? '0', - ); - final bSymbolic = _subtractCoefficients( - leftCoeffsSymbolic[1] ?? '0', - rightCoeffsSymbolic[1] ?? '0', - ); - final cSymbolic = _subtractCoefficients( - leftCoeffsSymbolic[0] ?? '0', - rightCoeffsSymbolic[0] ?? '0', - ); + // Parse coefficients symbolically (kept for potential future use) + // final leftCoeffsSymbolic = _parsePolynomialSymbolic(eqParts[0]); + // final rightCoeffsSymbolic = _parsePolynomialSymbolic(eqParts[1]); + // final aSymbolic = _subtractCoefficients( + // leftCoeffsSymbolic[2] ?? '0', + // rightCoeffsSymbolic[2] ?? '0', + // ); + // final bSymbolic = _subtractCoefficients( + // leftCoeffsSymbolic[1] ?? '0', + // rightCoeffsSymbolic[1] ?? '0', + // ); + // final cSymbolic = _subtractCoefficients( + // leftCoeffsSymbolic[0] ?? '0', + // rightCoeffsSymbolic[0] ?? '0', + // ); // Also get numeric values for calculations final leftCoeffs = _parsePolynomial(eqParts[0]); @@ -288,9 +287,6 @@ class SolverService { // Step 2: Move constant term to the other side final constantTerm = c / a; - final constantStr = constantTerm >= 0 - ? '+${constantTerm}' - : constantTerm.toString(); steps.add( CalculationStep( @@ -1023,187 +1019,6 @@ ${b1}y &= ${c1 - a1 * x.toDouble()} int gcd(int a, int b) => b == 0 ? a : gcd(b, a % b); - /// 格式化 Rational 值的平方根表达式,保持符号形式 - String _formatSqrtFromRational(Rational value) { - if (value == Rational.zero) return '0'; - - // 处理负数(用于复数根) - if (value < Rational.zero) { - return '\\sqrt{${(-value).toBigInt()}}'; - } - - // 尝试将 Rational 转换为完全平方数的形式 - // 例如: 4/9 -> 2/3, 9/4 -> 3/2, 25/16 -> 5/4 等 - - // 首先简化分数 - final simplified = value; - - // 检查分子和分母是否都是完全平方数 - final numerator = simplified.numerator; - final denominator = simplified.denominator; - - // 寻找分子和分母的平方根因子 - BigInt sqrtNumerator = _findSquareRootFactor(numerator); - BigInt sqrtDenominator = _findSquareRootFactor(denominator); - - // 计算剩余的分子和分母 - final remainingNumerator = numerator ~/ (sqrtNumerator * sqrtNumerator); - final remainingDenominator = - denominator ~/ (sqrtDenominator * sqrtDenominator); - - // 构建结果 - String result = ''; - - // 处理系数部分 - if (sqrtNumerator > BigInt.one || sqrtDenominator > BigInt.one) { - if (sqrtNumerator > sqrtDenominator) { - final coeff = sqrtNumerator ~/ sqrtDenominator; - if (coeff > BigInt.one) { - result += '$coeff'; - } - } else if (sqrtDenominator > sqrtNumerator) { - // 这会导致分母,需要用分数表示 - final coeffNum = sqrtNumerator; - final coeffDen = sqrtDenominator; - if (coeffNum == BigInt.one) { - result += '\\frac{1}{$coeffDen}'; - } else { - result += '\\frac{$coeffNum}{$coeffDen}'; - } - } - } - - // 处理根号部分 - if (remainingNumerator == BigInt.one && - remainingDenominator == BigInt.one) { - // 没有根号部分 - if (result.isEmpty) { - return '1'; - } - } else if (remainingNumerator == remainingDenominator) { - // 根号部分约分后为1 - if (result.isEmpty) { - return '1'; - } - } else { - // 需要根号 - String sqrtContent = ''; - if (remainingDenominator == BigInt.one) { - sqrtContent = '$remainingNumerator'; - } else { - sqrtContent = '\\frac{$remainingNumerator}{$remainingDenominator}'; - } - - if (result.isEmpty) { - result = '\\sqrt{$sqrtContent}'; - } else { - result += '\\sqrt{$sqrtContent}'; - } - } - - return result.isEmpty ? '1' : result; - } - - /// 寻找一个大整数的平方根因子 - BigInt _findSquareRootFactor(BigInt n) { - if (n <= BigInt.one) return BigInt.one; - - BigInt factor = BigInt.one; - BigInt i = BigInt.two; - - while (i * i <= n) { - BigInt count = BigInt.zero; - while (n % (i * i) == BigInt.zero) { - n = n ~/ (i * i); - count += BigInt.one; - } - if (count > BigInt.zero) { - factor = factor * i; - } - i += BigInt.one; - } - - return factor; - } - - /// 格式化二次方程的根:(-b ± sqrt(delta)) / (2a) - String _formatQuadraticRoot( - double b, - Rational delta, - double denominator, - bool isPlus, - ) { - final denomInt = denominator.toInt(); - final denomStr = denominator == 2 ? '2' : denominator.toString(); - - // Format sqrt(delta) symbolically using the Rational value - final sqrtExpr = _formatSqrtFromRational(delta); - - if (b == 0) { - // 简化为 ±sqrt(delta)/denominator - if (denominator == 2) { - return isPlus ? '\\frac{$sqrtExpr}{2}' : '-\\frac{$sqrtExpr}{2}'; - } else { - return isPlus - ? '\\frac{$sqrtExpr}{$denomStr}' - : '-\\frac{$sqrtExpr}{$denomStr}'; - } - } else { - // 完整的表达式:(-b ± sqrt(delta))/denominator - final bInt = b.toInt(); - - // Check if b is divisible by denominator for simplification - if (bInt % denomInt == 0) { - // Can simplify: b/denominator becomes integer - final simplifiedB = bInt ~/ denomInt; - - if (simplifiedB == 0) { - // Just the sqrt part with correct sign - return isPlus ? sqrtExpr : '-$sqrtExpr'; - } else if (simplifiedB == 1) { - // +1 * sqrt part - return isPlus ? '1 + $sqrtExpr' : '1 - $sqrtExpr'; - } else if (simplifiedB == -1) { - // -1 * sqrt part - return isPlus ? '-1 + $sqrtExpr' : '-1 - $sqrtExpr'; - } else if (simplifiedB > 0) { - // Positive coefficient - return isPlus - ? '$simplifiedB + $sqrtExpr' - : '$simplifiedB - $sqrtExpr'; - } else { - // Negative coefficient - final absB = (-simplifiedB).toString(); - return isPlus ? '-$absB + $sqrtExpr' : '-$absB - $sqrtExpr'; - } - } else { - // Cannot simplify, use fraction form - final bStr = b > 0 ? '$bInt' : '($bInt)'; - final signStr = isPlus ? '+' : '-'; - final numerator = b > 0 - ? '-$bStr $signStr $sqrtExpr' - : '($bInt) $signStr $sqrtExpr'; - - if (denominator == 2) { - return '\\frac{$numerator}{2}'; - } else { - return '\\frac{$numerator}{$denomStr}'; - } - } - } - } - - /// 格式化复数根的虚部:sqrt(-delta)/(2a) - String _formatImaginaryPart(String sqrtExpr, double denominator) { - final denomStr = denominator == 2 ? '2' : denominator.toString(); - - if (denominator == 2) { - return '\\frac{\\sqrt{${sqrtExpr.replaceAll('\\sqrt{', '').replaceAll('}', '')}}}{2}i'; - } else { - return '\\frac{\\sqrt{${sqrtExpr.replaceAll('\\sqrt{', '').replaceAll('}', '')}}}{$denomStr}i'; - } - } - /// 格式化原始方程,保持符号形式 String _formatOriginalEquation(String input) { // Parse the equation and convert to LaTeX @@ -1365,181 +1180,6 @@ ${b1}y &= ${c1 - a1 * x.toDouble()} return result; } - /// 解析多项式,保持符号形式 - Map _parsePolynomialSymbolic(String side) { - final coeffs = {}; - - // Use a simpler approach: split by terms and parse each term individually - var s = side.replaceAll(' ', ''); // Remove spaces - if (!s.startsWith('+') && !s.startsWith('-')) { - s = '+$s'; - } - - // Split by + and - but be more careful about parentheses and functions - final terms = []; - int start = 0; - int parenDepth = 0; - - for (int i = 0; i < s.length; i++) { - final char = s[i]; - - if (char == '(') { - parenDepth++; - } else if (char == ')') { - parenDepth--; - } - - // Only split on + or - when not inside parentheses - if (parenDepth == 0 && (char == '+' || char == '-') && i > start) { - terms.add(s.substring(start, i)); - start = i; - } - } - terms.add(s.substring(start)); - - for (final term in terms) { - if (term.isEmpty) continue; - - // Parse each term - final termPattern = RegExp(r'^([+-]?)(.*?)x(?:\^(\d+))?$|^([+-]?)(.*?)$'); - final match = termPattern.firstMatch(term); - - if (match != null) { - if (match.group(5) != null) { - // Constant term - final sign = match.group(4) ?? '+'; - final value = match.group(5)!; - final coeffStr = sign == '+' && value.isNotEmpty - ? value - : '$sign$value'; - coeffs[0] = _combineCoefficients(coeffs[0], coeffStr); - } else { - // x term - final sign = match.group(1) ?? '+'; - final coeffPart = match.group(2) ?? ''; - final power = match.group(3) != null ? int.parse(match.group(3)!) : 1; - - String coeffStr; - if (coeffPart.isEmpty) { - coeffStr = sign == '+' ? '1' : '-1'; - } else { - coeffStr = sign == '+' ? coeffPart : '$sign$coeffPart'; - } - - coeffs[power] = _combineCoefficients(coeffs[power], coeffStr); - } - } - } - - return coeffs; - } - - /// 合并系数,保持符号形式 - String _combineCoefficients(String? existing, String newCoeff) { - if (existing == null || existing == '0') return newCoeff; - if (newCoeff == '0') return existing; - - // 简化逻辑:如果都是数字,可以相加;否则保持原样 - final existingNum = double.tryParse(existing); - final newNum = double.tryParse(newCoeff); - - if (existingNum != null && newNum != null) { - final sum = existingNum + newNum; - return sum.toString(); - } - - // 如果包含符号表达式,直接连接 - return '$existing+$newCoeff'.replaceAll('+-', '-'); - } - - /// 减去系数 - String _subtractCoefficients(String a, String b) { - if (a == '0') return b.startsWith('-') ? b.substring(1) : '-$b'; - if (b == '0') return a; - - final aNum = double.tryParse(a); - final bNum = double.tryParse(b); - - if (aNum != null && bNum != null) { - final result = aNum - bNum; - return result.toString(); - } - - // 符号表达式相减 - return '$a-${b.startsWith('-') ? b.substring(1) : b}'; - } - - /// 计算判别式,保持符号形式 - String _calculateDeltaSymbolic(String a, String b, String c) { - // Delta = b^2 - 4ac - - // 计算 b^2 - String bSquared; - if (b == '0') { - bSquared = '0'; - } else if (b == '1') { - bSquared = '1'; - } else if (b == '-1') { - bSquared = '1'; - } else if (b.startsWith('-')) { - final absB = b.substring(1); - bSquared = '$absB^2'; - } else { - bSquared = '$b^2'; - } - - // 计算 4ac - String fourAC; - if (a == '0' || c == '0') { - fourAC = '0'; - } else { - // 处理符号 - String aCoeff = a; - String cCoeff = c; - - // 如果 a 或 c 是负数,需要处理符号 - bool aNegative = a.startsWith('-'); - bool cNegative = c.startsWith('-'); - - if (aNegative) aCoeff = a.substring(1); - if (cNegative) cCoeff = c.substring(1); - - String acProduct; - if (aCoeff == '1' && cCoeff == '1') { - acProduct = '1'; - } else if (aCoeff == '1') { - acProduct = cCoeff; - } else if (cCoeff == '1') { - acProduct = aCoeff; - } else { - acProduct = '$aCoeff \\cdot $cCoeff'; - } - - // 确定 4ac 的符号 - bool productNegative = aNegative != cNegative; - String fourACValue = '4 \\cdot $acProduct'; - - if (productNegative) { - fourAC = '-$fourACValue'; - } else { - fourAC = fourACValue; - } - } - - // 计算 Delta = b^2 - 4ac - if (bSquared == '0' && fourAC == '0') { - return '0'; - } else if (bSquared == '0') { - return fourAC.startsWith('-') ? fourAC.substring(1) : '-$fourAC'; - } else if (fourAC == '0') { - return bSquared; - } else { - String sign = fourAC.startsWith('-') ? '+' : '-'; - String absFourAC = fourAC.startsWith('-') ? fourAC.substring(1) : fourAC; - return '$bSquared $sign $absFourAC'; - } - } - Rational _rationalFromDouble(double value, {int maxPrecision = 12}) { // 限制小数精度,避免无限循环小数 final str = value.toStringAsFixed(maxPrecision);