Updated day 12 WIP solver
This commit is contained in:
parent
21ef4c08f1
commit
60ef49c1ee
|
@ -22,7 +22,7 @@ unit UHotSprings;
|
|||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, Math, Generics.Collections, USolver, UCommon, UMultiIndexEnumerator;
|
||||
Classes, SysUtils, Math, Generics.Collections, USolver, UCommon, UMultiIndexEnumerator, UBinomialCoefficients;
|
||||
|
||||
const
|
||||
COperationalChar = '.';
|
||||
|
@ -114,6 +114,7 @@ type
|
|||
|
||||
TConditionRecord = class
|
||||
private
|
||||
FBinomialCoefficients: TBinomialCoefficientCache;
|
||||
FValidation: TIntegerList;
|
||||
// List of non-empty, maximum-length parts of the pattern without operational springs ("blocks").
|
||||
FBlocks: TStringList;
|
||||
|
@ -150,11 +151,12 @@ type
|
|||
constref AIndices: TIndexArray; const AStartIndex, AStopIndex: Integer): Int64;
|
||||
function CalcCombinationsBlockAssignedValidations(const ABlockLength: Integer; constref APositionInfos:
|
||||
TValidationPositionInfos; constref AOffsets: TIndexArray; const AStartIndex, AStopIndex: Integer): Int64;
|
||||
function CalcCombinationsWildcardSequence(const ASequenceLength, AStartIndex, AStopIndex: Integer): Int64;
|
||||
function ParseDamages(const ABlock: string): TDamages;
|
||||
public
|
||||
property Blocks: TStringList read FBlocks;
|
||||
property Validation: TIntegerList read FValidation;
|
||||
constructor Create;
|
||||
constructor Create(constref ABinomialCoefficients: TBinomialCoefficientCache);
|
||||
destructor Destroy; override;
|
||||
// Adds all non-empty, maximum-length parts of the pattern without operational springs ("blocks").
|
||||
procedure AddBlocks(const APattern: string);
|
||||
|
@ -164,7 +166,12 @@ type
|
|||
{ THotSprings }
|
||||
|
||||
THotSprings = class(TSolver)
|
||||
private
|
||||
// Keeping the binomial coefficients calculator here so it can be shared for all lines.
|
||||
FBinomialCoefficients: TBinomialCoefficientCache;
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
procedure ProcessDataLine(const ALine: string); override;
|
||||
procedure Finish; override;
|
||||
function GetDataFileName: string; override;
|
||||
|
@ -442,7 +449,7 @@ begin
|
|||
end;
|
||||
///////////////////////////////
|
||||
|
||||
Result := 9999;
|
||||
Result := 0;
|
||||
|
||||
// Assigns validation numbers to specific damages.
|
||||
validationToDamageAssignments := TValidationToDamageAssignments.Create(FValidation, FValidationLengths, ADamages,
|
||||
|
@ -457,7 +464,7 @@ begin
|
|||
for i := 0 to ADamages.Count - 1 do
|
||||
Write(indices[i] - AStartIndex, ' ');
|
||||
WriteLn(')');
|
||||
CalcCombinationsBlockMultiValidations(Length(ABlock), ADamages, indices, AStartIndex, AStopIndex);
|
||||
Result := Result + CalcCombinationsBlockMultiValidations(Length(ABlock), ADamages, indices, AStartIndex, AStopIndex);
|
||||
end;
|
||||
validationToDamageAssignments.Free;
|
||||
end;
|
||||
|
@ -526,9 +533,10 @@ begin
|
|||
WriteLn(' ', position.ValidationIndex, ' ', position.MinStart, ' ', position.MaxStart);
|
||||
|
||||
WriteLn(' offsets');
|
||||
Result := 0;
|
||||
validationPositionOffsets := TValidationPositionOffsets.Create(FValidation, positions);
|
||||
for offsets in validationPositionOffsets do
|
||||
CalcCombinationsBlockAssignedValidations(ABlockLength, positions, offsets, AStartIndex, AStopIndex);
|
||||
Result := Result + CalcCombinationsBlockAssignedValidations(ABlockLength, positions, offsets, AStartIndex, AStopIndex);
|
||||
validationPositionOffsets.Free;
|
||||
|
||||
positions.Free;
|
||||
|
@ -537,44 +545,52 @@ end;
|
|||
function TConditionRecord.CalcCombinationsBlockAssignedValidations(const ABlockLength: Integer; constref APositionInfos:
|
||||
TValidationPositionInfos; constref AOffsets: TIndexArray; const AStartIndex, AStopIndex: Integer): Int64;
|
||||
var
|
||||
i, space, freedom, count: Integer;
|
||||
i, space: Integer;
|
||||
begin
|
||||
Write(' ');
|
||||
for i in AOffsets do
|
||||
Write(i, ' ');
|
||||
|
||||
Write(' count/space/freedom: ');
|
||||
// TODO: Number of combinations is binom(count + freedom, freedom).
|
||||
if AStartIndex < APositionInfos[0].ValidationIndex then
|
||||
begin
|
||||
count := APositionInfos[0].ValidationIndex - AStartIndex;
|
||||
space := AOffsets[0] - 2;
|
||||
freedom := space - FValidationLengths[AStartIndex, APositionInfos[0].ValidationIndex];
|
||||
Write(count, '/', space, '/', freedom, ' ');
|
||||
end
|
||||
else
|
||||
Write('X ');
|
||||
for i := 0 to APositionInfos.Count - 2 do
|
||||
if APositionInfos[i].ValidationIndex + 1 < APositionInfos[i + 1].ValidationIndex then
|
||||
begin
|
||||
count := APositionInfos[i + 1].ValidationIndex - APositionInfos[i].ValidationIndex - 1;
|
||||
space := AOffsets[i + 1] - AOffsets[i] - FValidation[APositionInfos[i].ValidationIndex] - 2;
|
||||
freedom := space - FValidationLengths[APositionInfos[i].ValidationIndex + 1, APositionInfos[i + 1].ValidationIndex];
|
||||
Write(count, '/', space, '/', freedom, ' ');
|
||||
end
|
||||
else
|
||||
Write('X ');
|
||||
if APositionInfos.Last.ValidationIndex < AStopIndex then
|
||||
begin
|
||||
count := AStopIndex - APositionInfos.Last.ValidationIndex;
|
||||
space := ABlockLength - AOffsets[APositionInfos.Count - 1] - FValidation[APositionInfos.Last.ValidationIndex];
|
||||
freedom := space - FValidationLengths[APositionInfos.Last.ValidationIndex + 1, AStopIndex + 1];
|
||||
Write(count, '/', space, '/', freedom, ' ');
|
||||
end
|
||||
else
|
||||
Write('X ');
|
||||
Write(' count/space/freedoms: ');
|
||||
space := AOffsets[0] - 2;
|
||||
Result := CalcCombinationsWildcardSequence(space, AStartIndex, APositionInfos[0].ValidationIndex);
|
||||
if Result = 0 then begin
|
||||
WriteLn(' result: ', Result);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
WriteLn;
|
||||
for i := 0 to APositionInfos.Count - 2 do begin
|
||||
space := AOffsets[i + 1] - AOffsets[i] - FValidation[APositionInfos[i].ValidationIndex] - 2;
|
||||
Result := Result * CalcCombinationsWildcardSequence(space, APositionInfos[i].ValidationIndex + 1, APositionInfos[i + 1].ValidationIndex);
|
||||
if Result = 0 then begin
|
||||
WriteLn(' result: ', Result);
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
space := ABlockLength - AOffsets[APositionInfos.Count - 1] - FValidation[APositionInfos.Last.ValidationIndex];
|
||||
Result := Result * CalcCombinationsWildcardSequence(space, APositionInfos.Last.ValidationIndex + 1, AStopIndex + 1);
|
||||
WriteLn(' result: ', Result);
|
||||
end;
|
||||
|
||||
function TConditionRecord.CalcCombinationsWildcardSequence(const ASequenceLength, AStartIndex, AStopIndex: Integer):
|
||||
Int64;
|
||||
var
|
||||
count, freedoms: Integer;
|
||||
begin
|
||||
if AStartIndex < AStopIndex then
|
||||
begin
|
||||
count := AStopIndex - AStartIndex;
|
||||
freedoms := ASequenceLength - FValidationLengths[AStartIndex, AStopIndex];
|
||||
Write(count, '/', ASequenceLength, '/', freedoms, ' ');
|
||||
if freedoms >= 0 then
|
||||
Result := FBinomialCoefficients.Get(count + freedoms, freedoms)
|
||||
else
|
||||
Result := 0;
|
||||
end
|
||||
else begin
|
||||
Result := 1;
|
||||
Write('X ');
|
||||
end;
|
||||
end;
|
||||
|
||||
function TConditionRecord.ParseDamages(const ABlock: string): TDamages;
|
||||
|
@ -607,8 +623,10 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
constructor TConditionRecord.Create;
|
||||
constructor TConditionRecord.Create(constref ABinomialCoefficients: TBinomialCoefficientCache);
|
||||
begin
|
||||
FBinomialCoefficients := ABinomialCoefficients;
|
||||
|
||||
FBlocks := TStringList.Create;
|
||||
FValidation := TIntegerList.Create;
|
||||
FDamagesBlocks := TDamagesBlocks.Create;
|
||||
|
@ -700,6 +718,17 @@ end;
|
|||
|
||||
{ THotSprings }
|
||||
|
||||
constructor THotSprings.Create;
|
||||
begin
|
||||
FBinomialCoefficients := TBinomialCoefficientCache.Create;
|
||||
end;
|
||||
|
||||
destructor THotSprings.Destroy;
|
||||
begin
|
||||
FBinomialCoefficients.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure THotSprings.ProcessDataLine(const ALine: string);
|
||||
var
|
||||
conditionRecord1, conditionRecord2: TConditionRecord;
|
||||
|
@ -710,8 +739,8 @@ begin
|
|||
WriteLn(ALine);
|
||||
WriteLn;
|
||||
|
||||
conditionRecord1 := TConditionRecord.Create;
|
||||
conditionRecord2 := TConditionRecord.Create;
|
||||
conditionRecord1 := TConditionRecord.Create(FBinomialCoefficients);
|
||||
conditionRecord2 := TConditionRecord.Create(FBinomialCoefficients);
|
||||
|
||||
mainSplit := ALine.Split([' ']);
|
||||
|
||||
|
|
Loading…
Reference in New Issue