diff --git a/src/day9/bigint.pas b/src/day9/bigint.pas index 8775a38..297facd 100644 --- a/src/day9/bigint.pas +++ b/src/day9/bigint.pas @@ -88,7 +88,6 @@ begin end; end; - operator shl (a: int512; b: int32) o: int512; var i: int32; diff --git a/src/day9/fraction.pas b/src/day9/fraction.pas new file mode 100644 index 0000000..6035f88 --- /dev/null +++ b/src/day9/fraction.pas @@ -0,0 +1,131 @@ + +{$include bigint.pas} + +type + fraction = record + numerator: int512; + denominator: int512; + end; + +const + { i don't think there's a better way of doing this unfortunately } + SIMPLIFY_CUTOFF: int512 = ( + values: ($00000000FFFFFFFF, $00000000FFFFFFFF, $00000000FFFFFFFF, $00000000FFFFFFFF, $00000000FFFFFFFF, $00000000FFFFFFFF, $00000000FFFFFFFF, $0000000000000000, + $0000000000000000, $0000000000000000, $0000000000000000, $0000000000000000, $0000000000000000, $0000000000000000, $0000000000000000, $0000000000000000); + ); + +procedure print_fraction(a: fraction); +begin + if a.denominator <> 1 then + begin + print512d(a.numerator); + write('/'); + print512d(a.denominator); + end + else + print512d(a.numerator); +end; + +function c_fraction(num: int512; den: int512): fraction; +begin + if den = 0 then + writeln('holy hell what are you doing'); + + c_fraction.numerator := num; + c_fraction.denominator := den; + +end; + +operator := (f: int64) out_ : fraction; +begin + out_ := c_fraction(f, 1); +end; + + +function gcd(a, b: int512): int512; +var + r: int512; +begin + + while true do + begin + + r := a mod b; + + if r = 0 then + break; + + a := b; + b := r; + + end; + + gcd := b; +end; + +function simplify(f: fraction): fraction; +var + b: int512; + neg: boolean; + +begin + + neg := false; + if isneg(f.numerator) then + begin + neg := not neg; + f.numerator := -f.numerator; + end; + + if isneg(f.denominator) then + begin + neg := not neg; + f.denominator := -f.denominator; + end; + + b := gcd(f.numerator, f.denominator); + + if b <> 0 then + simplify := c_fraction(f.numerator div b, f.denominator div b) + else + simplify := f; + + if neg then + simplify.numerator := -simplify.numerator; + +end; + +{ add fractions } +operator + (a, b: fraction) out_: fraction; +//var + // g: int512; +begin + + // print_fraction(a); + // write(' '); + // print_fraction(b); + // write(' '); + + // g := gcd(a.denominator, b.denominator); + + out_.denominator := a.denominator * b.denominator; + out_.numerator := a.denominator * b.numerator + b.denominator * a.numerator; + + // print_fraction(out_); + // write(' '); + if abs(out_.numerator) > SIMPLIFY_CUTOFF then + out_ := simplify(out_); + // print_fraction(out_); + // writeln('ya'); +end; + +{ mult fractions } +operator * (a, b: fraction) out_: fraction; +begin + out_.denominator := a.denominator * b.denominator; + out_.numerator := a.numerator * b.numerator; + + if abs(out_.numerator) > SIMPLIFY_CUTOFF then + out_ := simplify(out_); + +end; \ No newline at end of file diff --git a/src/day9/polynomial.pas b/src/day9/polynomial.pas index 1bc3b99..52afb88 100644 --- a/src/day9/polynomial.pas +++ b/src/day9/polynomial.pas @@ -2,138 +2,17 @@ uses sysutils, math; -{$include bigint.pas} +{$include fraction.pas} const MAX_POLYNOMIAL_LENGTH = 100; - EPSILON: double = 0; + type - fraction = record - numerator: int512; - denominator: int512; - end; polynomial = record degree: int64; { coefficients will be stored in reverse. ofc} coefficients: array[0..MAX_POLYNOMIAL_LENGTH] of fraction; end; - - -procedure print_fraction(a: fraction); -begin - if a.denominator <> 1 then - begin - print512d(a.numerator); - write('/'); - print512d(a.denominator); - end - else - print512d(a.numerator); -end; - -function c_fraction(num: int512; den: int512): fraction; -begin - if den = 0 then - writeln('holy hell what are you doing'); - - c_fraction.numerator := num; - c_fraction.denominator := den; - -end; - -operator := (f: int64) out_ : fraction; -begin - out_ := c_fraction(f, 1); -end; - - -function gcd(a, b: int512): int512; -var - r: int512; -begin - - while true do - begin - - r := a mod b; - - if r = 0 then - break; - - a := b; - b := r; - - end; - - gcd := b; -end; - -function simplify(f: fraction): fraction; -var - b: int512; - neg: boolean; - -begin - - neg := false; - if isneg(f.numerator) then - begin - neg := not neg; - f.numerator := -f.numerator; - end; - - if isneg(f.denominator) then - begin - neg := not neg; - f.denominator := -f.denominator; - end; - - b := gcd(f.numerator, f.denominator); - - if b <> 0 then - simplify := c_fraction(f.numerator div b, f.denominator div b) - else - simplify := f; - - if neg then - simplify.numerator := -simplify.numerator; - -end; - -{ add fractions } -operator + (a, b: fraction) out_: fraction; -//var - // g: int512; -begin - - // print_fraction(a); - // write(' '); - // print_fraction(b); - // write(' '); - - // g := gcd(a.denominator, b.denominator); - - out_.denominator := a.denominator * b.denominator; - out_.numerator := a.denominator * b.numerator + b.denominator * a.numerator; - - // print_fraction(out_); - // write(' '); - if abs(out_.numerator) > $7FFFFFFFFFFFFFFF then - out_ := simplify(out_); - // print_fraction(out_); - // writeln('ya'); -end; - -{ mult fractions } -operator * (a, b: fraction) out_: fraction; -begin - out_.denominator := a.denominator * b.denominator; - out_.numerator := a.numerator * b.numerator; - - //if out_.numerator > (1 shl 60) then - // out_ := simplify(out_); - -end; procedure fill_array_1(var a: array of fraction; l: int64 = MAX_POLYNOMIAL_LENGTH);