Added another WIP solution attempt

This commit is contained in:
Stefan Müller 2024-02-16 21:22:31 +01:00
parent cccf5693f7
commit 3d5235ad6e
4 changed files with 747 additions and 30 deletions

View File

@ -137,6 +137,14 @@
<Filename Value="solvers\UNeverTellMeTheOdds.pas"/> <Filename Value="solvers\UNeverTellMeTheOdds.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
</Unit> </Unit>
<Unit>
<Filename Value="UBigInt.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="UVector.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
</Units> </Units>
</ProjectOptions> </ProjectOptions>
<CompilerOptions> <CompilerOptions>

111
UVector.pas Normal file
View File

@ -0,0 +1,111 @@
{
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 <http://www.gnu.org/licenses/>.
}
unit UVector;
{$mode ObjFPC}{$H+}
interface
uses
Classes, SysUtils;
type
TVector3DataRange = 0..2;
TVector3Int64Data = array[TVector3DataRange] of Int64;
{ TVector3Int64 }
TVector3Int64 = object
private
function GetX: Int64;
function GetY: Int64;
function GetZ: Int64;
procedure SetX(AValue: Int64);
procedure SetY(AValue: Int64);
procedure SetZ(AValue: Int64);
public
Data: TVector3Int64Data;
property X: Int64 read GetX write SetX;
property Y: Int64 read GetY write SetY;
property Z: Int64 read GetZ write SetZ;
constructor Init(const AX, AY, AZ: Int64);
end;
//// Component-wise binary operators.
//operator - (const A, B: TVector3Int64): TVector3Int64;
//operator / (const A, B: TVector3Int64): TVector3Int64;
implementation
//operator - (const A, B: TVector3Int64): TVector3Int64;
//var
// i: TVector3DataRange;
//begin
// for i in TVector3DataRange do
// Result.Data[i] := A.Data[i] - B.Data[i];
//end;
//
//operator / (const A, B: TVector3Int64): TVector3Int64;
//var
// i: TVector3DataRange;
//begin
//for i in TVector3DataRange do
// Result.Data[i] := A.Data[i] / B.Data[i];
//end;
{ TVector3Int64 }
function TVector3Int64.GetX: Int64;
begin
Result := Data[0];
end;
function TVector3Int64.GetY: Int64;
begin
Result := Data[1];
end;
function TVector3Int64.GetZ: Int64;
begin
Result := Data[2];
end;
procedure TVector3Int64.SetX(AValue: Int64);
begin
Data[0] := AValue;
end;
procedure TVector3Int64.SetY(AValue: Int64);
begin
Data[1] := AValue;
end;
procedure TVector3Int64.SetZ(AValue: Int64);
begin
Data[2] := AValue;
end;
constructor TVector3Int64.Init(const AX, AY, AZ: Int64);
begin
X := AX;
Y := AY;
Z := AZ;
end;
end.

View File

@ -1,6 +1,6 @@
{ {
Solutions to the Advent Of Code. Solutions to the Advent Of Code.
Copyright (C) 2023 Stefan Müller Copyright (C) 2023-2024 Stefan Müller
This program is free software: you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
@ -22,26 +22,45 @@ unit UNeverTellMeTheOdds;
interface interface
uses uses
Classes, SysUtils, Generics.Collections, Math, USolver; Classes, SysUtils, Generics.Collections, Math, USolver, UVector;
type type
{ THailstone } { THailstone }
THailstone = record THailstone = class
X, Y, Z: Int64; public
VX, VY, VZ: Integer; Position, Velocity: TVector3Int64;
constructor Create(const ALine: string);
constructor Create(const APosition, AVelocity: TVector3Int64);
function GetParameterMinimum(const AMin, AMax: Int64): Int64;
function GetParameterMaximum(const AMin, AMax: Int64): Int64;
end; end;
THailstones = specialize TList<THailstone>; THailstones = specialize TObjectList<THailstone>;
//{ TFirstCollisionPolynomial }
//
//TFirstCollisionPolynomial = class
//private
// FA: array[0..10] of TBigInt;
// FH: array[0..6] of TBigInt;
// procedure NormalizeCoefficients;
//public
// procedure Init(constref AHailstone1, AHailstone2, AHailstone3: THailstone; const t_0, t_1, t_2: Int64);
// function EvaluateAt(const AT0: Int64): TBigInt;
// function CalcPositiveIntegerRoot: Int64;
// function CalcT1(const AT0: Int64): Int64;
//end;
{ TNeverTellMeTheOdds } { TNeverTellMeTheOdds }
TNeverTellMeTheOdds = class(TSolver) TNeverTellMeTheOdds = class(TSolver)
private private
FMin, FMax: Int64; FMin, FMax: Int64;
FHailStones: THailstones; FHailstones: THailstones;
function AreIntersecting(constref AHailstone1, AHailstone2: THailstone): Boolean; function AreIntersecting(constref AHailstone1, AHailstone2: THailstone): Boolean;
procedure FindRockThrow(const AIndex1, AIndex2, AIndex3: Integer);
public public
constructor Create(const AMin: Int64 = 200000000000000; const AMax: Int64 = 400000000000000); constructor Create(const AMin: Int64 = 200000000000000; const AMax: Int64 = 400000000000000);
destructor Destroy; override; destructor Destroy; override;
@ -51,8 +70,492 @@ type
function GetPuzzleName: string; override; function GetPuzzleName: string; override;
end; end;
const
CIterationThreshold = 0.00001;
CEpsilon = 0.0000000001;
implementation implementation
{ THailstone }
constructor THailstone.Create(const ALine: string);
var
split: TStringArray;
begin
split := ALine.Split([',', '@']);
Position.Init(
StrToInt64(Trim(split[0])),
StrToInt64(Trim(split[1])),
StrToInt64(Trim(split[2])));
Velocity.Init(
StrToInt64(Trim(split[3])),
StrToInt64(Trim(split[4])),
StrToInt64(Trim(split[5])));
//Position.init(
// StrToFloat(Trim(split[0])),
// StrToFloat(Trim(split[1])),
// StrToFloat(Trim(split[2])));
//Velocity.init(
// StrToFloat(Trim(split[3])),
// StrToFloat(Trim(split[4])),
// StrToFloat(Trim(split[5])));
end;
constructor THailstone.Create(const APosition, AVelocity: TVector3Int64);
begin
Position := APosition;
Velocity := AVelocity;
end;
function THailstone.GetParameterMinimum(const AMin, AMax: Int64): Int64;
var
i: TVector3DataRange;
boundary: Int64;
begin
Result := 0;
for i in TVector3DataRange do
begin
if Velocity.Data[i] > 0 then
boundary := AMin
else
boundary := AMax;
Result := Max(Result, Ceil64((boundary - Position.Data[i]) / Velocity.Data[i]));
end;
end;
function THailstone.GetParameterMaximum(const AMin, AMax: Int64): Int64;
var
i: TVector3DataRange;
boundary: Int64;
begin
Result := Int64.MaxValue;
for i in TVector3DataRange do
begin
if Velocity.Data[i] > 0 then
boundary := AMax
else
boundary := AMin;
Result := Min(Result, Floor64((boundary - Position.Data[i]) / Velocity.Data[i]));
end;
end;
//{ TFirstCollisionPolynomial }
//
//procedure TFirstCollisionPolynomial.NormalizeCoefficients;
//var
// shift: Integer;
// i: Low(FA)..High(FA);
// //gcd: TBigInt;
//begin
// // Eliminates zero constant term.
// shift := 0;
// while (shift <= High(FA)) and (FA[shift] = 0) do
// Inc(shift);
//
// if shift <= High(FA) then
// begin
// if shift > 0 then
// begin
// for i := Low(FA) to High(FA) - shift do
// FA[i] := FA[i + shift];
// for i := High(FA) - shift + 1 to High(FA) do
// FA[i] := 0;
// end;
//
// //// Finds GCD of all coefficients.
// //gcd := FA[Low(FA)];
// //for i := Low(FA) + 1 to High(FA) do
// // if FA[i] <> 0 then
// // gcd := TNumberTheory.GreatestCommonDivisor(gcd, FA[i]);
// //WriteLn('GCD: ', gcd);
// //
// //for i := Low(FA) to High(FA) do
// // FA[i] := FA[i] div gcd;
// end;
//
// //WriteLn('(', FA[10], ') * x^10 + (', FA[9], ') * x^9 + (', FA[8], ') * x^8 + (', FA[7], ') * x^7 + (',
// // FA[6], ') * x^6 + (', FA[5], ') * x^5 + (', FA[4], ') * x^4 + (', FA[3], ') * x^3 + (', FA[2], ') * x^2 + (',
// // FA[1], ') * x + (', FA[0], ')');
//end;
//
//procedure TFirstCollisionPolynomial.Init(constref AHailstone1, AHailstone2, AHailstone3: THailstone; const t_0, t_1,
// t_2: Int64);
//var
// P_00, P_01, P_02, P_10, P_11, P_12, P_20, P_21, P_22,
// V_00, V_01, V_02, V_10, V_11, V_12, V_20, V_21, V_22: Int64;
// k: array[0..139] of TBigInt;
// // For debug calculations
// act, a_1, a_2, b_0, b_1, c_0, c_1, d_0, d_1, e_0, e_1, f_0, f_1, f_2: Int64;
//begin
// // Solving this non-linear equation system, with velocities V_i and start positions P_i:
// // V_0 * t_0 + P_0 = V_x * t_0 + P_x
// // V_1 * t_1 + P_1 = V_x * t_1 + P_x
// // V_2 * t_2 + P_2 = V_x * t_2 + P_x
// // Which gives:
// // P_x = (V_0 - V_x) * t_0 + P_0
// // V_x = (V_0 * t_0 - V_1 * t_1 + P_0 - P_1) / (t_0 - t_1)
// // And with vertex components:
// // 1: 0 = (t_1 - t_0) * (V_00 * t_0 - V_20 * t_2 + P_00 - P_20) - (t_2 - t_0) * (V_00 * t_0 - V_10 * t_1 + P_00 - P_10)
// // 2: t_1 = (((V_01 - V_21) * t_2 + P_11 - P_21) * t_0 + (P_01 - P_11) * t_2)
// // / ((V_01 - V_11) * t_0 + (V_11 - V_21) * t_2 + P_01 - P_21)
// // 3: t_2 = (((V_02 - V_12) * t_1 + P_22 - P_12) * t_0 + (P_02 - P_22) * t_1)
// // / ((V_02 - V_22) * t_0 + (V_22 - V_12) * t_1 + P_02 - P_12)
// // for t_0, t_1, t_2 not pairwise equal.
// // With some substitutions depending only on t_0 this gives
// // 1: 0 = (t_1 - t_0) * (f_2 - V_20 * t_2) - (t_2 - t_0) * (f_1 - V_10 * t_1)
// // 2: t_1 = (b_0 + b_1 * t_2) / (c_0 + c_1 * t_2)
// // 3: t_2 = (d_0 + d_1 * t_1) / (e_0 + e_1 * t_1)
// // And 3 in 2 gives:
// // 4: g_2 * t_1^2 - g_1 * t_1 - g_0 = 0
// // Then, with 4 and 3 in 1 and lengthy calculations with many substitutions (see constants k below, now independent of
// // t_0), the following polynomial can be constructed, with t_0 being a positive integer root of this polynomial.
// // y = a_10 * x^10 + a_9 * x^9 + ... + a_0
//
// P_00 := Round(AHailstone1.Position.data[0]);
// P_01 := Round(AHailstone1.Position.data[1]);
// P_02 := Round(AHailstone1.Position.data[2]);
// P_10 := Round(AHailstone2.Position.data[0]);
// P_11 := Round(AHailstone2.Position.data[1]);
// P_12 := Round(AHailstone2.Position.data[2]);
// P_20 := Round(AHailstone3.Position.data[0]);
// P_21 := Round(AHailstone3.Position.data[1]);
// P_22 := Round(AHailstone3.Position.data[2]);
// V_00 := Round(AHailstone1.Velocity.data[0]);
// V_01 := Round(AHailstone1.Velocity.data[1]);
// V_02 := Round(AHailstone1.Velocity.data[2]);
// V_10 := Round(AHailstone2.Velocity.data[0]);
// V_11 := Round(AHailstone2.Velocity.data[1]);
// V_12 := Round(AHailstone2.Velocity.data[2]);
// V_20 := Round(AHailstone3.Velocity.data[0]);
// V_21 := Round(AHailstone3.Velocity.data[1]);
// V_22 := Round(AHailstone3.Velocity.data[2]);
//
// k[0] := P_00 - P_20;
// k[1] := P_00 - P_10;
// k[2] := P_11 - P_21;
// k[3] := P_01 - P_11;
// k[4] := P_01 - P_21;
// k[5] := P_22 - P_12;
// k[6] := P_02 - P_22;
// k[7] := P_02 - P_12;
// k[8] := V_11 - V_21;
// k[9] := V_22 - V_12;
// k[10] := V_01 - V_21;
// k[11] := V_01 - V_11;
// k[12] := V_02 - V_12;
// k[13] := V_02 - V_22;
//
// FH[0] := k[11] * k[9] + k[8] * k[12];
// FH[1] := k[4] * k[9] + k[8] * k[6];
// FH[2] := k[11] * k[13] - k[10] * k[12];
// FH[3] := k[11] * k[7] + k[4] * k[13] + k[8] * k[5] - k[2] * k[9] - k[10] * k[6] - k[3] * k[12];
// FH[4] := k[4] * k[7] - k[3] * k[6];
// FH[5] := k[10] * k[5] + k[2] * k[13];
// FH[6] := k[3] * k[5] + k[2] * k[7];
//
// k[14] := V_00 * k[9] - V_20 * k[12];
// k[15] := k[0] * k[9] - V_20 * k[6];
// k[16] := V_00 * k[13];
// k[17] := V_00 * k[7] + k[0] * k[13] - V_20 * k[5];
// k[18] := k[0] * k[7];
// k[19] := k[5] - k[7];
// k[20] := 2 * FH[2] * FH[3];
// k[21] := FH[3] * FH[3];
// k[22] := k[21] + 2 * FH[2] * FH[4];
// k[23] := 2 * FH[3] * FH[4];
// k[24] := 2 * FH[0] * FH[1];
// k[25] := FH[0] * FH[0]; // KILL?
// k[26] := FH[5] * k[25]; // KILL?
// k[126] := FH[5] * FH[0];
// k[127] := FH[5] * FH[1] + FH[6] * FH[0];
// k[128] := FH[6] * FH[1];
// k[27] := FH[5] * k[24] + FH[6] * k[25]; // KILL?
// k[28] := FH[1] * FH[1]; // KILL?
// k[29] := FH[5] * k[28] + FH[6] * k[24]; // KILL?
// k[30] := FH[6] * k[28]; // KILL?
// k[31] := FH[2] * FH[2];
// k[132] := k[20] + 4 * k[126];
// k[133] := k[22] + 4 * k[127];
// k[134] := k[23] + 4 * k[128];
// k[32] := k[31] + 4 * k[26]; // KILL?
// k[33] := k[20] + 4 * k[27]; // KILL?
// k[34] := k[22] + 4 * k[29]; // KILL?
// k[35] := k[23] + 4 * k[30]; // KILL?
// k[36] := k[31] + 2 * k[26]; // KILL?
// k[37] := k[20] + 2 * k[27]; // KILL?
// k[38] := k[22] + 2 * k[29]; // KILL?
// k[39] := k[23] + 2 * k[30]; // KILL?
// k[137] := k[20] + 2 * k[126];
// k[138] := k[22] + 2 * k[127];
// k[139] := k[23] + 2 * k[128];
// k[40] := k[14] + V_10 * (k[12] - k[9]);
// k[41] := k[15] + V_10 * k[6];
// k[42] := k[16] - k[14] - V_10 * k[13] - (k[12] - k[9]) * V_00;
// k[43] := k[17] - k[15] + V_10 * k[19] - (k[12] - k[9]) * k[1] - k[6] * V_00;
// k[44] := k[18] - k[6] * k[1];
// k[45] := k[42] * FH[0] - k[40] * FH[2];
// k[46] := k[42] * FH[1] + k[43] * FH[0] - k[41] * FH[2] - k[40] * FH[3];
// k[47] := k[43] * FH[1] + k[44] * FH[0] - k[41] * FH[3] - k[40] * FH[4];
// k[48] := k[44] * FH[1] - k[41] * FH[4];
// k[49] := k[42] * FH[2];
// k[50] := k[40] * k[31] - k[49] * FH[0];
// k[51] := k[42] * FH[3] + k[43] * FH[2];
// k[52] := k[40] * k[137] + k[41] * k[31] - k[51] * FH[0] - k[49] * FH[1];
// k[53] := k[42] * FH[4] + k[43] * FH[3] + k[44] * FH[2];
// k[54] := k[40] * k[138] + k[41] * k[137] - k[53] * FH[0] - k[51] * FH[1];
// k[55] := k[43] * FH[4] + k[44] * FH[3];
// k[56] := k[40] * k[139] + k[41] * k[138] - k[55] * FH[0] - k[53] * FH[1];
// k[57] := k[44] * FH[4];
// k[58] := FH[4] * FH[4];
// k[59] := k[40] * k[58] + k[41] * k[139] - k[57] * FH[0] - k[55] * FH[1];
// k[60] := k[41] * k[58] - k[57] * FH[1];
// k[61] := k[13] * V_00 - k[16];
// k[62] := 2 * k[25] * k[61];
// k[63] := k[13] * k[1] - k[19] * V_00 - k[17];
// k[64] := 2 * (k[24] * k[61] + k[25] * k[63]);
// k[65] := - k[19] * k[1] - k[18];
// k[66] := 2 * (k[28] * k[61] + k[24] * k[63] + k[25] * k[65]);
// k[67] := 2 * (k[28] * k[63] + k[24] * k[65]);
// k[68] := 2 * k[28] * k[65];
// k[69] := k[50] + k[62];
// k[70] := k[52] + k[64];
// k[71] := k[54] + k[66];
// k[72] := k[56] + k[67];
// k[73] := k[59] + k[68];
// k[74] := k[45] * k[45];
// k[75] := 2 * k[45] * k[46];
// k[76] := k[46] * k[46] + 2 * k[45] * k[47];
// k[77] := 2 * (k[45] * k[48] + k[46] * k[47]);
// k[78] := k[47] * k[47] + 2 * k[46] * k[48];
// k[79] := 2 * k[47] * k[48];
// k[80] := k[48] * k[48];
//
// FA[0] := k[58] * k[80] - k[60] * k[60];
// FA[1] := k[134] * k[80] + k[58] * k[79] - 2 * k[73] * k[60];
// FA[2] := k[133] * k[80] + k[134] * k[79] + k[58] * k[78] - k[73] * k[73] - 2 * k[72] * k[60];
// FA[3] := k[133] * k[79] + k[134] * k[78] + k[58] * k[77] + k[132] * k[80]
// - 2 * (k[71] * k[60] + k[72] * k[73]);
// FA[4] := k[31] * k[80] + k[133] * k[78] + k[134] * k[77] + k[58] * k[76] + k[132] * k[79] - k[72] * k[72]
// - 2 * (k[70] * k[60] + k[71] * k[73]);
// FA[5] := k[31] * k[79] + k[133] * k[77] + k[134] * k[76] + k[58] * k[75] + k[132] * k[78]
// - 2 * (k[69] * k[60] + k[70] * k[73] + k[71] * k[72]);
// FA[6] := k[31] * k[78] + k[133] * k[76] + k[134] * k[75] + k[58] * k[74] + k[132] * k[77] - k[71] * k[71]
// - 2 * (k[69] * k[73] + k[70] * k[72]);
// FA[7] := k[31] * k[77] + k[133] * k[75] + k[134] * k[74] + k[132] * k[76] - 2 * (k[69] * k[72] + k[70] * k[71]);
// FA[8] := k[31] * k[76] + k[132] * k[75] + k[133] * k[74] - k[70] * k[70] - 2 * k[69] * k[71];
// FA[9] := k[31] * k[75] + k[132] * k[74] - 2 * k[69] * k[70];
// FA[10] := k[31] * k[74] - k[69] * k[69];
//
// // Debug calculations
// //a_1 := V_00 * t_0 + P_00 - P_20;
// //a_2 := V_00 * t_0 + P_00 - P_10;
// //b_0 := (P_11 - P_21) * t_0;
// //b_1 := (V_01 - V_21) * t_0 + P_01 - P_11;
// //c_0 := (V_01 - V_11) * t_0 + P_01 - P_21;
// //c_1 := V_11 - V_21;
// //d_0 := (P_22 - P_12) * t_0;
// //d_1 := (V_02 - V_12) * t_0 + P_02 - P_22;
// //e_0 := (V_02 - V_22) * t_0 + P_02 - P_12;
// //e_1 := V_22 - V_12;
// //f_2 := c_0 * e_1 + c_1 * d_1;
// //f_1 := c_0 * e_0 + c_1 * d_0 - b_0 * e_1 - b_1 * d_1;
// //f_0 := b_1 * d_0 + b_0 * e_0;
// //
// //act := f_2 * t_1 * t_1 + f_1 * t_1 - f_0;
// //Write('debug10: ', 0 = act, ' ');
// //
// //if f_2 <> 0 then
// //begin
// // act := Round(- f_1 / (2 * f_2) + Sqrt((f_1 / (2 * f_2)) * (f_1 / (2 * f_2)) + f_0 / f_2));
// // Write('debug15: ', t_1 = act);
// // act := Round(- f_1 / (2 * f_2) - Sqrt((f_1 / (2 * f_2)) * (f_1 / (2 * f_2)) + f_0 / f_2));
// // Write(' OR ', t_1 = act, ' ');
// //end;
// //
// //act := (e_0 + e_1 * t_1) * t_2 - (d_0 + d_1 * t_1);
// //Write('debug20: ', 0 = act, ' ');
// //
// //act := (a_1 * e_1 - V_20 * d_1 + V_10 * (d_1 - e_1 * t_0)) * t_1 * t_1
// // + (a_1 * e_0 - V_20 * d_0 - t_0 * (a_1 * e_1 - V_20 * d_1) - (d_1 - e_1 * t_0) * a_2 + V_10 * (d_0 - e_0 * t_0)) * t_1
// // + t_0 * (V_20 * d_0 - a_1 * e_0) + (e_0 * t_0 - d_0) * a_2;
// //Write('debug30: ', 0 = act, ' ');
// //
// //act := Round((a_1 * e_1 - V_20 * d_1 + V_10 * (d_1 - e_1 * t_0)) * (f_1 * f_1 + 2 * f_0 * f_2 - f_1 * Sqrt(f_1 * f_1 + 4 * f_0 * f_2))
// // + (a_1 * e_0 - V_20 * d_0 - t_0 * (a_1 * e_1 - V_20 * d_1) - (d_1 - e_1 * t_0) * a_2 + V_10 * (d_0 - e_0 * t_0)) * (- f_1 * f_2 + f_2 * Sqrt(f_1 * f_1 + 4 * f_0 * f_2))
// // + t_0 * (V_20 * d_0 - a_1 * e_0) * 2 * f_2 * f_2 + (e_0 * t_0 - d_0) * a_2 * 2 * f_2 * f_2);
// //Write('debug40: ', 0 = act, ' ');
// //
// //Write('debug41: ',
// // a_1 * k[9] - V_20 * d_1
// // = k[14] * t_0 + k[15], ' ');
// //Write('debug42: ',
// // d_1 - k[9] * t_0
// // = (k[12] - k[9]) * t_0 + k[6], ' ');
// //Write('debug43: ',
// // a_1 * e_0 - V_20 * d_0
// // = k[16] * t_0 * t_0 + k[17] * t_0 + k[18], ' ');
// //Write('debug44: ',
// // d_0 - e_0 * t_0
// // = - k[13] * t_0 * t_0 + k[19] * t_0, ' ');
// //Write('debug45: ',
// // f_1 * f_1
// // = FH[2] * FH[2] * t_0 * t_0 * t_0 * t_0 + k[20] * t_0 * t_0 * t_0 + k[22] * t_0 * t_0 + k[23] * t_0 + FH[4] * FH[4], ' ');
// //Write('debug46: ',
// // f_2 * f_2
// // = FH[0] * FH[0] * t_0 * t_0 + k[24] * t_0 + FH[1] * FH[1], ' ');
// //Write('debug47: ',
// // f_0 * f_2
// // = k[126] * t_0 * t_0 * t_0 + k[127] * t_0 * t_0 + k[128] * t_0, ' ');
// //Write('debug48: ',
// // f_1 * f_1 + 4 * f_0 * f_2
// // = k[31] * t_0 * t_0 * t_0 * t_0 + k[132] * t_0 * t_0 * t_0 + k[133] * t_0 * t_0 + k[134] * t_0 + k[58], ' ');
// //Write('debug49: ',
// // f_1 * f_1 + 2 * f_0 * f_2
// // = k[31] * t_0 * t_0 * t_0 * t_0 + k[137] * t_0 * t_0 * t_0 + k[138] * t_0 * t_0 + k[139] * t_0 + k[58], ' ');
// //
// //act := Round((k[14] * t_0 + k[15] + V_10 * ((k[12] - k[9]) * t_0 + k[6])) * (k[31] * t_0 * t_0 * t_0 * t_0 + k[137] * t_0 * t_0 * t_0 + k[138] * t_0 * t_0 + k[139] * t_0 + k[58] - f_1 * sqrt(f_1 * f_1 + 4 * f_0 * f_2))
// // + (k[16] * t_0 * t_0 + k[17] * t_0 + k[18] - t_0 * (k[14] * t_0 + k[15]) - ((k[12] - k[9]) * t_0 + k[6]) * a_2 - V_10 * (k[13] * t_0 * t_0 - k[19] * t_0)) * (- f_1 * f_2 + f_2 * sqrt(f_1 * f_1 + 4 * f_0 * f_2))
// // - 2 * t_0 * (k[16] * t_0 * t_0 + k[17] * t_0 + k[18]) * (FH[0] * FH[0] * t_0 * t_0 + k[24] * t_0 + FH[1] * FH[1]) + 2 * (k[13] * t_0 * t_0 - k[19] * t_0) * a_2 * (FH[0] * FH[0] * t_0 * t_0 + k[24] * t_0 + FH[1] * FH[1]));
// //Write('debug50: ', 0 = act, ' ');
// //
// //Write('debug53: ',
// // 0 = Round((k[40] * t_0 + k[41]) * (k[31] * t_0 * t_0 * t_0 * t_0 + k[137] * t_0 * t_0 * t_0 + k[138] * t_0 * t_0 + k[139] * t_0 + k[58] - f_1 * sqrt(f_1 * f_1 + 4 * f_0 * f_2))
// // + ((k[16] - k[14] - V_10 * k[13] - (k[12] - k[9]) * V_00) * t_0 * t_0 + (k[17] - k[15] + V_10 * k[19] - (k[12] - k[9]) * k[1] - k[6] * V_00) * t_0 + k[18] - k[6] * k[1]) * (- f_1 * f_2 + f_2 * sqrt(f_1 * f_1 + 4 * f_0 * f_2))
// // - 2 * t_0 * (k[16] * t_0 * t_0 + k[17] * t_0 + k[18]) * (FH[0] * FH[0] * t_0 * t_0 + k[24] * t_0 + FH[1] * FH[1]) + 2 * (k[13] * t_0 * t_0 - k[19] * t_0) * a_2 * (FH[0] * FH[0] * t_0 * t_0 + k[24] * t_0 + FH[1] * FH[1])),
// // ' ');
// //
// //Write('debug55: ',
// // 0 = Round((k[40] * t_0 + k[41]) * (k[31] * t_0 * t_0 * t_0 * t_0 + k[137] * t_0 * t_0 * t_0 + k[138] * t_0 * t_0 + k[139] * t_0 + k[58])
// // - (k[40] * t_0 + k[41]) * f_1 * sqrt(f_1 * f_1 + 4 * f_0 * f_2)
// // + (k[42] * t_0 * t_0 + k[43] * t_0 + k[44]) * (- f_1 * f_2 + f_2 * sqrt(f_1 * f_1 + 4 * f_0 * f_2))
// // - 2 * t_0 * (k[16] * t_0 * t_0 + k[17] * t_0 + k[18]) * (FH[0] * FH[0] * t_0 * t_0 + k[24] * t_0 + FH[1] * FH[1]) + 2 * (k[13] * t_0 * t_0 - k[19] * t_0) * a_2 * (FH[0] * FH[0] * t_0 * t_0 + k[24] * t_0 + FH[1] * FH[1])),
// // ' ');
// //
// //Write('debug70: ',
// // 0 = Round(((k[42] * t_0 * t_0 + k[43] * t_0 + k[44]) * (FH[0] * t_0 + FH[1]) - (k[40] * t_0 + k[41]) * (FH[2] * t_0 * t_0 + FH[3] * t_0 + FH[4])) * sqrt(f_1 * f_1 + 4 * f_0 * f_2))
// // + (k[40] * t_0 + k[41]) * (k[31] * t_0 * t_0 * t_0 * t_0 + k[137] * t_0 * t_0 * t_0 + k[138] * t_0 * t_0 + k[139] * t_0 + k[58])
// // - (k[42] * t_0 * t_0 + k[43] * t_0 + k[44]) * (FH[2] * t_0 * t_0 + FH[3] * t_0 + FH[4]) * (FH[0] * t_0 + FH[1])
// // - 2 * t_0 * (k[16] * t_0 * t_0 + k[17] * t_0 + k[18]) * (FH[0] * FH[0] * t_0 * t_0 + k[24] * t_0 + FH[1] * FH[1]) + 2 * (k[13] * t_0 * t_0 - k[19] * t_0) * (V_00 * t_0 + k[1]) * (FH[0] * FH[0] * t_0 * t_0 + k[24] * t_0 + FH[1] * FH[1]),
// // ' ');
////
//// Write('debug73: ',
//// 0 = Round((
//// (k[42] * FH[0] - k[40] * FH[2]) * t_0 * t_0 * t_0
//// + (k[42] * FH[1] + k[43] * FH[0] - k[41] * FH[2] - k[40] * FH[3]) * t_0 * t_0
//// + (k[43] * FH[1] + k[44] * FH[0] - k[41] * FH[3] - k[40] * FH[4]) * t_0
//// + k[44] * FH[1] - k[41] * FH[4]
//// ) * sqrt(f_1 * f_1 + 4 * f_0 * f_2))
//// + (k[40] * k[31] - k[42] * FH[2] * FH[0]) * t_0 * t_0 * t_0 * t_0 * t_0
//// + (k[40] * k[137] + k[41] * k[31] - k[42] * FH[3] * FH[0] - k[43] * FH[2] * FH[0] - k[42] * FH[2] * FH[1]) * t_0 * t_0 * t_0 * t_0
//// + (k[40] * k[138] + k[41] * k[137] - k[42] * FH[4] * FH[0] - k[43] * FH[3] * FH[0] - k[44] * FH[2] * FH[0] - k[42] * FH[3] * FH[1] - k[43] * FH[2] * FH[1]) * t_0 * t_0 * t_0
//// + (k[40] * k[139] + k[41] * k[138] - k[43] * FH[4] * FH[0] - k[44] * FH[3] * FH[0] - k[42] * FH[4] * FH[1] - k[43] * FH[3] * FH[1] - k[44] * FH[2] * FH[1]) * t_0 * t_0
//// + (k[40] * k[58] + k[41] * k[139] - k[44] * FH[4] * FH[0] - k[43] * FH[4] * FH[1] - k[44] * FH[3] * FH[1]) * t_0
//// + k[41] * k[58] - k[44] * FH[4] * FH[1]
//// + 2 * (k[13] * V_00 * FH[0] * FH[0] - k[16] * FH[0] * FH[0]) * t_0 * t_0 * t_0 * t_0 * t_0
//// + 2 * (k[13] * V_00 * k[24] + k[13] * k[1] * FH[0] * FH[0] - k[19] * V_00 * FH[0] * FH[0] - k[16] * k[24] - k[17] * FH[0] * FH[0]) * t_0 * t_0 * t_0 * t_0
//// + 2 * (k[13] * V_00 * FH[1] * FH[1] + k[13] * k[1] * k[24] - k[19] * V_00 * k[24] - k[19] * k[1] * FH[0] * FH[0] - k[16] * FH[1] * FH[1] - k[17] * k[24] - k[18] * FH[0] * FH[0]) * t_0 * t_0 * t_0
//// + 2 * (k[13] * k[1] * FH[1] * FH[1] - k[19] * V_00 * FH[1] * FH[1] - k[19] * k[1] * k[24] - k[17] * FH[1] * FH[1] - k[18] * k[24]) * t_0 * t_0
//// + 2 * (- k[19] * k[1] * FH[1] * FH[1] - k[18] * FH[1] * FH[1]) * t_0,
//// ' ');
////
//// Write('debug78: ',
//// 0 = Round((k[45] * t_0 * t_0 * t_0 + k[46] * t_0 * t_0 + k[47] * t_0 + k[48]) * sqrt(f_1 * f_1 + 4 * f_0 * f_2))
//// + (k[50] + k[62]) * t_0 * t_0 * t_0 * t_0 * t_0 + (k[52] + k[64]) * t_0 * t_0 * t_0 * t_0 + (k[54] + k[66]) * t_0 * t_0 * t_0 + (k[56] + k[67]) * t_0 * t_0 + (k[59] + k[68]) * t_0 + k[60],
//// ' ');
////
//// Write('debug80: ',
//// 0 = Round((k[45] * t_0 * t_0 * t_0 + k[46] * t_0 * t_0 + k[47] * t_0 + k[48]) * sqrt(k[31] * t_0 * t_0 * t_0 * t_0 + k[132] * t_0 * t_0 * t_0 + k[133] * t_0 * t_0 + k[134] * t_0 + k[58])
//// + k[69] * t_0 * t_0 * t_0 * t_0 * t_0 + k[70] * t_0 * t_0 * t_0 * t_0 + k[71] * t_0 * t_0 * t_0 + k[72] * t_0 * t_0 + k[73] * t_0 + k[60]),
//// ' ');
//// WriteLn;
//// WriteLn(' 0 = ((', k[45], ') * x^3 + (', k[46], ') * x^2 + (', k[47], ') * x + (', k[48], ')) * sqrt((', k[31], ') * x^4 + (', k[132], ') * x^3 + (', k[133], ') * x^2 + (', k[134], ') * x + (', k[58], ')) + (',
//// k[69], ') * x^5 + (', k[70], ') * x^4 + (', k[71], ') * x^3 + (', k[72], ') * x^2 + (', k[73], ') * x + (', k[60], ')');
//
// Write('debug83: ',
// (k[45] * t_0 * t_0 * t_0 + k[46] * t_0 * t_0 + k[47] * t_0 + k[48]) * (k[45] * t_0 * t_0 * t_0 + k[46] * t_0 * t_0 + k[47] * t_0 + k[48]) * (k[31] * t_0 * t_0 * t_0 * t_0 + k[132] * t_0 * t_0 * t_0 + k[133] * t_0 * t_0 + k[134] * t_0 + k[58]) =
// (k[69] * t_0 * t_0 * t_0 * t_0 * t_0 + k[70] * t_0 * t_0 * t_0 * t_0 + k[71] * t_0 * t_0 * t_0 + k[72] * t_0 * t_0 + k[73] * t_0 + k[60]) * (k[69] * t_0 * t_0 * t_0 * t_0 * t_0 + k[70] * t_0 * t_0 * t_0 * t_0 + k[71] * t_0 * t_0 * t_0 + k[72] * t_0 * t_0 + k[73] * t_0 + k[60]),
// ' ');
// Write('debug85: ',
// 0 =
// (
// k[45] * k[45] * t_0 * t_0 * t_0 * t_0 * t_0 * t_0
// + 2 * k[45] * k[46] * t_0 * t_0 * t_0 * t_0 * t_0
// + k[46] * k[46] * t_0 * t_0 * t_0 * t_0
// + 2 * k[45] * k[47] * t_0 * t_0 * t_0 * t_0
// + 2 * k[45] * k[48] * t_0 * t_0 * t_0
// + 2 * k[46] * k[47] * t_0 * t_0 * t_0
// + k[47] * k[47] * t_0 * t_0
// + 2 * k[46] * k[48] * t_0 * t_0
// + 2 * k[47] * k[48] * t_0
// + k[48] * k[48]
// ) * (k[31] * t_0 * t_0 * t_0 * t_0 + k[132] * t_0 * t_0 * t_0 + k[133] * t_0 * t_0 + k[134] * t_0 + k[58])
// - k[69] * k[69] * t_0 * t_0 * t_0 * t_0 * t_0 * t_0 * t_0 * t_0 * t_0 * t_0
// - 2 * k[69] * k[70] * t_0 * t_0 * t_0 * t_0 * t_0 * t_0 * t_0 * t_0 * t_0
// - (k[70] * k[70] + 2 * k[69] * k[71]) * t_0 * t_0 * t_0 * t_0 * t_0 * t_0 * t_0 * t_0
// - 2 * (k[69] * k[72] + k[70] * k[71]) * t_0 * t_0 * t_0 * t_0 * t_0 * t_0 * t_0
// - (k[71] * k[71] + 2 * k[69] * k[73] + 2 * k[70] * k[72]) * t_0 * t_0 * t_0 * t_0 * t_0 * t_0
// - 2 * (k[69] * k[60] + k[70] * k[73] + k[71] * k[72]) * t_0 * t_0 * t_0 * t_0 * t_0
// - (k[72] * k[72] + 2 * k[70] * k[60] + 2 * k[71] * k[73]) * t_0 * t_0 * t_0 * t_0
// - 2 * (k[71] * k[60] + k[72] * k[73]) * t_0 * t_0 * t_0
// - (k[73] * k[73] + 2 * k[72] * k[60]) * t_0 * t_0
// - 2 * k[73] * k[60] * t_0
// - k[60] * k[60],
// ' ');
//
// WriteLn('debug96: ', EvaluateAt(t_0) = 0);
//
// NormalizeCoefficients;
//
// WriteLn('debug99: ', EvaluateAt(t_0) = 0, ' ');
//end;
//
//function TFirstCollisionPolynomial.EvaluateAt(const AT0: Int64): TBigInt;
//var
// i: Low(FA)..High(FA);
//begin
// Result := TBigInt.Zero;
// for i := High(FA) downto Low(FA) do
// Result := Result * AT0 + FA[i];
//end;
//
//function TFirstCollisionPolynomial.CalcPositiveIntegerRoot: Int64;
//var
// dividers: TDividers;
// factors: TInt64Array;
// divider: Int64;
//begin
// Result := 0;
// //factors := TIntegerFactorization.PollardsRhoAlgorithm(FA[0]);
// //dividers := TDividers.Create(factors);
// //
// //try
// //for divider in dividers do
// //begin
// // //WriteLn('Check if ', divider, ' is a root...');
// // if EvaluateAt(divider) = 0 then
// // begin
// // Result := divider;
// // Break;
// // end;
// //end;
// //
// //finally
// // dividers.Free;
// //end;
//end;
//
//function TFirstCollisionPolynomial.CalcT1(const AT0: Int64): Int64;
//var
// g_0, g_1, g_2: Int64;
// g: Extended;
//begin
// //g_2 := FH[0] * AT0 + FH[1];
// //g_1 := FH[2] * AT0 * AT0 + FH[3] * AT0 + FH[4];
// //g_0 := FH[5] * AT0 * AT0 + FH[6] * AT0;
// //g := - g_1 / (2 * g_2);
// //Result := Round(g + sqrt(g * g + g_0));
//end;
{ TNeverTellMeTheOdds } { TNeverTellMeTheOdds }
function TNeverTellMeTheOdds.AreIntersecting(constref AHailstone1, AHailstone2: THailstone): Boolean; function TNeverTellMeTheOdds.AreIntersecting(constref AHailstone1, AHailstone2: THailstone): Boolean;
@ -60,58 +563,141 @@ var
m1, m2, x, y: Double; m1, m2, x, y: Double;
begin begin
Result := False; Result := False;
m1 := AHailstone1.VY / AHailstone1.VX; m1 := AHailstone1.Velocity.Y / AHailstone1.Velocity.X;
m2 := AHailstone2.VY / AHailstone2.VX; //m1 := AHailstone1.Velocity.data[1] / AHailstone1.Velocity.data[0];
m2 := AHailstone2.Velocity.Y / AHailstone2.Velocity.X;
//m2 := AHailstone2.Velocity.data[1] / AHailstone2.Velocity.data[0];
if m1 <> m2 then if m1 <> m2 then
begin begin
x := (AHailstone2.Y - m2 * AHailstone2.X - AHailstone1.Y + m1 * AHailstone1.X) / (m1 - m2); x := (AHailstone2.Position.Y - m2 * AHailstone2.Position.X
- AHailstone1.Position.Y + m1 * AHailstone1.Position.X)
/ (m1 - m2);
//x := (AHailstone2.Position.data[1] - m2 * AHailstone2.Position.data[0]
// - AHailstone1.Position.data[1] + m1 * AHailstone1.Position.data[0])
// / (m1 - m2);
if (FMin <= x) and (x <= FMax) if (FMin <= x) and (x <= FMax)
and (x * Sign(AHailstone1.VX) >= AHailstone1.X * Sign(AHailstone1.VX)) and (x * Sign(AHailstone1.Velocity.X) >= AHailstone1.Position.X * Sign(AHailstone1.Velocity.X))
and (x * Sign(AHailstone2.VX) >= AHailstone2.X * Sign(AHailstone2.VX)) then //and (x * Sign(AHailstone1.Velocity.data[0]) >= AHailstone1.Position.data[0] * Sign(AHailstone1.Velocity.data[0]))
and (x * Sign(AHailstone2.Velocity.X) >= AHailstone2.Position.X * Sign(AHailstone2.Velocity.X))
//and (x * Sign(AHailstone2.Velocity.data[0]) >= AHailstone2.Position.data[0] * Sign(AHailstone2.Velocity.data[0]))
then
begin begin
y := m1 * (x - AHailstone1.X) + AHailstone1.Y; y := m1 * (x - AHailstone1.Position.X) + AHailstone1.Position.Y;
y := m1 * (x - AHailstone1.Position.X) + AHailstone1.Position.Y;
if (FMin <= y) and (y <= FMax) then if (FMin <= y) and (y <= FMax) then
Result := True Result := True
end; end;
end; end;
end; end;
// For debug calculations:
Const
T : array[0..4] of Byte = (5, 3, 4, 6, 1);
procedure TNeverTellMeTheOdds.FindRockThrow(const AIndex1, AIndex2, AIndex3: Integer);
var
i: TVector3DataRange;
//i, j, k: Integer;
//x0, x1, x2: Extended;
//f: TFirstCollisionPolynomial;
t0, t1, t2, t0Min, t0Max, t1Min, t1Max, t2Min, t2Max: Int64;
boundary: Int64;
//p, v: Tvector3_extended;
//test: TBigInt;
begin
//WriteLn;
WriteLn(AIndex1, ' ', AIndex2, ' ', AIndex3, ' ');
t0Min := FHailstones[AIndex1].GetParameterMinimum(FMin, FMax);
t0Max := FHailstones[AIndex1].GetParameterMaximum(FMin, FMax);
WriteLn('t0 bounds: ', t0Min, ' ', t0Max);
t1Min := FHailstones[AIndex2].GetParameterMinimum(FMin, FMax);
t1Max := FHailstones[AIndex2].GetParameterMaximum(FMin, FMax);
WriteLn('t1 bounds: ', t1Min, ' ', t1Max);
t2Min := FHailstones[AIndex3].GetParameterMinimum(FMin, FMax);
t2Max := FHailstones[AIndex3].GetParameterMaximum(FMin, FMax);
WriteLn('t2 bounds: ', t2Min, ' ', t2Max);
//t0 := t0Min >> 1 + t0Max >> 1;
//WriteLn('t0: ', t0);
//t1 := t1Min >> 1 + t1Max >> 1;
//WriteLn('t1: ', t1);
//t2 := t2Min >> 1 + t2Max >> 1;
//WriteLn('t2: ', t2);
//f := TFirstCollisionPolynomial.Create;
//f.Init(FHailstones[AIndex1], FHailstones[AIndex2], FHailstones[AIndex3], T[AIndex1], T[AIndex2], T[AIndex3]);
////t0 := f.CalcPositiveIntegerRoot;
////WriteLn('t0: ', t0, ' ', t0 = T[AIndex1]);
////t1 := f.CalcT1(t0);
////WriteLn(', t1: ', t1);
//f.Free;
//// V_x = (V_0 * t_0 - V_1 * t_1 + P_0 - P_1) / (t_0 - t_1)
//v := (FHailstones[AIndex1].Velocity * t0 - FHailstones[AIndex2].Velocity * t1
// + FHailstones[AIndex1].Position - FHailstones[AIndex2].Position) / (t0 - t1);
//// P_x = (V_0 - V_x) * t_0 + P_0
//p := (FHailstones[AIndex1].Velocity - v) * t0 + FHailstones[AIndex1].Position;
//FPart2 := Round(p.data[0]) + Round(p.data[1]) + Round(p.data[2]);
//for i := 0 to FHailstones.Count - 3 do
// for j := i + 1 to FHailstones.Count - 2 do
// for k:= j + 1 to FHailstones.Count - 1 do
// begin
// WriteLn(i, j, k);
// solver := TRockThrowSolver.Create(FHailstones[i], FHailstones[j], FHailstones[k], 0);
// case i of
// 0: x0 := 5;
// 1: x0 := 3;
// 2: x0 := 4;
// end;
// f := solver.CalcValue(x0);
// solver.Free;
// end;
//for i := 80 to 120 do
//begin
// solver := TRockThrowSolver.Create(FHailstones[0], FHailstones[1], FHailstones[2], 0);
// x0 := i / 20;
// f := solver.CalcValue(x0);
// WriteLn(x0, ' ', f.Valid, ' ', f.Value);
// solver.Free;
//end;
end;
constructor TNeverTellMeTheOdds.Create(const AMin: Int64; const AMax: Int64); constructor TNeverTellMeTheOdds.Create(const AMin: Int64; const AMax: Int64);
begin begin
FMin := AMin; FMin := AMin;
FMax := AMax; FMax := AMax;
FHailStones := THailstones.Create; FHailstones := THailstones.Create;
end; end;
destructor TNeverTellMeTheOdds.Destroy; destructor TNeverTellMeTheOdds.Destroy;
begin begin
FHailStones.Free; FHailstones.Free;
inherited Destroy; inherited Destroy;
end; end;
procedure TNeverTellMeTheOdds.ProcessDataLine(const ALine: string); procedure TNeverTellMeTheOdds.ProcessDataLine(const ALine: string);
var
split: TStringArray;
hailstone: THailstone;
begin begin
split := ALine.Split([',', '@']); FHailstones.Add(THailstone.Create(ALine));
hailstone.X := StrToInt64(Trim(split[0]));
hailstone.Y := StrToInt64(Trim(split[1]));
hailstone.Z := StrToInt64(Trim(split[2]));
hailstone.VX := StrToInt(Trim(split[3]));
hailstone.VY := StrToInt(Trim(split[4]));
hailstone.VZ := StrToInt(Trim(split[5]));
FHailStones.Add(hailstone);
end; end;
procedure TNeverTellMeTheOdds.Finish; procedure TNeverTellMeTheOdds.Finish;
var var
i, j: Integer; i, j, k: Integer;
begin begin
for i := 0 to FHailStones.Count - 2 do for i := 0 to FHailstones.Count - 2 do
for j := i + 1 to FHailStones.Count - 1 do for j := i + 1 to FHailstones.Count - 1 do
if AreIntersecting(FHailStones[i], FHailStones[j]) then if AreIntersecting(FHailstones[i], FHailstones[j]) then
Inc(FPart1); Inc(FPart1);
//for i := 0 to FHailstones.Count - 1 do
// for j := 0 to FHailstones.Count - 1 do
// for k := 0 to FHailstones.Count - 1 do
// if (i <> j) and (i <> k) and (j <> k) then
// FindRockThrow(i, j, k);
FindRockThrow(0, 1, 2);
end; end;
function TNeverTellMeTheOdds.GetDataFileName: string; function TNeverTellMeTheOdds.GetDataFileName: string;

View File

@ -33,6 +33,7 @@ type
function CreateSolver: ISolver; override; function CreateSolver: ISolver; override;
published published
procedure TestPart1; procedure TestPart1;
procedure TestPart2;
end; end;
{ TNeverTellMeTheOddsExampleTestCase } { TNeverTellMeTheOddsExampleTestCase }
@ -42,6 +43,7 @@ type
function CreateSolver: ISolver; override; function CreateSolver: ISolver; override;
published published
procedure TestPart1; procedure TestPart1;
procedure TestPart2;
end; end;
{ TNeverTellMeTheOddsTestCase } { TNeverTellMeTheOddsTestCase }
@ -77,6 +79,11 @@ begin
AssertEquals(15107, FSolver.GetResultPart1); AssertEquals(15107, FSolver.GetResultPart1);
end; end;
procedure TNeverTellMeTheOddsFullDataTestCase.TestPart2;
begin
AssertEquals(-1, FSolver.GetResultPart2);
end;
{ TNeverTellMeTheOddsExampleTestCase } { TNeverTellMeTheOddsExampleTestCase }
function TNeverTellMeTheOddsExampleTestCase.CreateSolver: ISolver; function TNeverTellMeTheOddsExampleTestCase.CreateSolver: ISolver;
@ -89,6 +96,11 @@ begin
AssertEquals(2, FSolver.GetResultPart1); AssertEquals(2, FSolver.GetResultPart1);
end; end;
procedure TNeverTellMeTheOddsExampleTestCase.TestPart2;
begin
AssertEquals(47, FSolver.GetResultPart2);
end;
{ TNeverTellMeTheOddsTestCase } { TNeverTellMeTheOddsTestCase }
function TNeverTellMeTheOddsTestCase.CreateSolver: ISolver; function TNeverTellMeTheOddsTestCase.CreateSolver: ISolver;