Skip to content

Commit 3db9cfd

Browse files
✨ feat(simplify): Add fraction simplification method.
1 parent 505a4dd commit 3db9cfd

File tree

3 files changed

+58
-12
lines changed

3 files changed

+58
-12
lines changed

src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ export * from './mul' ;
44
export * from './sub' ;
55
export * from './cmp' ;
66
export * from './cmp_no_bounds' ;
7+
export * from './simplify' ;

src/simplify.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export function _simplify ( { egcd , sgn , neg } ) {
2+
return function ( a , b ) {
3+
const { u , v } = egcd(a , b) ;
4+
return [
5+
sgn(v) === sgn(a) ? v : neg(v) ,
6+
sgn(u) === sgn(b) ? u : neg(u)
7+
] ;
8+
} ;
9+
}

test/src/core.js

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
import test from 'ava';
2-
import { _add , _sub , _mul , _div , _cmp , _cmp_no_bounds } from '../../src';
2+
import { _add , _sub , _mul , _div , _cmp , _cmp_no_bounds , _simplify } from '../../src';
33

44
import int from 'int' ;
55
import { ZZ } from '@aureooms/js-integer' ;
66

77
const GOOGOL = '10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' ;
88

9-
function macro ( t , alu , [ [ _x , _y , factory ] , a , b , c , d , e ] ) {
9+
function binary ( t , alu , [ [ _x , _y , factory ] , a , b , c , d , e ] ) {
1010

1111
const apply = factory( alu );
1212

13-
//const repr = x => `${alu.str(x[0])} / ${alu.str(x[1])}` ;
1413
const num = x => Number(alu.str(x[0])) / Number(alu.str(x[1])) ;
1514

1615
const a0 = alu.reg(a);
@@ -25,10 +24,29 @@ function macro ( t , alu , [ [ _x , _y , factory ] , a , b , c , d , e ] ) {
2524

2625
}
2726

28-
macro.title = ( _ , alu , [ [ name , op , impl ] , a , b , c , d , e] ) => {
27+
binary.title = ( _ , alu , [ [ name , op , impl ] , a , b , c , d , e] ) => {
2928
return `${name}<${impl.name}, ${alu.name}> ${a}/${b} ${op} ${c}/${d} = ${e}` ;
3029
} ;
3130

31+
function unary ( t , alu , [ [ _x , _y , factory ] , a , b , e ] ) {
32+
33+
const apply = factory( alu );
34+
35+
const repr = x => `${alu.str(x[0])}/${alu.str(x[1])}` ;
36+
37+
const _a = alu.reg(a);
38+
const _b = alu.reg(b);
39+
40+
const z = apply( _a , _b ) ;
41+
42+
t.is(e, repr(z));
43+
44+
}
45+
46+
unary.title = ( _ , alu , [ [ name , impl ] , a , b , e ] ) => {
47+
return `${name}<${impl.name}, ${alu.name}> ${name}(${a}/${b}) = ${e}` ;
48+
} ;
49+
3250
const ALU = [
3351
{
3452
name : 'int',
@@ -42,6 +60,7 @@ const ALU = [
4260
lt0 : x => x.lt(0),
4361
cmp : (a,b) => a.cmp(b),
4462
neg : x => x.neg(),
63+
sgn : x => x.cmp(0),
4564
divmod : (a,b) => [a.div(b), a.mod(b)],
4665
},
4766
{
@@ -55,16 +74,19 @@ const ALU = [
5574
jz : x => x.iszero(),
5675
lt0 : x => x.sign() < 0,
5776
cmp : (a,b) => a.cmp(b),
77+
sgn : x => x.sign(),
5878
neg : x => x.opposite(),
5979
divmod : (a,b) => a.divmod(b),
80+
egcd : (a,b) => a.egcd(b),
6081
}
6182
];
6283

63-
const add = [ 'add' , '+' , [ _add ] ] ;
64-
const sub = [ 'sub' , '-' , [ _sub ] ] ;
65-
const mul = [ 'mul' , '*' , [ _mul ] ] ;
66-
const div = [ 'div' , '/' , [ _div ] ] ;
67-
const cmp = [ 'cmp' , '~' , [ _cmp , _cmp_no_bounds ] ] ;
84+
const add = [ 'add' , '+' , [ _add ] , binary ] ;
85+
const sub = [ 'sub' , '-' , [ _sub ] , binary ] ;
86+
const mul = [ 'mul' , '*' , [ _mul ] , binary ] ;
87+
const div = [ 'div' , '/' , [ _div ] , binary ] ;
88+
const cmp = [ 'cmp' , '~' , [ _cmp , _cmp_no_bounds ] , binary ] ;
89+
const simplify = [ 'simplify' , '=' , [ _simplify ] , unary , alu => alu.egcd ] ;
6890

6991
const PARAMS = [
7092

@@ -131,9 +153,23 @@ const PARAMS = [
131153
[ cmp , GOOGOL, '3', GOOGOL, '3', 0 ] ,
132154
[ cmp , GOOGOL, GOOGOL, GOOGOL, GOOGOL, 0 ] ,
133155

156+
[ simplify , GOOGOL, GOOGOL, '1/1' ] ,
157+
[ simplify , '7', '14', '1/2' ] ,
158+
[ simplify , '-7', '14', '-1/2' ] ,
159+
[ simplify , '170141183460469231731687303715884105729' , '56713727820156410577229101238628035243' , '3/1' ] ,
160+
[ simplify , '56713727820156410577229101238628035243' , '170141183460469231731687303715884105729' , '1/3' ] ,
161+
[ simplify , '170141183460469231731687303715884105729' , '3' , '56713727820156410577229101238628035243/1' ] ,
162+
[ simplify , '3' , '170141183460469231731687303715884105729' , '1/56713727820156410577229101238628035243' ] ,
163+
[ simplify , '-170141183460469231731687303715884105729' , '56713727820156410577229101238628035243' , '-3/1' ] ,
164+
[ simplify , '-56713727820156410577229101238628035243' , '170141183460469231731687303715884105729' , '-1/3' ] ,
165+
[ simplify , '-170141183460469231731687303715884105729' , '3' , '-56713727820156410577229101238628035243/1' ] ,
166+
[ simplify , '-3' , '170141183460469231731687303715884105729' , '-1/56713727820156410577229101238628035243' ] ,
167+
134168
] ;
135169

136170
for (const alu of ALU)
137-
for (const [[name, symbol, implementations], ...params] of PARAMS)
138-
for (const factory of implementations)
139-
test(macro, alu, [[name, symbol, factory], ...params]);
171+
for (const [[name, symbol, implementations, macro, predicate], ...params] of PARAMS)
172+
if (!predicate || predicate(alu)) {
173+
for (const factory of implementations)
174+
test(macro, alu, [[name, symbol, factory], ...params]);
175+
}

0 commit comments

Comments
 (0)