math-exercises 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/package.json +2 -2
  2. package/src/exercises/calcul/addAndSub.js +19 -13
  3. package/src/exercises/calcul/addAndSub.ts +31 -23
  4. package/src/exercises/calcul/fractions/fractionAndIntegerDivision.js +35 -0
  5. package/src/exercises/calcul/fractions/fractionAndIntegerDivision.ts +38 -0
  6. package/src/exercises/calcul/fractions/fractionAndIntegerProduct.js +31 -0
  7. package/src/exercises/calcul/fractions/fractionAndIntegerProduct.ts +32 -0
  8. package/src/exercises/calcul/fractions/fractionAndIntegerSum.js +32 -0
  9. package/src/exercises/calcul/fractions/fractionAndIntegerSum.ts +31 -0
  10. package/src/exercises/calcul/fractions/fractionsDivision.js +29 -0
  11. package/src/exercises/calcul/fractions/fractionsDivision.ts +30 -0
  12. package/src/exercises/calcul/fractions/fractionsProduct.js +29 -0
  13. package/src/exercises/calcul/fractions/fractionsProduct.ts +29 -0
  14. package/src/exercises/calcul/fractions/fractionsSum.js +29 -0
  15. package/src/exercises/calcul/fractions/fractionsSum.ts +28 -0
  16. package/src/exercises/calcul/fractions/simplifyFraction.js +25 -0
  17. package/src/exercises/calcul/fractions/simplifyFraction.ts +24 -0
  18. package/src/exercises/calcul/operationsPriorities.js +89 -0
  19. package/src/exercises/calcul/operationsPriorities.ts +118 -0
  20. package/src/exercises/calcul/rounding/roundToUnit.js +70 -0
  21. package/src/exercises/calcul/rounding/roundToUnit.ts +68 -0
  22. package/src/exercises/calculLitteral/distributivity/allIdentities.js +2 -0
  23. package/src/exercises/calculLitteral/distributivity/allIdentities.ts +2 -0
  24. package/src/exercises/calculLitteral/distributivity/doubleDistributivity.js +3 -3
  25. package/src/exercises/calculLitteral/distributivity/doubleDistributivity.ts +2 -0
  26. package/src/exercises/calculLitteral/distributivity/firstIdentity.js +2 -0
  27. package/src/exercises/calculLitteral/distributivity/firstIdentity.ts +2 -0
  28. package/src/exercises/calculLitteral/distributivity/secondIdentity.js +3 -3
  29. package/src/exercises/calculLitteral/distributivity/secondIdentity.ts +2 -0
  30. package/src/exercises/calculLitteral/distributivity/simpleDistributivity.js +3 -3
  31. package/src/exercises/calculLitteral/distributivity/simpleDistributivity.ts +2 -0
  32. package/src/exercises/calculLitteral/distributivity/thirdIdentity.js +4 -2
  33. package/src/exercises/calculLitteral/distributivity/thirdIdentity.ts +2 -0
  34. package/src/exercises/calculLitteral/equation/equationType1Exercise.js +3 -3
  35. package/src/exercises/calculLitteral/equation/equationType1Exercise.ts +4 -5
  36. package/src/exercises/calculLitteral/equation/equationType2Exercise.js +3 -3
  37. package/src/exercises/calculLitteral/equation/equationType2Exercise.ts +5 -5
  38. package/src/exercises/calculLitteral/equation/equationType3Exercise.js +3 -3
  39. package/src/exercises/calculLitteral/equation/equationType3Exercise.ts +5 -5
  40. package/src/exercises/calculLitteral/equation/equationType4Exercise.js +3 -3
  41. package/src/exercises/calculLitteral/equation/equationType4Exercise.ts +7 -12
  42. package/src/exercises/calculLitteral/factorisation/factoType1Exercise.js +4 -9
  43. package/src/exercises/calculLitteral/factorisation/factoType1Exercise.ts +3 -6
  44. package/src/exercises/calculLitteral/reduction.ts +27 -0
  45. package/src/exercises/exercise.ts +2 -0
  46. package/src/exercises/exercises.js +83 -0
  47. package/src/exercises/exercises.ts +58 -0
  48. package/src/exercises/powers/powersDivision.js +46 -0
  49. package/src/exercises/powers/powersDivision.ts +51 -0
  50. package/src/exercises/powers/powersOfTenToDecimal.js +33 -0
  51. package/src/exercises/powers/powersOfTenToDecimal.ts +37 -0
  52. package/src/exercises/powers/powersPower.js +45 -0
  53. package/src/exercises/powers/powersPower.ts +55 -0
  54. package/src/exercises/powers/powersProduct.js +46 -0
  55. package/src/exercises/powers/powersProduct.ts +51 -0
  56. package/src/exercises/powers/scientificToDecimal.js +38 -0
  57. package/src/exercises/powers/scientificToDecimal.ts +44 -0
  58. package/src/exercises/squareRoots/simpifySquareRoot.js +2 -3
  59. package/src/exercises/squareRoots/simpifySquareRoot.ts +2 -0
  60. package/src/index.js +8 -8
  61. package/src/index.ts +5 -16
  62. package/src/mathutils/arithmetic/coprimesOf.js +13 -0
  63. package/src/mathutils/arithmetic/coprimesOf.ts +9 -0
  64. package/src/mathutils/arithmetic/dividersOf.ts +7 -0
  65. package/src/mathutils/arithmetic/lcd.js +12 -0
  66. package/src/mathutils/arithmetic/lcd.ts +7 -0
  67. package/src/mathutils/arithmetic/nonCoprimesOf.ts +9 -0
  68. package/src/mathutils/arithmetic/nonDividersOf.ts +12 -0
  69. package/src/mathutils/decimals/decimalPartLengthOf.ts +10 -0
  70. package/src/mathutils/random/randint.js +11 -2
  71. package/src/mathutils/random/randint.ts +10 -2
  72. package/src/numbers/decimals/decimal.js +144 -0
  73. package/src/numbers/decimals/decimal.ts +140 -0
  74. package/src/numbers/integer/integer.js +61 -4
  75. package/src/numbers/integer/integer.ts +58 -7
  76. package/src/numbers/integer/power.js +53 -0
  77. package/src/numbers/integer/power.ts +49 -0
  78. package/src/numbers/nombre.js +3 -2
  79. package/src/numbers/nombre.ts +2 -0
  80. package/src/numbers/rationals/rational.js +96 -10
  81. package/src/numbers/rationals/rational.ts +81 -15
  82. package/src/numbers/reals/real.js +2 -0
  83. package/src/numbers/reals/real.ts +3 -1
  84. package/src/numbers/reals/squareRoot.ts +3 -10
  85. package/src/polynomials/affine.ts +2 -6
  86. package/src/polynomials/polynomial.js +4 -13
  87. package/src/polynomials/polynomial.ts +8 -25
  88. package/src/tree/latexParser/latexParse.js +81 -34
  89. package/src/tree/latexParser/latexParse.ts +85 -39
  90. package/src/tree/nodes/functions/functionNode.js +19 -0
  91. package/src/tree/nodes/functions/functionNode.ts +18 -0
  92. package/src/tree/nodes/functions/oppositeNode.js +30 -0
  93. package/src/tree/nodes/functions/oppositeNode.ts +12 -0
  94. package/src/tree/nodes/functions/sqrtNode.js +24 -9
  95. package/src/tree/nodes/functions/sqrtNode.ts +5 -9
  96. package/src/tree/nodes/node.ts +1 -3
  97. package/src/tree/nodes/numbers/numberNode.js +3 -6
  98. package/src/tree/nodes/numbers/numberNode.ts +4 -7
  99. package/src/tree/nodes/operators/addNode.js +23 -8
  100. package/src/tree/nodes/operators/addNode.ts +3 -7
  101. package/src/tree/nodes/operators/divideNode.js +21 -9
  102. package/src/tree/nodes/operators/divideNode.ts +4 -11
  103. package/src/tree/nodes/operators/equalNode.js +20 -8
  104. package/src/tree/nodes/operators/equalNode.ts +3 -9
  105. package/src/tree/nodes/operators/fractionNode.js +34 -0
  106. package/src/tree/nodes/operators/fractionNode.ts +16 -0
  107. package/src/tree/nodes/operators/multiplyNode.js +20 -8
  108. package/src/tree/nodes/operators/multiplyNode.ts +3 -9
  109. package/src/tree/nodes/operators/operatorNode.js +35 -0
  110. package/src/tree/nodes/operators/operatorNode.ts +35 -2
  111. package/src/tree/nodes/operators/powerNode.js +20 -8
  112. package/src/tree/nodes/operators/powerNode.ts +3 -8
  113. package/src/tree/nodes/operators/substractNode.js +20 -8
  114. package/src/tree/nodes/operators/substractNode.ts +3 -9
  115. package/src/tree/nodes/variables/variableNode.js +1 -4
  116. package/src/tree/nodes/variables/variableNode.ts +4 -7
  117. package/src/utils/coin.js +7 -0
  118. package/src/utils/coin.ts +3 -0
  119. package/src/utils/shuffle.js +15 -4
  120. package/src/utils/shuffle.ts +7 -5
  121. package/src/exercises/calcul/priority.ts +0 -33
  122. package/src/expression/expression.js +0 -9
  123. package/src/expression/expression.ts +0 -13
  124. package/src/tree/nodes/operators/oppositeNode.ts +0 -17
@@ -1,10 +1,39 @@
1
- import { Expression } from "../../expression/expression";
1
+ import { coprimesOf } from "../../mathutils/arithmetic/coprimesOf";
2
2
  import { gcd } from "../../mathutils/arithmetic/gcd";
3
+ import { lcd } from "../../mathutils/arithmetic/lcd";
4
+ import { randint } from "../../mathutils/random/randint";
3
5
  import { Node } from "../../tree/nodes/node";
4
6
  import { NumberNode } from "../../tree/nodes/numbers/numberNode";
5
7
  import { DivideNode } from "../../tree/nodes/operators/divideNode";
8
+ import { FractionNode } from "../../tree/nodes/operators/fractionNode";
9
+ import { random } from "../../utils/random";
10
+ import { shuffle } from "../../utils/shuffle";
6
11
  import { Integer } from "../integer/integer";
7
- import { Nombre } from "../nombre";
12
+ import { Nombre, NumberType } from "../nombre";
13
+
14
+ export abstract class RationalConstructor {
15
+ /**
16
+ * @param maxGcd max number by which the fraction is simplifiable
17
+ */
18
+ static randomSimplifiable(maxGcd: number = 10) {
19
+ const gcd = randint(2, maxGcd);
20
+ const max = randint(3, 11);
21
+ const min = random(coprimesOf(max));
22
+ let [num, denum]: number[] = shuffle([gcd * min, gcd * max]);
23
+ if (denum === gcd) {
24
+ //si 10/2 on transforme en 2/10
25
+ return new Rational(denum, num);
26
+ }
27
+ return new Rational(num, denum);
28
+ }
29
+ static randomIrreductible(max: number = 11) {
30
+ const a = randint(2, max);
31
+ const b = random([...coprimesOf(a), 1]);
32
+ if (b === 1) return new Rational(b, a);
33
+ const [num, denum] = shuffle([a, b]);
34
+ return new Rational(num, denum);
35
+ }
36
+ }
8
37
 
9
38
  export class Rational implements Nombre {
10
39
  num: number;
@@ -12,25 +41,68 @@ export class Rational implements Nombre {
12
41
  tex: string;
13
42
  value: number;
14
43
  isSimplified: boolean;
44
+ type: NumberType;
15
45
 
16
46
  constructor(numerator: number, denumerator: number) {
47
+ if (denumerator === 0) throw Error("division by zero");
17
48
  this.num = numerator;
18
49
  this.denum = denumerator;
19
50
  this.value = numerator / denumerator;
20
51
  this.isSimplified = Math.abs(gcd(numerator, denumerator)) === 1;
21
52
  this.tex = `\\frac{${this.num}}{${this.denum}}`;
53
+ this.type = NumberType.Rational;
22
54
  }
23
55
 
24
56
  toTex() {
25
57
  return `\\frac{${this.num}}{${this.denum}}`;
26
58
  }
27
59
 
28
- add(expression: Expression): Expression {
29
- return this;
60
+ add(nb: Nombre): Nombre {
61
+ switch (nb.type) {
62
+ case NumberType.Integer: {
63
+ const num = this.num + this.denum * nb.value;
64
+ return new Rational(num, this.denum).simplify();
65
+ }
66
+ case NumberType.Rational: {
67
+ const rational = nb as Rational;
68
+ const ppcm = lcd(rational.denum, this.denum);
69
+ const num = this.num * (ppcm / this.denum) + rational.num * (ppcm / rational.denum);
70
+ return new Rational(num, ppcm).simplify();
71
+ }
72
+ }
73
+ throw Error("not implemented yet");
30
74
  }
31
75
 
32
- multiply(expression: Expression): Expression {
33
- return this;
76
+ multiply(nb: Nombre): Nombre {
77
+ switch (nb.type) {
78
+ case NumberType.Integer: {
79
+ const num = this.num * nb.value;
80
+ const denum = this.denum;
81
+ return new Rational(num, denum).simplify();
82
+ }
83
+ case NumberType.Rational: {
84
+ const rational = nb as Rational;
85
+ const num = this.num * rational.num;
86
+ const denum = this.denum * rational.denum;
87
+ return new Rational(num, denum).simplify();
88
+ }
89
+ }
90
+ throw Error("not implemented yet");
91
+ }
92
+ divide(nb: Nombre): Nombre {
93
+ switch (nb.type) {
94
+ case NumberType.Integer: {
95
+ const denum = this.denum * nb.value;
96
+ return new Rational(this.num, denum).simplify();
97
+ }
98
+ case NumberType.Rational: {
99
+ const rational = nb as Rational;
100
+ const num = this.num * rational.denum;
101
+ const denum = this.denum * rational.num;
102
+ return new Rational(num, denum).simplify();
103
+ }
104
+ }
105
+ throw Error("not implemented yet");
34
106
  }
35
107
 
36
108
  opposite(): Rational {
@@ -38,19 +110,13 @@ export class Rational implements Nombre {
38
110
  }
39
111
 
40
112
  toTree(): Node {
41
- return new DivideNode(new NumberNode(this.num), new NumberNode(this.denum));
113
+ return new FractionNode(new NumberNode(this.num), new NumberNode(this.denum));
42
114
  }
43
115
 
44
116
  simplify(): Nombre {
45
- const sign =
46
- (this.num > 0 && this.denum > 0) || (this.num < 0 && this.denum < 0)
47
- ? 1
48
- : -1;
117
+ const sign = (this.num > 0 && this.denum > 0) || (this.num < 0 && this.denum < 0) ? 1 : -1;
49
118
  const div = Math.abs(gcd(this.num, this.denum));
50
119
  if (Math.abs(this.denum) === div) return new Integer(this.num / this.denum);
51
- return new Rational(
52
- (sign * Math.abs(this.num)) / div,
53
- Math.abs(this.denum) / div
54
- );
120
+ return new Rational((sign * Math.abs(this.num)) / div, Math.abs(this.denum) / div);
55
121
  }
56
122
  }
@@ -2,10 +2,12 @@
2
2
  exports.__esModule = true;
3
3
  exports.Real = void 0;
4
4
  var numberNode_1 = require("../../tree/nodes/numbers/numberNode");
5
+ var nombre_1 = require("../nombre");
5
6
  var Real = /** @class */ (function () {
6
7
  function Real(value, tex) {
7
8
  this.value = value;
8
9
  this.tex = tex;
10
+ this.type = nombre_1.NumberType.Real;
9
11
  }
10
12
  Real.prototype.toTree = function () {
11
13
  return new numberNode_1.NumberNode(this.value);
@@ -1,13 +1,15 @@
1
1
  import { Node } from "../../tree/nodes/node";
2
2
  import { NumberNode } from "../../tree/nodes/numbers/numberNode";
3
- import { Nombre } from "../nombre";
3
+ import { Nombre, NumberType } from "../nombre";
4
4
 
5
5
  export class Real implements Nombre {
6
6
  value: number;
7
7
  tex: string;
8
+ type: NumberType;
8
9
  constructor(value: number, tex: string) {
9
10
  this.value = value;
10
11
  this.tex = tex;
12
+ this.type = NumberType.Real;
11
13
  }
12
14
  toTree(): Node {
13
15
  return new NumberNode(this.value);
@@ -11,10 +11,7 @@ export abstract class SquareRootConstructor {
11
11
  /**
12
12
  * @returns simplifiable square root type sqrt(c)=a*sqrt(b)
13
13
  */
14
- static randomSimplifiable({
15
- allowPerfectSquare = false,
16
- maxSquare = 11,
17
- }): SquareRoot {
14
+ static randomSimplifiable({ allowPerfectSquare = false, maxSquare = 11 }): SquareRoot {
18
15
  const a = randint(2, maxSquare);
19
16
  let b;
20
17
  let bMin = allowPerfectSquare ? 1 : 2;
@@ -44,8 +41,7 @@ export class SquareRoot extends Real {
44
41
  }
45
42
  }
46
43
  const outsideSqrt = multiples.reduce((x, y) => x * y);
47
- const insideSqrt =
48
- factors.length === 0 ? 1 : factors.reduce((x, y) => x * y);
44
+ const insideSqrt = factors.length === 0 ? 1 : factors.reduce((x, y) => x * y);
49
45
 
50
46
  const simplified =
51
47
  insideSqrt !== 1
@@ -58,10 +54,7 @@ export class SquareRoot extends Real {
58
54
  return insideSqrt !== 1
59
55
  ? outsideSqrt === 1
60
56
  ? new SqrtNode(new NumberNode(insideSqrt))
61
- : new MultiplyNode(
62
- new NumberNode(outsideSqrt),
63
- new SqrtNode(new NumberNode(insideSqrt))
64
- )
57
+ : new MultiplyNode(new NumberNode(outsideSqrt), new SqrtNode(new NumberNode(insideSqrt)))
65
58
  : new NumberNode(outsideSqrt);
66
59
  };
67
60
  return simplified;
@@ -13,9 +13,7 @@ import { Nombre } from "../numbers/nombre";
13
13
 
14
14
  export abstract class AffineConstructor {
15
15
  static random(
16
- domainA: MathSet = new Interval("[[-10; 10]]").difference(
17
- new DiscreteSet([new Integer(0)])
18
- ),
16
+ domainA: MathSet = new Interval("[[-10; 10]]").difference(new DiscreteSet([new Integer(0)])),
19
17
  domainB: MathSet = new Interval("[[-10; 10]]")
20
18
  ): Affine {
21
19
  const a = domainA.getRandomElement();
@@ -25,9 +23,7 @@ export abstract class AffineConstructor {
25
23
 
26
24
  static differentRandoms(
27
25
  nb: number,
28
- domainA: MathSet = new Interval("[[-10; 10]]").difference(
29
- new DiscreteSet([new Integer(0)])
30
- ),
26
+ domainA: MathSet = new Interval("[[-10; 10]]").difference(new DiscreteSet([new Integer(0)])),
31
27
  domainB: MathSet = new Interval("[[-10; 10]]")
32
28
  ): Affine[] {
33
29
  const res: Affine[] = [];
@@ -4,7 +4,7 @@ exports.Polynomial = void 0;
4
4
  var numberNode_1 = require("../tree/nodes/numbers/numberNode");
5
5
  var addNode_1 = require("../tree/nodes/operators/addNode");
6
6
  var multiplyNode_1 = require("../tree/nodes/operators/multiplyNode");
7
- var oppositeNode_1 = require("../tree/nodes/operators/oppositeNode");
7
+ var oppositeNode_1 = require("../tree/nodes/functions/oppositeNode");
8
8
  var powerNode_1 = require("../tree/nodes/operators/powerNode");
9
9
  var variableNode_1 = require("../tree/nodes/variables/variableNode");
10
10
  var Polynomial = /** @class */ (function () {
@@ -25,15 +25,13 @@ var Polynomial = /** @class */ (function () {
25
25
  this.degree = coefficients.length - 1;
26
26
  }
27
27
  Polynomial.prototype.equals = function (P) {
28
- return (P.degree === this.degree &&
29
- this.coefficients.every(function (coeff, i) { return coeff === P.coefficients[i]; }));
28
+ return P.degree === this.degree && this.coefficients.every(function (coeff, i) { return coeff === P.coefficients[i]; });
30
29
  };
31
30
  Polynomial.prototype.getRoots = function () { };
32
31
  Polynomial.prototype.add = function (P) {
33
32
  if (P.variable !== this.variable)
34
33
  throw Error("Can't add two polynomials with different variables");
35
- var newDegree = P.degree === this.degree &&
36
- P.coefficients[P.degree] === -this.coefficients[this.degree]
34
+ var newDegree = P.degree === this.degree && P.coefficients[P.degree] === -this.coefficients[this.degree]
37
35
  ? P.degree - 1
38
36
  : Math.max(P.degree, this.degree);
39
37
  var res = [];
@@ -110,14 +108,7 @@ var Polynomial = /** @class */ (function () {
110
108
  s += coeff === 1 ? "" : coeff === -1 ? "-" : coeff;
111
109
  }
112
110
  else {
113
- s +=
114
- coeff === 1
115
- ? "+"
116
- : coeff === -1
117
- ? "-"
118
- : coeff > 0
119
- ? "+".concat(coeff)
120
- : coeff;
111
+ s += coeff === 1 ? "+" : coeff === -1 ? "-" : coeff > 0 ? "+".concat(coeff) : coeff;
121
112
  }
122
113
  //x^n
123
114
  if (i === 0)
@@ -1,14 +1,13 @@
1
- import { Expression } from "../expression/expression";
2
1
  import { Node } from "../tree/nodes/node";
3
2
  import { NumberNode } from "../tree/nodes/numbers/numberNode";
4
3
  import { AddNode } from "../tree/nodes/operators/addNode";
5
4
  import { MultiplyNode } from "../tree/nodes/operators/multiplyNode";
6
- import { OppositeNode } from "../tree/nodes/operators/oppositeNode";
5
+ import { OppositeNode } from "../tree/nodes/functions/oppositeNode";
7
6
  import { PowerNode } from "../tree/nodes/operators/powerNode";
8
7
  import { SubstractNode } from "../tree/nodes/operators/substractNode";
9
8
  import { VariableNode } from "../tree/nodes/variables/variableNode";
10
9
 
11
- export class Polynomial implements Expression {
10
+ export class Polynomial {
12
11
  degree: number;
13
12
  variable: string;
14
13
  /**
@@ -31,19 +30,14 @@ export class Polynomial implements Expression {
31
30
  this.degree = coefficients.length - 1;
32
31
  }
33
32
  equals(P: Polynomial): boolean {
34
- return (
35
- P.degree === this.degree &&
36
- this.coefficients.every((coeff, i) => coeff === P.coefficients[i])
37
- );
33
+ return P.degree === this.degree && this.coefficients.every((coeff, i) => coeff === P.coefficients[i]);
38
34
  }
39
35
  getRoots() {}
40
36
  add(P: Polynomial): Polynomial {
41
- if (P.variable !== this.variable)
42
- throw Error("Can't add two polynomials with different variables");
37
+ if (P.variable !== this.variable) throw Error("Can't add two polynomials with different variables");
43
38
 
44
39
  const newDegree =
45
- P.degree === this.degree &&
46
- P.coefficients[P.degree] === -this.coefficients[this.degree]
40
+ P.degree === this.degree && P.coefficients[P.degree] === -this.coefficients[this.degree]
47
41
  ? P.degree - 1
48
42
  : Math.max(P.degree, this.degree);
49
43
 
@@ -60,8 +54,7 @@ export class Polynomial implements Expression {
60
54
  );
61
55
  }
62
56
  multiply(Q: Polynomial): Polynomial {
63
- if (Q.variable !== this.variable)
64
- throw Error("Can't multiply two polynomials with different variables");
57
+ if (Q.variable !== this.variable) throw Error("Can't multiply two polynomials with different variables");
65
58
 
66
59
  const p = this.degree;
67
60
  const q = Q.degree;
@@ -96,10 +89,7 @@ export class Polynomial implements Expression {
96
89
 
97
90
  const monome =
98
91
  cursor > 1
99
- ? new PowerNode(
100
- new VariableNode(this.variable),
101
- new NumberNode(cursor)
102
- )
92
+ ? new PowerNode(new VariableNode(this.variable), new NumberNode(cursor))
103
93
  : new VariableNode(this.variable);
104
94
 
105
95
  let res: Node;
@@ -132,14 +122,7 @@ export class Polynomial implements Expression {
132
122
  else if (i === this.degree) {
133
123
  s += coeff === 1 ? "" : coeff === -1 ? "-" : coeff;
134
124
  } else {
135
- s +=
136
- coeff === 1
137
- ? "+"
138
- : coeff === -1
139
- ? "-"
140
- : coeff > 0
141
- ? `+${coeff}`
142
- : coeff;
125
+ s += coeff === 1 ? "+" : coeff === -1 ? "-" : coeff > 0 ? `+${coeff}` : coeff;
143
126
  }
144
127
  //x^n
145
128
  if (i === 0) continue;
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  exports.__esModule = true;
3
3
  exports.latexParse = void 0;
4
+ var functionNode_1 = require("../nodes/functions/functionNode");
4
5
  var node_1 = require("../nodes/node");
6
+ var operatorNode_1 = require("../nodes/operators/operatorNode");
5
7
  function latexParse(node) {
6
8
  if (!node) {
7
9
  console.log("parsing a null node ???");
@@ -13,59 +15,104 @@ function latexParse(node) {
13
15
  case node_1.NodeType.number:
14
16
  return node.tex;
15
17
  case node_1.NodeType.operator:
16
- var rightTex = latexParse(node.rightChild);
17
- var leftTex = latexParse(node.leftChild);
18
- var leftChild = node.leftChild, rightChild = node.rightChild;
19
- switch (node.id) {
20
- case "add":
18
+ var operatorNode = node;
19
+ var rightTex = latexParse(operatorNode.rightChild);
20
+ var leftTex = latexParse(operatorNode.leftChild);
21
+ var leftChild = operatorNode.leftChild, rightChild = operatorNode.rightChild;
22
+ switch (operatorNode.id) {
23
+ case operatorNode_1.OperatorIds.add:
21
24
  return "".concat(leftTex, " ").concat(rightTex[0] === "-" ? "" : "+ ").concat(rightTex);
22
- case "opposite":
23
- var needBrackets = leftChild.id === "add" ||
24
- leftChild.id === "substract" ||
25
- leftTex[0] === "-";
26
- if (needBrackets)
27
- leftTex = "(".concat(leftTex, ")");
28
- return "-".concat(leftTex);
29
- case "substract": {
30
- var needBrackets_1 = rightChild.id === "add" ||
31
- rightChild.id === "substract" ||
25
+ case operatorNode_1.OperatorIds.substract: {
26
+ var needBrackets = (rightChild.type === node_1.NodeType.operator &&
27
+ [operatorNode_1.OperatorIds.add, operatorNode_1.OperatorIds.substract].includes(rightChild.id)) ||
32
28
  rightTex[0] === "-";
33
- if (needBrackets_1)
29
+ if (needBrackets)
34
30
  rightTex = "(".concat(rightTex, ")");
35
31
  return "".concat(leftTex, " - ").concat(rightTex);
36
32
  }
37
- case "multiply": {
38
- if (leftChild.id === "add" || leftChild.id === "substract")
39
- leftTex = "(".concat(leftTex, ")");
40
- var needBrackets_2 = rightChild.id === "add" ||
41
- rightChild.id === "substract" ||
42
- rightTex[0] === "-";
43
- if (needBrackets_2)
33
+ case operatorNode_1.OperatorIds.multiply: {
34
+ if (leftChild.type === node_1.NodeType.operator) {
35
+ if ([operatorNode_1.OperatorIds.add, operatorNode_1.OperatorIds.substract, operatorNode_1.OperatorIds.divide].includes(leftChild.id))
36
+ leftTex = "(".concat(leftTex, ")");
37
+ }
38
+ var needBrackets = rightTex[0] === "-";
39
+ if (rightChild.type === node_1.NodeType.operator) {
40
+ var operatorRightChild = rightChild;
41
+ needBrackets || (needBrackets = [operatorNode_1.OperatorIds.add, operatorNode_1.OperatorIds.substract].includes(operatorRightChild.id));
42
+ }
43
+ if (needBrackets)
44
44
  rightTex = "(".concat(rightTex, ")");
45
- var showTimesSign = !isNaN(+rightTex[0]); //permet de gérer le cas 3*2^x
45
+ // permet de gérer le cas 3*2^x
46
+ var showTimesSign = !isNaN(+rightTex[0]) || rightChild.type === node_1.NodeType.number;
47
+ if (rightChild.type === node_1.NodeType.operator) {
48
+ var operatorRightChild = rightChild;
49
+ showTimesSign || (showTimesSign = [operatorNode_1.OperatorIds.fraction].includes(operatorRightChild.id));
50
+ }
46
51
  return "".concat(leftTex).concat(showTimesSign ? "\\times " : "").concat(rightTex);
47
52
  }
48
- case "divide": {
53
+ case operatorNode_1.OperatorIds.divide: {
54
+ if (leftChild.type === node_1.NodeType.operator) {
55
+ if ([operatorNode_1.OperatorIds.add, operatorNode_1.OperatorIds.substract, operatorNode_1.OperatorIds.multiply].includes(leftChild.id))
56
+ leftTex = "(".concat(leftTex, ")");
57
+ }
58
+ var needBrackets = rightTex[0] === "-";
59
+ if (rightChild.type === node_1.NodeType.operator) {
60
+ var operatorRightChild = rightChild;
61
+ needBrackets || (needBrackets = [operatorNode_1.OperatorIds.add, operatorNode_1.OperatorIds.substract].includes(operatorRightChild.id));
62
+ }
63
+ if (needBrackets)
64
+ rightTex = "(".concat(rightTex, ")");
65
+ // permet de gérer le cas 3*2^x
66
+ var showTimesSign = !isNaN(+rightTex[0]);
67
+ if (rightChild.type === node_1.NodeType.operator) {
68
+ var operatorRightChild = rightChild;
69
+ showTimesSign || (showTimesSign = [operatorNode_1.OperatorIds.fraction].includes(operatorRightChild.id));
70
+ }
71
+ return "".concat(leftTex).concat(showTimesSign ? "\\div " : "").concat(rightTex);
72
+ }
73
+ case operatorNode_1.OperatorIds.fraction: {
49
74
  return "\\frac{".concat(leftTex, "}{").concat(rightTex, "}");
50
75
  }
51
- case "power": {
52
- if (leftChild.id === "add" ||
53
- leftChild.id === "substract" ||
54
- leftChild.id === "multiply")
76
+ case operatorNode_1.OperatorIds.power: {
77
+ var needBrackets = leftTex[0] === "-";
78
+ if (leftChild.type === node_1.NodeType.operator) {
79
+ var childOperator = leftChild;
80
+ needBrackets || (needBrackets = [
81
+ operatorNode_1.OperatorIds.add,
82
+ operatorNode_1.OperatorIds.substract,
83
+ operatorNode_1.OperatorIds.multiply,
84
+ operatorNode_1.OperatorIds.divide,
85
+ operatorNode_1.OperatorIds.fraction,
86
+ operatorNode_1.OperatorIds.power,
87
+ ].includes(childOperator.id));
88
+ }
89
+ if (needBrackets)
55
90
  leftTex = "(".concat(leftTex, ")");
56
91
  return "".concat(leftTex, "^{").concat(rightTex, "}");
57
92
  }
58
- case "equal": {
93
+ case operatorNode_1.OperatorIds.equal: {
59
94
  return "".concat(leftTex, " = ").concat(rightTex);
60
95
  }
61
96
  default:
62
97
  return node.tex;
63
98
  }
64
99
  case node_1.NodeType["function"]: {
65
- var leftTex_1 = latexParse(node.leftChild);
66
- switch (node.id) {
67
- case "sqrt": {
68
- return "\\sqrt{".concat(leftTex_1, "}");
100
+ var functionNode = node;
101
+ var child = functionNode.child;
102
+ var childTex = latexParse(functionNode.child);
103
+ switch (functionNode.id) {
104
+ case functionNode_1.FunctionsIds.sqrt: {
105
+ return "\\sqrt{".concat(childTex, "}");
106
+ }
107
+ case functionNode_1.FunctionsIds.opposite: {
108
+ var needBrackets = childTex[0] === "-";
109
+ if (child.type === node_1.NodeType.operator) {
110
+ var operatorChild = child;
111
+ needBrackets || (needBrackets = [operatorNode_1.OperatorIds.add, operatorNode_1.OperatorIds.substract].includes(operatorChild.id));
112
+ }
113
+ if (needBrackets)
114
+ childTex = "(".concat(childTex, ")");
115
+ return "-".concat(childTex);
69
116
  }
70
117
  }
71
118
  }
@@ -1,7 +1,8 @@
1
+ import { FunctionNode, FunctionsIds } from "../nodes/functions/functionNode";
1
2
  import { Node, NodeType } from "../nodes/node";
2
- import { OperatorNode } from "../nodes/operators/operatorNode";
3
+ import { OperatorIds, OperatorNode } from "../nodes/operators/operatorNode";
3
4
 
4
- export function latexParse(node: Node | null): string {
5
+ export function latexParse(node: Node): string {
5
6
  if (!node) {
6
7
  console.log("parsing a null node ???");
7
8
  return "";
@@ -12,67 +13,112 @@ export function latexParse(node: Node | null): string {
12
13
  case NodeType.number:
13
14
  return node.tex;
14
15
  case NodeType.operator:
15
- let rightTex = latexParse(node.rightChild);
16
- let leftTex = latexParse(node.leftChild);
17
- const { leftChild, rightChild } = node;
18
- switch (node.id) {
19
- case "add":
16
+ const operatorNode = node as OperatorNode;
17
+ let rightTex = latexParse(operatorNode.rightChild);
18
+ let leftTex = latexParse(operatorNode.leftChild);
19
+ const { leftChild, rightChild } = operatorNode;
20
+ switch (operatorNode.id) {
21
+ case OperatorIds.add:
20
22
  return `${leftTex} ${rightTex[0] === "-" ? "" : "+ "}${rightTex}`;
21
23
 
22
- case "opposite":
24
+ case OperatorIds.substract: {
23
25
  const needBrackets =
24
- leftChild!.id === "add" ||
25
- leftChild!.id === "substract" ||
26
- leftTex[0] === "-";
27
- if (needBrackets) leftTex = `(${leftTex})`;
28
- return `-${leftTex}`;
29
-
30
- case "substract": {
31
- const needBrackets =
32
- rightChild!.id === "add" ||
33
- rightChild!.id === "substract" ||
26
+ (rightChild.type === NodeType.operator &&
27
+ [OperatorIds.add, OperatorIds.substract].includes((rightChild as OperatorNode).id)) ||
34
28
  rightTex[0] === "-";
29
+
35
30
  if (needBrackets) rightTex = `(${rightTex})`;
31
+
36
32
  return `${leftTex} - ${rightTex}`;
37
33
  }
38
34
 
39
- case "multiply": {
40
- if (leftChild!.id === "add" || leftChild!.id === "substract")
41
- leftTex = `(${leftTex})`;
42
- const needBrackets =
43
- rightChild!.id === "add" ||
44
- rightChild!.id === "substract" ||
45
- rightTex[0] === "-";
35
+ case OperatorIds.multiply: {
36
+ if (leftChild.type === NodeType.operator) {
37
+ if ([OperatorIds.add, OperatorIds.substract, OperatorIds.divide].includes((leftChild as OperatorNode).id))
38
+ leftTex = `(${leftTex})`;
39
+ }
40
+ let needBrackets = rightTex[0] === "-";
41
+ if (rightChild.type === NodeType.operator) {
42
+ const operatorRightChild = rightChild as OperatorNode;
43
+ needBrackets ||= [OperatorIds.add, OperatorIds.substract].includes(operatorRightChild.id);
44
+ }
46
45
  if (needBrackets) rightTex = `(${rightTex})`;
47
- const showTimesSign = !isNaN(+rightTex[0]); //permet de gérer le cas 3*2^x
46
+
47
+ // permet de gérer le cas 3*2^x
48
+ let showTimesSign = !isNaN(+rightTex[0]) || rightChild.type === NodeType.number;
49
+ if (rightChild.type === NodeType.operator) {
50
+ const operatorRightChild = rightChild as OperatorNode;
51
+ showTimesSign ||= [OperatorIds.fraction].includes(operatorRightChild.id);
52
+ }
48
53
  return `${leftTex}${showTimesSign ? "\\times " : ""}${rightTex}`;
49
54
  }
50
55
 
51
- case "divide": {
56
+ case OperatorIds.divide: {
57
+ if (leftChild.type === NodeType.operator) {
58
+ if ([OperatorIds.add, OperatorIds.substract, OperatorIds.multiply].includes((leftChild as OperatorNode).id))
59
+ leftTex = `(${leftTex})`;
60
+ }
61
+ let needBrackets = rightTex[0] === "-";
62
+ if (rightChild.type === NodeType.operator) {
63
+ const operatorRightChild = rightChild as OperatorNode;
64
+ needBrackets ||= [OperatorIds.add, OperatorIds.substract].includes(operatorRightChild.id);
65
+ }
66
+ if (needBrackets) rightTex = `(${rightTex})`;
67
+
68
+ // permet de gérer le cas 3*2^x
69
+ let showTimesSign = !isNaN(+rightTex[0]);
70
+ if (rightChild.type === NodeType.operator) {
71
+ const operatorRightChild = rightChild as OperatorNode;
72
+ showTimesSign ||= [OperatorIds.fraction].includes(operatorRightChild.id);
73
+ }
74
+ return `${leftTex}${showTimesSign ? "\\div " : ""}${rightTex}`;
75
+ }
76
+
77
+ case OperatorIds.fraction: {
52
78
  return `\\frac{${leftTex}}{${rightTex}}`;
53
79
  }
54
80
 
55
- case "power": {
56
- if (
57
- leftChild!.id === "add" ||
58
- leftChild!.id === "substract" ||
59
- leftChild!.id === "multiply"
60
- )
61
- leftTex = `(${leftTex})`;
81
+ case OperatorIds.power: {
82
+ let needBrackets = leftTex[0] === "-";
83
+ if (leftChild.type === NodeType.operator) {
84
+ const childOperator = leftChild as OperatorNode;
85
+ needBrackets ||= [
86
+ OperatorIds.add,
87
+ OperatorIds.substract,
88
+ OperatorIds.multiply,
89
+ OperatorIds.divide,
90
+ OperatorIds.fraction,
91
+ OperatorIds.power,
92
+ ].includes(childOperator.id);
93
+ }
94
+ if (needBrackets) leftTex = `(${leftTex})`;
62
95
  return `${leftTex}^{${rightTex}}`;
63
96
  }
64
97
 
65
- case "equal": {
98
+ case OperatorIds.equal: {
66
99
  return `${leftTex} = ${rightTex}`;
67
100
  }
68
101
  default:
69
102
  return node.tex;
70
103
  }
104
+
71
105
  case NodeType.function: {
72
- let leftTex = latexParse(node.leftChild);
73
- switch (node.id) {
74
- case "sqrt": {
75
- return `\\sqrt{${leftTex}}`;
106
+ const functionNode = node as FunctionNode;
107
+ const child = functionNode.child;
108
+ let childTex = latexParse(functionNode.child);
109
+ switch (functionNode.id) {
110
+ case FunctionsIds.sqrt: {
111
+ return `\\sqrt{${childTex}}`;
112
+ }
113
+
114
+ case FunctionsIds.opposite: {
115
+ let needBrackets = childTex[0] === "-";
116
+ if (child.type === NodeType.operator) {
117
+ const operatorChild = child as OperatorNode;
118
+ needBrackets ||= [OperatorIds.add, OperatorIds.substract].includes(operatorChild.id);
119
+ }
120
+ if (needBrackets) childTex = `(${childTex})`;
121
+ return `-${childTex}`;
76
122
  }
77
123
  }
78
124
  }