mirror of
https://github.com/plasmaofthedawn/2023adventofcode.git
synced 2024-10-18 08:16:25 -05:00
improvements to day 9
This commit is contained in:
parent
d17fcb67c5
commit
9366b8c03c
@ -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
131
src/day9/fraction.pas
Normal 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;
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user