{ Solutions to the Advent Of Code. Copyright (C) 2024 Stefan Müller This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . } unit UPolynomial; {$mode ObjFPC}{$H+} interface uses Classes, SysUtils, UBigInt; type TInt64Array = array of Int64; { TBigIntPolynomial } TBigIntPolynomial = object private FCoefficients: array of TBigInt; function GetDegree: Integer; function GetCoefficient(const AIndex: Integer): TBigInt; public property Degree: Integer read GetDegree; property Coefficient[const AIndex: Integer]: TBigInt read GetCoefficient; function CalcValueAt(const AX: Int64): TBigInt; function IsEqualTo(const AOther: TBigIntPolynomial): Boolean; function ScaleVariable(const AScaleFactor: TBigInt): TBigIntPolynomial; function ToString: string; class function Create(const ACoefficients: array of TBigInt): TBigIntPolynomial; static; end; { Operators } operator = (const A, B: TBigIntPolynomial): Boolean; operator <> (const A, B: TBigIntPolynomial): Boolean; implementation { TBigIntPolynomial } function TBigIntPolynomial.GetDegree: Integer; begin Result := Length(FCoefficients) - 1; end; function TBigIntPolynomial.GetCoefficient(const AIndex: Integer): TBigInt; begin Result := FCoefficients[AIndex]; end; function TBigIntPolynomial.CalcValueAt(const AX: Int64): TBigInt; var i: Integer; begin Result := TBigInt.Zero; for i := High(FCoefficients) downto 0 do Result := Result * AX + FCoefficients[i]; end; function TBigIntPolynomial.IsEqualTo(const AOther: TBigIntPolynomial): Boolean; var i: Integer; begin if Length(FCoefficients) = Length(AOther.FCoefficients) then begin Result := True; for i := 0 to Length(FCoefficients) - 1 do if FCoefficients[i] <> AOther.FCoefficients[i] then begin Result := False; Break; end; end else Result := False; end; function TBigIntPolynomial.ScaleVariable(const AScaleFactor: TBigInt): TBigIntPolynomial; var len, i: Integer; factor: TBigInt; begin if AScaleFactor <> TBigInt.Zero then begin len := Length(FCoefficients); SetLength(Result.FCoefficients, len); Result.FCoefficients[0] := FCoefficients[0]; factor := AScaleFactor; for i := 1 to len - 1 do begin Result.FCoefficients[i] := FCoefficients[i] * factor; factor := factor * AScaleFactor; end; end else SetLength(Result.FCoefficients, 0); end; function TBigIntPolynomial.ToString: string; var i: Integer; begin Result := FCoefficients[0].ToString; for i := 1 to Length(FCoefficients) - 1 do if i > 1 then Result := Result + ' + ' + FCoefficients[i].ToString + ' * x^' + IntToStr(i) else Result := Result + ' + ' + FCoefficients[i].ToString + ' * x'; end; class function TBigIntPolynomial.Create(const ACoefficients: array of TBigInt): TBigIntPolynomial; var high, i: integer; begin high := -1; for i := Length(ACoefficients) - 1 downto 0 do if ACoefficients[i] <> 0 then begin high := i; Break; end; if high >= 0 then begin SetLength(Result.FCoefficients, high + 1); for i := 0 to high do Result.FCoefficients[i] := ACoefficients[i]; end; end; { Operators } operator = (const A, B: TBigIntPolynomial): Boolean; begin Result := A.IsEqualTo(B); end; operator <> (const A, B: TBigIntPolynomial): Boolean; begin Result := not A.IsEqualTo(B); end; end.