Updated day 12 WIP performance refactor
- Added combinations calculation directly to the multi-index enumerable (TValidationPositionOffsets) and added new intermediate derived class TAccumulatedCombinationsMultiIndexStrategy to make this reusable for the other enumerables - Removed TBinomialCoefficientCache instances and used new global instance instead - Renamed TValidationToDamageAssignments to TDamageToValidationAssignments
This commit is contained in:
		
							parent
							
								
									3f7fb4a548
								
							
						
					
					
						commit
						ec6928679a
					
				| @ -41,6 +41,7 @@ const | |||||||
| 
 | 
 | ||||||
| type | type | ||||||
|   TIntegerList = specialize TList<Integer>; |   TIntegerList = specialize TList<Integer>; | ||||||
|  |   TInt64Array = array of Int64; | ||||||
| 
 | 
 | ||||||
| implementation | implementation | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -63,9 +63,9 @@ type | |||||||
|   end; |   end; | ||||||
|   TBlocks = specialize TObjectList<TBlock>; |   TBlocks = specialize TObjectList<TBlock>; | ||||||
| 
 | 
 | ||||||
|   { TValidationToDamageAssignments } |   { TDamageToValidationAssignments } | ||||||
| 
 | 
 | ||||||
|   TValidationToDamageAssignments = class(TEnumerableMultiIndexStrategy) |   TDamageToValidationAssignments = class(TEnumerableMultiIndexStrategy) | ||||||
|   private |   private | ||||||
|     FValidation: TIntegerList; |     FValidation: TIntegerList; | ||||||
|     FValidationLengths: TValidationLengths; |     FValidationLengths: TValidationLengths; | ||||||
| @ -92,14 +92,34 @@ type | |||||||
| 
 | 
 | ||||||
|   TValidationPositionInfos = specialize TList<TValidationPositionInfo>; |   TValidationPositionInfos = specialize TList<TValidationPositionInfo>; | ||||||
| 
 | 
 | ||||||
|  |   TConditionRecord = class; | ||||||
|  | 
 | ||||||
|  |   { TAccumulatedCombinationsMultiIndexStrategy } | ||||||
|  | 
 | ||||||
|  |   TAccumulatedCombinationsMultiIndexStrategy = class(TEnumerableMultiIndexStrategy) | ||||||
|  |   private | ||||||
|  |     FAccumulatedCombinations: TInt64Array; | ||||||
|  |   protected | ||||||
|  |     function CalcCombinations(constref ACurrentIndexArray: TIndexArray; const ACurrentIndex: Integer): Int64; virtual; | ||||||
|  |       abstract; | ||||||
|  |     function UpdateCombinations(const AValidationResult: TIndexValidationResult; constref ACurrentIndexArray: | ||||||
|  |       TIndexArray; const ACurrentIndex: Integer): TIndexValidationResult; | ||||||
|  |   public | ||||||
|  |     function GetCombinations: Int64; | ||||||
|  |   end; | ||||||
|  | 
 | ||||||
|   { TValidationPositionOffsets } |   { TValidationPositionOffsets } | ||||||
| 
 | 
 | ||||||
|   TValidationPositionOffsets = class(TEnumerableMultiIndexStrategy) |   TValidationPositionOffsets = class(TAccumulatedCombinationsMultiIndexStrategy) | ||||||
|   private |   private | ||||||
|     FValidation: TIntegerList; |     FConditionRecord: TConditionRecord; | ||||||
|     FPositionInfos: TValidationPositionInfos; |     FPositionInfos: TValidationPositionInfos; | ||||||
|  |     FBlockLength, FStartIndex, FStopIndex: Integer; | ||||||
|  |   protected | ||||||
|  |     function CalcCombinations(constref ACurrentIndexArray: TIndexArray; const ACurrentIndex: Integer): Int64; override; | ||||||
|   public |   public | ||||||
|     constructor Create(constref AValidation: TIntegerList; constref APositionInfos: TValidationPositionInfos); |     constructor Create(constref AConditionRecord: TConditionRecord; constref APositionInfos: TValidationPositionInfos; | ||||||
|  |       const ABlockLength, AStartIndex, AStopIndex: Integer); | ||||||
|     function GetCardinality: Integer; override; |     function GetCardinality: Integer; override; | ||||||
|     function TryGetStartIndexValue(constref ACurrentIndexArray: TIndexArray; const ACurrentIndex: Integer; |     function TryGetStartIndexValue(constref ACurrentIndexArray: TIndexArray; const ACurrentIndex: Integer; | ||||||
|       out AStartIndexValue: Integer): Boolean; override; |       out AStartIndexValue: Integer): Boolean; override; | ||||||
| @ -111,7 +131,6 @@ type | |||||||
| 
 | 
 | ||||||
|   TConditionRecord = class |   TConditionRecord = class | ||||||
|   private |   private | ||||||
|     FBinomialCoefficients: TBinomialCoefficientCache; |  | ||||||
|     FValidation: TIntegerList; |     FValidation: TIntegerList; | ||||||
|     // List of non-empty, maximum-length parts of the pattern without operational springs ("blocks"). |     // List of non-empty, maximum-length parts of the pattern without operational springs ("blocks"). | ||||||
|     FBlocks: TBlocks; |     FBlocks: TBlocks; | ||||||
| @ -129,17 +148,13 @@ type | |||||||
|     function CalcCombinationsBlockSingleValidation(constref ABlock: TBlock; const AIndex: Integer): Int64; |     function CalcCombinationsBlockSingleValidation(constref ABlock: TBlock; const AIndex: Integer): Int64; | ||||||
|     function CalcCombinationsBlockMultiValidations(constref ABlock: TBlock; constref AIndices: TIndexArray; |     function CalcCombinationsBlockMultiValidations(constref ABlock: TBlock; constref AIndices: TIndexArray; | ||||||
|       const AStartIndex, AStopIndex: Integer): Int64; |       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; |  | ||||||
|   public |   public | ||||||
|     constructor Create(constref ABinomialCoefficients: TBinomialCoefficientCache); |     constructor Create; | ||||||
|     destructor Destroy; override; |     destructor Destroy; override; | ||||||
|     // Adds all non-empty, maximum-length parts of the pattern without operational springs ("blocks"). |     // Adds all non-empty, maximum-length parts of the pattern without operational springs ("blocks"). | ||||||
|     procedure AddBlocks(const APattern: string); |     procedure AddBlocks(const APattern: string); | ||||||
|     function GenerateBlockAssignments: Int64; |     function GenerateBlockAssignments: Int64; | ||||||
|     // TODO: Blocks is not needed? |     function CalcCombinationsWildcardSequence(const ASequenceLength, AStartIndex, AStopIndex: Integer): Int64; | ||||||
|     //property Blocks: TBlocks read FBlocks; |  | ||||||
|     property Validation: TIntegerList read FValidation; |     property Validation: TIntegerList read FValidation; | ||||||
|   end; |   end; | ||||||
| 
 | 
 | ||||||
| @ -147,8 +162,6 @@ type | |||||||
| 
 | 
 | ||||||
|   THotSprings = class(TSolver) |   THotSprings = class(TSolver) | ||||||
|   private |   private | ||||||
|     // Keeping the binomial coefficients calculator here so it can be shared for all lines. |  | ||||||
|     FBinomialCoefficients: TBinomialCoefficientCache; |  | ||||||
|     // TODO: Remove FDebugIndex. |     // TODO: Remove FDebugIndex. | ||||||
|     FDebugIndex: Integer; |     FDebugIndex: Integer; | ||||||
|   public |   public | ||||||
| @ -206,9 +219,9 @@ begin | |||||||
|   inherited Destroy; |   inherited Destroy; | ||||||
| end; | end; | ||||||
| 
 | 
 | ||||||
| { TValidationToDamageAssignments } | { TDamageToValidationAssignments } | ||||||
| 
 | 
 | ||||||
| function TValidationToDamageAssignments.CalcValidationSpan(constref ACurrentIndexArray: TIndexArray; | function TDamageToValidationAssignments.CalcValidationSpan(constref ACurrentIndexArray: TIndexArray; | ||||||
|   const ALastDamageIndex, AValidationNumber: Integer): Integer; |   const ALastDamageIndex, AValidationNumber: Integer): Integer; | ||||||
| var | var | ||||||
|   spanStart: Integer; |   spanStart: Integer; | ||||||
| @ -221,7 +234,7 @@ begin | |||||||
|     Inc(Result, FDamages[ALastDamageIndex].Start - FDamages[spanStart].Start); |     Inc(Result, FDamages[ALastDamageIndex].Start - FDamages[spanStart].Start); | ||||||
| end; | end; | ||||||
| 
 | 
 | ||||||
| constructor TValidationToDamageAssignments.Create(constref AValidation: TIntegerList; constref AValidationLengths: | constructor TDamageToValidationAssignments.Create(constref AValidation: TIntegerList; constref AValidationLengths: | ||||||
|   TValidationLengths; constref ADamages: TDamages; const AStartIndex, AStopIndex: Integer); |   TValidationLengths; constref ADamages: TDamages; const AStartIndex, AStopIndex: Integer); | ||||||
| begin | begin | ||||||
|   FValidation := AValidation; |   FValidation := AValidation; | ||||||
| @ -231,12 +244,12 @@ begin | |||||||
|   FValidationStopIndex := AStopIndex; |   FValidationStopIndex := AStopIndex; | ||||||
| end; | end; | ||||||
| 
 | 
 | ||||||
| function TValidationToDamageAssignments.GetCardinality: Integer; | function TDamageToValidationAssignments.GetCardinality: Integer; | ||||||
| begin | begin | ||||||
|   Result := FDamages.Count; |   Result := FDamages.Count; | ||||||
| end; | end; | ||||||
| 
 | 
 | ||||||
| function TValidationToDamageAssignments.TryGetStartIndexValue(constref ACurrentIndexArray: TIndexArray; | function TDamageToValidationAssignments.TryGetStartIndexValue(constref ACurrentIndexArray: TIndexArray; | ||||||
|   const ACurrentIndex: Integer; out AStartIndexValue: Integer): Boolean; |   const ACurrentIndex: Integer; out AStartIndexValue: Integer): Boolean; | ||||||
| begin | begin | ||||||
|   Result := True; |   Result := True; | ||||||
| @ -246,7 +259,7 @@ begin | |||||||
|     AStartIndexValue := FValidationStartIndex; |     AStartIndexValue := FValidationStartIndex; | ||||||
| end; | end; | ||||||
| 
 | 
 | ||||||
| function TValidationToDamageAssignments.ValidateIndexValue(constref ACurrentIndexArray: TIndexArray; | function TDamageToValidationAssignments.ValidateIndexValue(constref ACurrentIndexArray: TIndexArray; | ||||||
|   const ACurrentIndex: Integer): TIndexValidationResult; |   const ACurrentIndex: Integer): TIndexValidationResult; | ||||||
| var | var | ||||||
|   i, prev, firstSkip: Integer; |   i, prev, firstSkip: Integer; | ||||||
| @ -296,13 +309,71 @@ begin | |||||||
|   Result := ivrValid; |   Result := ivrValid; | ||||||
| end; | end; | ||||||
| 
 | 
 | ||||||
|  | { TAccumulatedCombinationsMultiIndexStrategy } | ||||||
|  | 
 | ||||||
|  | function TAccumulatedCombinationsMultiIndexStrategy.UpdateCombinations(const AValidationResult: TIndexValidationResult; | ||||||
|  |   constref ACurrentIndexArray: TIndexArray; const ACurrentIndex: Integer): TIndexValidationResult; | ||||||
|  | var | ||||||
|  |   combinations: Int64; | ||||||
|  | begin | ||||||
|  |   Result := AValidationResult; | ||||||
|  |   if Result = ivrValid then | ||||||
|  |   begin | ||||||
|  |     combinations := CalcCombinations(ACurrentIndexArray, ACurrentIndex); | ||||||
|  |     if combinations = 0 then | ||||||
|  |       Result := ivrBacktrack | ||||||
|  |     else if ACurrentIndex > 0 then | ||||||
|  |       FAccumulatedCombinations[ACurrentIndex] := combinations * FAccumulatedCombinations[ACurrentIndex - 1] | ||||||
|  |     else begin | ||||||
|  |       SetLength(FAccumulatedCombinations, GetCardinality); | ||||||
|  |       FAccumulatedCombinations[ACurrentIndex] := combinations; | ||||||
|  |     end; | ||||||
|  |   end; | ||||||
|  | end; | ||||||
|  | 
 | ||||||
|  | function TAccumulatedCombinationsMultiIndexStrategy.GetCombinations: Int64; | ||||||
|  | begin | ||||||
|  |   Result := FAccumulatedCombinations[GetCardinality - 1]; | ||||||
|  | end; | ||||||
|  | 
 | ||||||
| { TValidationPositionOffsets } | { TValidationPositionOffsets } | ||||||
| 
 | 
 | ||||||
| constructor TValidationPositionOffsets.Create(constref AValidation: TIntegerList; constref APositionInfos: | function TValidationPositionOffsets.CalcCombinations(constref ACurrentIndexArray: TIndexArray; const ACurrentIndex: | ||||||
|   TValidationPositionInfos); |   Integer): Int64; | ||||||
|  | var | ||||||
|  |   space, start, stop: Integer; | ||||||
| begin | begin | ||||||
|   FValidation := AValidation; |   stop := FPositionInfos[ACurrentIndex].ValidationIndex - 1; | ||||||
|  |   if ACurrentIndex > 0 then | ||||||
|  |   begin | ||||||
|  |     space := ACurrentIndexArray[ACurrentIndex] - ACurrentIndexArray[ACurrentIndex - 1] | ||||||
|  |       - FConditionRecord.Validation[FPositionInfos[ACurrentIndex - 1].ValidationIndex] - 2; | ||||||
|  |     start := FPositionInfos[ACurrentIndex - 1].ValidationIndex + 1; | ||||||
|  |     Result :=  FConditionRecord.CalcCombinationsWildcardSequence(space, start, stop); | ||||||
|  |   end | ||||||
|  |   else begin | ||||||
|  |     // Handles first calculated offset. | ||||||
|  |     space := ACurrentIndexArray[0] - 2; | ||||||
|  |     Result := FConditionRecord.CalcCombinationsWildcardSequence(space, FStartIndex, stop); | ||||||
|  |   end; | ||||||
|  | 
 | ||||||
|  |   if (Result > 0) and (ACurrentIndex + 1 = GetCardinality) then | ||||||
|  |   begin | ||||||
|  |     // Handles last calculated offset. | ||||||
|  |     space := FBlockLength - ACurrentIndexArray[ACurrentIndex] - FConditionRecord.Validation[FPositionInfos.Last.ValidationIndex]; | ||||||
|  |     Result := Result * FConditionRecord.CalcCombinationsWildcardSequence(space, FPositionInfos.Last.ValidationIndex + 1, FStopIndex); | ||||||
|  |   end; | ||||||
|  | end; | ||||||
|  | 
 | ||||||
|  | constructor TValidationPositionOffsets.Create(constref AConditionRecord: TConditionRecord; constref APositionInfos: | ||||||
|  |   TValidationPositionInfos; const ABlockLength, AStartIndex, AStopIndex: Integer); | ||||||
|  | begin | ||||||
|  |   FConditionRecord := AConditionRecord; | ||||||
|   FPositionInfos := APositionInfos; |   FPositionInfos := APositionInfos; | ||||||
|  |   FBlockLength := ABlockLength; | ||||||
|  |   FStartIndex := AStartIndex; | ||||||
|  |   FStopIndex := AStopIndex; | ||||||
|  |   inherited Create; | ||||||
| end; | end; | ||||||
| 
 | 
 | ||||||
| function TValidationPositionOffsets.GetCardinality: Integer; | function TValidationPositionOffsets.GetCardinality: Integer; | ||||||
| @ -317,13 +388,12 @@ var | |||||||
| begin | begin | ||||||
|   info := FPositionInfos[ACurrentIndex]; |   info := FPositionInfos[ACurrentIndex]; | ||||||
|   // Calculates start value such that the validation number just includes MinEnd. |   // Calculates start value such that the validation number just includes MinEnd. | ||||||
|   //AStartIndexValue := info.MinEnd - FValidation[info.ValidationIndex] + 1; |  | ||||||
|   AStartIndexValue := info.MinStart; |   AStartIndexValue := info.MinStart; | ||||||
|   // Adjusts start value to avoid overlap of this validation number with the previous one (the one from previous |   // Adjusts start value to avoid overlap of this validation number with the previous one (the one from previous | ||||||
|   // position info). |   // position info). | ||||||
|   if ACurrentIndex > 0 then |   if ACurrentIndex > 0 then | ||||||
|     AStartIndexValue := Max(AStartIndexValue, |     AStartIndexValue := Max(AStartIndexValue, | ||||||
|       ACurrentIndexArray[ACurrentIndex - 1] + FValidation[FPositionInfos[ACurrentIndex - 1].ValidationIndex] + 1); |       ACurrentIndexArray[ACurrentIndex - 1] + FConditionRecord.Validation[FPositionInfos[ACurrentIndex - 1].ValidationIndex] + 1); | ||||||
|   Result := True; |   Result := True; | ||||||
| end; | end; | ||||||
| 
 | 
 | ||||||
| @ -334,6 +404,8 @@ begin | |||||||
|     Result := ivrValid |     Result := ivrValid | ||||||
|   else |   else | ||||||
|     Result := ivrBacktrack; |     Result := ivrBacktrack; | ||||||
|  | 
 | ||||||
|  |   Result := UpdateCombinations(Result, ACurrentIndexArray, ACurrentIndex); | ||||||
| end; | end; | ||||||
| 
 | 
 | ||||||
| { TConditionRecord } | { TConditionRecord } | ||||||
| @ -413,7 +485,7 @@ function TConditionRecord.CalcCombinationsBlock(constref ABlock: TBlock; const A | |||||||
| var | var | ||||||
|   i, j, k: Integer; |   i, j, k: Integer; | ||||||
|   indices: TIndexArray; |   indices: TIndexArray; | ||||||
|   validationToDamageAssignments: TValidationToDamageAssignments; |   validationToDamageAssignments: TDamageToValidationAssignments; | ||||||
| begin | begin | ||||||
|   {$ifdef debug} |   {$ifdef debug} | ||||||
|   Write('    ', ABlock.Pattern, ' '); |   Write('    ', ABlock.Pattern, ' '); | ||||||
| @ -464,7 +536,7 @@ begin | |||||||
|     Result := 0; |     Result := 0; | ||||||
| 
 | 
 | ||||||
|     // Assigns validation numbers to specific damages. |     // Assigns validation numbers to specific damages. | ||||||
|     validationToDamageAssignments := TValidationToDamageAssignments.Create(FValidation, FValidationLengths, ABlock.Damages, |     validationToDamageAssignments := TDamageToValidationAssignments.Create(FValidation, FValidationLengths, ABlock.Damages, | ||||||
|       AStartIndex, AStopIndex); |       AStartIndex, AStopIndex); | ||||||
|     {$ifdef debug} |     {$ifdef debug} | ||||||
|     WriteLn('        validation numbers (indices) per damages:'); |     WriteLn('        validation numbers (indices) per damages:'); | ||||||
| @ -551,82 +623,17 @@ begin | |||||||
|   WriteLn('                    offsets'); |   WriteLn('                    offsets'); | ||||||
|   {$endif} |   {$endif} | ||||||
|   Result := 0; |   Result := 0; | ||||||
|   validationPositionOffsets := TValidationPositionOffsets.Create(FValidation, positions); |   validationPositionOffsets := TValidationPositionOffsets.Create(Self, positions, Length(ABlock.Pattern), | ||||||
|  |     AStartIndex, AStopIndex); | ||||||
|   for offsets in validationPositionOffsets do |   for offsets in validationPositionOffsets do | ||||||
|     Result := Result |     Result := Result + validationPositionOffsets.GetCombinations; | ||||||
|       + CalcCombinationsBlockAssignedValidations(Length(ABlock.Pattern), positions, offsets, AStartIndex, AStopIndex); |  | ||||||
|   validationPositionOffsets.Free; |   validationPositionOffsets.Free; | ||||||
| 
 | 
 | ||||||
|   positions.Free; |   positions.Free; | ||||||
| end; | end; | ||||||
| 
 | 
 | ||||||
| function TConditionRecord.CalcCombinationsBlockAssignedValidations(const ABlockLength: Integer; constref APositionInfos: | constructor TConditionRecord.Create; | ||||||
|   TValidationPositionInfos; constref AOffsets: TIndexArray; const AStartIndex, AStopIndex: Integer): Int64; |  | ||||||
| var |  | ||||||
|   i, space: Integer; |  | ||||||
| begin | begin | ||||||
|   {$ifdef debug} |  | ||||||
|   Write('                      '); |  | ||||||
|   for i in AOffsets do |  | ||||||
|     Write(i, ' '); |  | ||||||
| 
 |  | ||||||
|   Write('    count/space/freedoms: '); |  | ||||||
|   {$endif} |  | ||||||
|   space := AOffsets[0] - 2; |  | ||||||
|   Result := CalcCombinationsWildcardSequence(space, AStartIndex, APositionInfos[0].ValidationIndex - 1); |  | ||||||
|   if Result = 0 then begin |  | ||||||
|     {$ifdef debug} |  | ||||||
|     WriteLn('    result: ', Result); |  | ||||||
|     {$endif} |  | ||||||
|     Exit; |  | ||||||
|   end; |  | ||||||
| 
 |  | ||||||
|   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 - 1); |  | ||||||
|     if Result = 0 then begin |  | ||||||
|       {$ifdef debug} |  | ||||||
|       WriteLn('    result: ', Result); |  | ||||||
|       {$endif} |  | ||||||
|       Exit; |  | ||||||
|     end; |  | ||||||
|   end; |  | ||||||
|   space := ABlockLength - AOffsets[APositionInfos.Count - 1] - FValidation[APositionInfos.Last.ValidationIndex]; |  | ||||||
|   Result := Result * CalcCombinationsWildcardSequence(space, APositionInfos.Last.ValidationIndex + 1, AStopIndex); |  | ||||||
|   {$ifdef debug} |  | ||||||
|   WriteLn('    result: ', Result); |  | ||||||
|   {$endif} |  | ||||||
| end; |  | ||||||
| 
 |  | ||||||
| function TConditionRecord.CalcCombinationsWildcardSequence(const ASequenceLength, AStartIndex, AStopIndex: Integer): |  | ||||||
|   Int64; |  | ||||||
| var |  | ||||||
|   count, freedoms: Integer; |  | ||||||
| begin |  | ||||||
|   if AStartIndex < AStopIndex + 1 then |  | ||||||
|   begin |  | ||||||
|     count := AStopIndex + 1 - AStartIndex; |  | ||||||
|     freedoms := ASequenceLength - FValidationLengths[AStartIndex, AStopIndex + 1]; |  | ||||||
|     {$ifdef debug} |  | ||||||
|     Write(count, '/', ASequenceLength, '/', freedoms, ' '); |  | ||||||
|     {$endif} |  | ||||||
|     if freedoms >= 0 then |  | ||||||
|       Result := FBinomialCoefficients.Get(count + freedoms, freedoms) |  | ||||||
|     else |  | ||||||
|       Result := 0; |  | ||||||
|   end |  | ||||||
|   else begin |  | ||||||
|     Result := 1; |  | ||||||
|     {$ifdef debug} |  | ||||||
|     Write('X '); |  | ||||||
|     {$endif} |  | ||||||
|   end; |  | ||||||
| end; |  | ||||||
| 
 |  | ||||||
| constructor TConditionRecord.Create(constref ABinomialCoefficients: TBinomialCoefficientCache); |  | ||||||
| begin |  | ||||||
|   FBinomialCoefficients := ABinomialCoefficients; |  | ||||||
| 
 |  | ||||||
|   FBlocks := TBlocks.Create; |   FBlocks := TBlocks.Create; | ||||||
|   FValidation := TIntegerList.Create; |   FValidation := TIntegerList.Create; | ||||||
| end; | end; | ||||||
| @ -710,17 +717,40 @@ begin | |||||||
|   WriteLn('    missed: ', misses, '/', count); |   WriteLn('    missed: ', misses, '/', count); | ||||||
| end; | end; | ||||||
| 
 | 
 | ||||||
|  | function TConditionRecord.CalcCombinationsWildcardSequence(const ASequenceLength, AStartIndex, AStopIndex: Integer): | ||||||
|  |   Int64; | ||||||
|  | var | ||||||
|  |   count, freedoms: Integer; | ||||||
|  | begin | ||||||
|  |   if AStartIndex < AStopIndex + 1 then | ||||||
|  |   begin | ||||||
|  |     count := AStopIndex + 1 - AStartIndex; | ||||||
|  |     freedoms := ASequenceLength - FValidationLengths[AStartIndex, AStopIndex + 1]; | ||||||
|  |     {$ifdef debug} | ||||||
|  |     Write(count, '/', ASequenceLength, '/', freedoms, ' '); | ||||||
|  |     {$endif} | ||||||
|  |     if freedoms >= 0 then | ||||||
|  |       Result := BinomialCoefficients.Get(count + freedoms, freedoms) | ||||||
|  |     else | ||||||
|  |       Result := 0; | ||||||
|  |   end | ||||||
|  |   else begin | ||||||
|  |     Result := 1; | ||||||
|  |     {$ifdef debug} | ||||||
|  |     Write('X '); | ||||||
|  |     {$endif} | ||||||
|  |   end; | ||||||
|  | end; | ||||||
|  | 
 | ||||||
| { THotSprings } | { THotSprings } | ||||||
| 
 | 
 | ||||||
| constructor THotSprings.Create; | constructor THotSprings.Create; | ||||||
| begin | begin | ||||||
|   FDebugIndex := 0; |   FDebugIndex := 0; | ||||||
|   FBinomialCoefficients := TBinomialCoefficientCache.Create; |  | ||||||
| end; | end; | ||||||
| 
 | 
 | ||||||
| destructor THotSprings.Destroy; | destructor THotSprings.Destroy; | ||||||
| begin | begin | ||||||
|   FBinomialCoefficients.Free; |  | ||||||
|   inherited Destroy; |   inherited Destroy; | ||||||
| end; | end; | ||||||
| 
 | 
 | ||||||
| @ -736,8 +766,8 @@ begin | |||||||
|   WriteLn; |   WriteLn; | ||||||
|   {$endif} |   {$endif} | ||||||
| 
 | 
 | ||||||
|   conditionRecord1 := TConditionRecord.Create(FBinomialCoefficients); |   conditionRecord1 := TConditionRecord.Create; | ||||||
|   conditionRecord2 := TConditionRecord.Create(FBinomialCoefficients); |   conditionRecord2 := TConditionRecord.Create; | ||||||
| 
 | 
 | ||||||
|   mainSplit := ALine.Split([' ']); |   mainSplit := ALine.Split([' ']); | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user