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.
- package/package.json +2 -2
- package/src/exercises/calcul/addAndSub.js +19 -13
- package/src/exercises/calcul/addAndSub.ts +31 -23
- package/src/exercises/calcul/fractions/fractionAndIntegerDivision.js +35 -0
- package/src/exercises/calcul/fractions/fractionAndIntegerDivision.ts +38 -0
- package/src/exercises/calcul/fractions/fractionAndIntegerProduct.js +31 -0
- package/src/exercises/calcul/fractions/fractionAndIntegerProduct.ts +32 -0
- package/src/exercises/calcul/fractions/fractionAndIntegerSum.js +32 -0
- package/src/exercises/calcul/fractions/fractionAndIntegerSum.ts +31 -0
- package/src/exercises/calcul/fractions/fractionsDivision.js +29 -0
- package/src/exercises/calcul/fractions/fractionsDivision.ts +30 -0
- package/src/exercises/calcul/fractions/fractionsProduct.js +29 -0
- package/src/exercises/calcul/fractions/fractionsProduct.ts +29 -0
- package/src/exercises/calcul/fractions/fractionsSum.js +29 -0
- package/src/exercises/calcul/fractions/fractionsSum.ts +28 -0
- package/src/exercises/calcul/fractions/simplifyFraction.js +25 -0
- package/src/exercises/calcul/fractions/simplifyFraction.ts +24 -0
- package/src/exercises/calcul/operationsPriorities.js +89 -0
- package/src/exercises/calcul/operationsPriorities.ts +118 -0
- package/src/exercises/calcul/rounding/roundToUnit.js +70 -0
- package/src/exercises/calcul/rounding/roundToUnit.ts +68 -0
- package/src/exercises/calculLitteral/distributivity/allIdentities.js +2 -0
- package/src/exercises/calculLitteral/distributivity/allIdentities.ts +2 -0
- package/src/exercises/calculLitteral/distributivity/doubleDistributivity.js +3 -3
- package/src/exercises/calculLitteral/distributivity/doubleDistributivity.ts +2 -0
- package/src/exercises/calculLitteral/distributivity/firstIdentity.js +2 -0
- package/src/exercises/calculLitteral/distributivity/firstIdentity.ts +2 -0
- package/src/exercises/calculLitteral/distributivity/secondIdentity.js +3 -3
- package/src/exercises/calculLitteral/distributivity/secondIdentity.ts +2 -0
- package/src/exercises/calculLitteral/distributivity/simpleDistributivity.js +3 -3
- package/src/exercises/calculLitteral/distributivity/simpleDistributivity.ts +2 -0
- package/src/exercises/calculLitteral/distributivity/thirdIdentity.js +4 -2
- package/src/exercises/calculLitteral/distributivity/thirdIdentity.ts +2 -0
- package/src/exercises/calculLitteral/equation/equationType1Exercise.js +3 -3
- package/src/exercises/calculLitteral/equation/equationType1Exercise.ts +4 -5
- package/src/exercises/calculLitteral/equation/equationType2Exercise.js +3 -3
- package/src/exercises/calculLitteral/equation/equationType2Exercise.ts +5 -5
- package/src/exercises/calculLitteral/equation/equationType3Exercise.js +3 -3
- package/src/exercises/calculLitteral/equation/equationType3Exercise.ts +5 -5
- package/src/exercises/calculLitteral/equation/equationType4Exercise.js +3 -3
- package/src/exercises/calculLitteral/equation/equationType4Exercise.ts +7 -12
- package/src/exercises/calculLitteral/factorisation/factoType1Exercise.js +4 -9
- package/src/exercises/calculLitteral/factorisation/factoType1Exercise.ts +3 -6
- package/src/exercises/calculLitteral/reduction.ts +27 -0
- package/src/exercises/exercise.ts +2 -0
- package/src/exercises/exercises.js +83 -0
- package/src/exercises/exercises.ts +58 -0
- package/src/exercises/powers/powersDivision.js +46 -0
- package/src/exercises/powers/powersDivision.ts +51 -0
- package/src/exercises/powers/powersOfTenToDecimal.js +33 -0
- package/src/exercises/powers/powersOfTenToDecimal.ts +37 -0
- package/src/exercises/powers/powersPower.js +45 -0
- package/src/exercises/powers/powersPower.ts +55 -0
- package/src/exercises/powers/powersProduct.js +46 -0
- package/src/exercises/powers/powersProduct.ts +51 -0
- package/src/exercises/powers/scientificToDecimal.js +38 -0
- package/src/exercises/powers/scientificToDecimal.ts +44 -0
- package/src/exercises/squareRoots/simpifySquareRoot.js +2 -3
- package/src/exercises/squareRoots/simpifySquareRoot.ts +2 -0
- package/src/index.js +8 -8
- package/src/index.ts +5 -16
- package/src/mathutils/arithmetic/coprimesOf.js +13 -0
- package/src/mathutils/arithmetic/coprimesOf.ts +9 -0
- package/src/mathutils/arithmetic/dividersOf.ts +7 -0
- package/src/mathutils/arithmetic/lcd.js +12 -0
- package/src/mathutils/arithmetic/lcd.ts +7 -0
- package/src/mathutils/arithmetic/nonCoprimesOf.ts +9 -0
- package/src/mathutils/arithmetic/nonDividersOf.ts +12 -0
- package/src/mathutils/decimals/decimalPartLengthOf.ts +10 -0
- package/src/mathutils/random/randint.js +11 -2
- package/src/mathutils/random/randint.ts +10 -2
- package/src/numbers/decimals/decimal.js +144 -0
- package/src/numbers/decimals/decimal.ts +140 -0
- package/src/numbers/integer/integer.js +61 -4
- package/src/numbers/integer/integer.ts +58 -7
- package/src/numbers/integer/power.js +53 -0
- package/src/numbers/integer/power.ts +49 -0
- package/src/numbers/nombre.js +3 -2
- package/src/numbers/nombre.ts +2 -0
- package/src/numbers/rationals/rational.js +96 -10
- package/src/numbers/rationals/rational.ts +81 -15
- package/src/numbers/reals/real.js +2 -0
- package/src/numbers/reals/real.ts +3 -1
- package/src/numbers/reals/squareRoot.ts +3 -10
- package/src/polynomials/affine.ts +2 -6
- package/src/polynomials/polynomial.js +4 -13
- package/src/polynomials/polynomial.ts +8 -25
- package/src/tree/latexParser/latexParse.js +81 -34
- package/src/tree/latexParser/latexParse.ts +85 -39
- package/src/tree/nodes/functions/functionNode.js +19 -0
- package/src/tree/nodes/functions/functionNode.ts +18 -0
- package/src/tree/nodes/functions/oppositeNode.js +30 -0
- package/src/tree/nodes/functions/oppositeNode.ts +12 -0
- package/src/tree/nodes/functions/sqrtNode.js +24 -9
- package/src/tree/nodes/functions/sqrtNode.ts +5 -9
- package/src/tree/nodes/node.ts +1 -3
- package/src/tree/nodes/numbers/numberNode.js +3 -6
- package/src/tree/nodes/numbers/numberNode.ts +4 -7
- package/src/tree/nodes/operators/addNode.js +23 -8
- package/src/tree/nodes/operators/addNode.ts +3 -7
- package/src/tree/nodes/operators/divideNode.js +21 -9
- package/src/tree/nodes/operators/divideNode.ts +4 -11
- package/src/tree/nodes/operators/equalNode.js +20 -8
- package/src/tree/nodes/operators/equalNode.ts +3 -9
- package/src/tree/nodes/operators/fractionNode.js +34 -0
- package/src/tree/nodes/operators/fractionNode.ts +16 -0
- package/src/tree/nodes/operators/multiplyNode.js +20 -8
- package/src/tree/nodes/operators/multiplyNode.ts +3 -9
- package/src/tree/nodes/operators/operatorNode.js +35 -0
- package/src/tree/nodes/operators/operatorNode.ts +35 -2
- package/src/tree/nodes/operators/powerNode.js +20 -8
- package/src/tree/nodes/operators/powerNode.ts +3 -8
- package/src/tree/nodes/operators/substractNode.js +20 -8
- package/src/tree/nodes/operators/substractNode.ts +3 -9
- package/src/tree/nodes/variables/variableNode.js +1 -4
- package/src/tree/nodes/variables/variableNode.ts +4 -7
- package/src/utils/coin.js +7 -0
- package/src/utils/coin.ts +3 -0
- package/src/utils/shuffle.js +15 -4
- package/src/utils/shuffle.ts +7 -5
- package/src/exercises/calcul/priority.ts +0 -33
- package/src/expression/expression.js +0 -9
- package/src/expression/expression.ts +0 -13
- package/src/tree/nodes/operators/oppositeNode.ts +0 -17
|
@@ -1,10 +1,39 @@
|
|
|
1
|
-
import {
|
|
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(
|
|
29
|
-
|
|
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(
|
|
33
|
-
|
|
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
|
|
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/
|
|
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
|
|
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/
|
|
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
|
|
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
|
|
17
|
-
var
|
|
18
|
-
var
|
|
19
|
-
|
|
20
|
-
|
|
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
|
|
23
|
-
var needBrackets =
|
|
24
|
-
|
|
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 (
|
|
29
|
+
if (needBrackets)
|
|
34
30
|
rightTex = "(".concat(rightTex, ")");
|
|
35
31
|
return "".concat(leftTex, " - ").concat(rightTex);
|
|
36
32
|
}
|
|
37
|
-
case
|
|
38
|
-
if (leftChild.
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (
|
|
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
|
-
|
|
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
|
|
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
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
|
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
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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
|
|
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
|
-
|
|
16
|
-
let
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
|
24
|
+
case OperatorIds.substract: {
|
|
23
25
|
const needBrackets =
|
|
24
|
-
|
|
25
|
-
|
|
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
|
|
40
|
-
if (leftChild
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
leftChild
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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
|
|
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
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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
|
}
|