🗑️ Clean up code
This commit is contained in:
		
							
								
								
									
										390
									
								
								lib/solver.dart
									
									
									
									
									
								
							
							
						
						
									
										390
									
								
								lib/solver.dart
									
									
									
									
									
								
							| @@ -189,22 +189,21 @@ class SolverService { | |||||||
|     // Keep original equation for display |     // Keep original equation for display | ||||||
|     final originalEquation = _formatOriginalEquation(input); |     final originalEquation = _formatOriginalEquation(input); | ||||||
|  |  | ||||||
|     // Parse coefficients symbolically |     // Parse coefficients symbolically (kept for potential future use) | ||||||
|     final leftCoeffsSymbolic = _parsePolynomialSymbolic(eqParts[0]); |     // final leftCoeffsSymbolic = _parsePolynomialSymbolic(eqParts[0]); | ||||||
|     final rightCoeffsSymbolic = _parsePolynomialSymbolic(eqParts[1]); |     // final rightCoeffsSymbolic = _parsePolynomialSymbolic(eqParts[1]); | ||||||
|  |     // final aSymbolic = _subtractCoefficients( | ||||||
|     final aSymbolic = _subtractCoefficients( |     //   leftCoeffsSymbolic[2] ?? '0', | ||||||
|       leftCoeffsSymbolic[2] ?? '0', |     //   rightCoeffsSymbolic[2] ?? '0', | ||||||
|       rightCoeffsSymbolic[2] ?? '0', |     // ); | ||||||
|     ); |     // final bSymbolic = _subtractCoefficients( | ||||||
|     final bSymbolic = _subtractCoefficients( |     //   leftCoeffsSymbolic[1] ?? '0', | ||||||
|       leftCoeffsSymbolic[1] ?? '0', |     //   rightCoeffsSymbolic[1] ?? '0', | ||||||
|       rightCoeffsSymbolic[1] ?? '0', |     // ); | ||||||
|     ); |     // final cSymbolic = _subtractCoefficients( | ||||||
|     final cSymbolic = _subtractCoefficients( |     //   leftCoeffsSymbolic[0] ?? '0', | ||||||
|       leftCoeffsSymbolic[0] ?? '0', |     //   rightCoeffsSymbolic[0] ?? '0', | ||||||
|       rightCoeffsSymbolic[0] ?? '0', |     // ); | ||||||
|     ); |  | ||||||
|  |  | ||||||
|     // Also get numeric values for calculations |     // Also get numeric values for calculations | ||||||
|     final leftCoeffs = _parsePolynomial(eqParts[0]); |     final leftCoeffs = _parsePolynomial(eqParts[0]); | ||||||
| @@ -288,9 +287,6 @@ class SolverService { | |||||||
|  |  | ||||||
|     // Step 2: Move constant term to the other side |     // Step 2: Move constant term to the other side | ||||||
|     final constantTerm = c / a; |     final constantTerm = c / a; | ||||||
|     final constantStr = constantTerm >= 0 |  | ||||||
|         ? '+${constantTerm}' |  | ||||||
|         : constantTerm.toString(); |  | ||||||
|  |  | ||||||
|     steps.add( |     steps.add( | ||||||
|       CalculationStep( |       CalculationStep( | ||||||
| @@ -1023,187 +1019,6 @@ ${b1}y &= ${c1 - a1 * x.toDouble()} | |||||||
|  |  | ||||||
|   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); | ||||||
|  |  | ||||||
|   /// 格式化 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) { |   String _formatOriginalEquation(String input) { | ||||||
|     // Parse the equation and convert to LaTeX |     // Parse the equation and convert to LaTeX | ||||||
| @@ -1365,181 +1180,6 @@ ${b1}y &= ${c1 - a1 * x.toDouble()} | |||||||
|     return result; |     return result; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /// 解析多项式,保持符号形式 |  | ||||||
|   Map<int, String> _parsePolynomialSymbolic(String side) { |  | ||||||
|     final coeffs = <int, String>{}; |  | ||||||
|  |  | ||||||
|     // 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 = <String>[]; |  | ||||||
|     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}) { |   Rational _rationalFromDouble(double value, {int maxPrecision = 12}) { | ||||||
|     // 限制小数精度,避免无限循环小数 |     // 限制小数精度,避免无限循环小数 | ||||||
|     final str = value.toStringAsFixed(maxPrecision); |     final str = value.toStringAsFixed(maxPrecision); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user