improvements to day 9

This commit is contained in:
m 2023-12-17 09:21:05 -05:00
parent d17fcb67c5
commit 9366b8c03c
3 changed files with 133 additions and 124 deletions

View File

@ -88,7 +88,6 @@ begin
end; end;
end; end;
operator shl (a: int512; b: int32) o: int512; operator shl (a: int512; b: int32) o: int512;
var var
i: int32; i: int32;

131
src/day9/fraction.pas Normal file
View File

@ -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;

View File

@ -2,138 +2,17 @@
uses sysutils, math; uses sysutils, math;
{$include bigint.pas} {$include fraction.pas}
const const
MAX_POLYNOMIAL_LENGTH = 100; MAX_POLYNOMIAL_LENGTH = 100;
EPSILON: double = 0;
type type
fraction = record
numerator: int512;
denominator: int512;
end;
polynomial = record polynomial = record
degree: int64; degree: int64;
{ coefficients will be stored in reverse. ofc} { coefficients will be stored in reverse. ofc}
coefficients: array[0..MAX_POLYNOMIAL_LENGTH] of fraction; coefficients: array[0..MAX_POLYNOMIAL_LENGTH] of fraction;
end; 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); procedure fill_array_1(var a: array of fraction; l: int64 = MAX_POLYNOMIAL_LENGTH);