🐛 Fix solver issue on (x+3)^2-(1-2x)^2=0
This commit is contained in:
		| @@ -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), | ||||||
|   | |||||||
| @@ -529,13 +529,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 +560,41 @@ ${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 = root1Den == 1 ? '$root1Num' : '\\frac{$root1Num}{$root1Den}'; | ||||||
|     final f1 = c1 == 0 ? f1Part1 : '$f1Part1 ${c1 >= 0 ? '+' : ''} $c1'; |     String sol2 = root2Den == 1 ? '$root2Num' : '\\frac{$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); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   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); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user