diff --git a/solvers/UHotSprings.pas b/solvers/UHotSprings.pas index 8f12cab..3244dd6 100644 --- a/solvers/UHotSprings.pas +++ b/solvers/UHotSprings.pas @@ -30,6 +30,7 @@ const CWildcardChar = '?'; COperationalPatternChars = [COperationalChar, CWildcardChar]; CDamagedPatternChars = [CDamagedChar, CWildcardChar]; + CPart2Repetition = 4; type @@ -40,7 +41,7 @@ type FValidation: specialize TList; FSpringPattern: string; procedure ExtendArrangement(const AArrangement: string; const ARemainingFreeOperationalCount, ACurrentValidationIndex: - Integer); + Integer; var AArrangementCount: Int64); function TryAppendOperationalChar(var AArrangement: string): Boolean; function TryAppendValidationBlock(var AArrangement: string; const ALength: Integer): Boolean; public @@ -57,19 +58,19 @@ implementation { THotSprings } procedure THotSprings.ExtendArrangement(const AArrangement: string; const ARemainingFreeOperationalCount, - ACurrentValidationIndex: Integer); + ACurrentValidationIndex: Integer; var AArrangementCount: Int64); var match: Boolean; temp: string; begin if Length(AArrangement) = Length(FSpringPattern) then - Inc(FPart1) + Inc(AArrangementCount) else begin temp := AArrangement; // Tries to append a dot (operational) to the current arrangement. if (ARemainingFreeOperationalCount > 0) and TryAppendOperationalChar(temp) then begin - ExtendArrangement(temp, ARemainingFreeOperationalCount - 1, ACurrentValidationIndex); + ExtendArrangement(temp, ARemainingFreeOperationalCount - 1, ACurrentValidationIndex, AArrangementCount); end; // Tries to append the current validation block (damaged) to the current arrangement. @@ -85,7 +86,7 @@ begin match := False; if match then - ExtendArrangement(temp, ARemainingFreeOperationalCount, ACurrentValidationIndex + 1); + ExtendArrangement(temp, ARemainingFreeOperationalCount, ACurrentValidationIndex + 1, AArrangementCount); end; end; end; @@ -132,7 +133,7 @@ end; procedure THotSprings.ProcessDataLine(const ALine: string); var split: TStringArray; - i, val, maxFreeOperationalCount: Integer; + i, j, val, maxFreeOperationalCount: Integer; begin FValidation.Clear; split := ALine.Split([' ', ',']); @@ -146,7 +147,19 @@ begin Dec(maxFreeOperationalCount, val); end; - ExtendArrangement('', maxFreeOperationalCount, 0); + ExtendArrangement('', maxFreeOperationalCount, 0, FPart1); + WriteLn('Part 1: ', FPart1); + + for i := 1 to CPart2Repetition do + begin + FSpringPattern := FSpringPattern + CWildcardChar + split[0]; + for j := 0 to Length(split) - 2 do + FValidation.Add(FValidation[j]); + end; + maxFreeOperationalCount := (CPart2Repetition + 1) * maxFreeOperationalCount; + + ExtendArrangement('', maxFreeOperationalCount, 0, FPart2); + WriteLn('Part 2: ', FPart2); end; procedure THotSprings.Finish; diff --git a/tests/UHotSpringsTestCases.pas b/tests/UHotSpringsTestCases.pas index 03f9a92..6819d82 100644 --- a/tests/UHotSpringsTestCases.pas +++ b/tests/UHotSpringsTestCases.pas @@ -26,6 +26,16 @@ uses type + { THotSpringsFullDataTestCase } + + THotSpringsFullDataTestCase = class(TEngineBaseTest) + protected + function CreateSolver: ISolver; override; + published + procedure TestPart1; + procedure TestPart2; + end; + { THotSpringsExampleTestCase } THotSpringsExampleTestCase = class(TExampleEngineBaseTest) @@ -33,6 +43,7 @@ type function CreateSolver: ISolver; override; published procedure TestPart1; + procedure TestPart2; end; { THotSpringsTestCase } @@ -40,18 +51,29 @@ type THotSpringsTestCase = class(TSolverTestCase) protected function CreateSolver: ISolver; override; - procedure TestSingleLine(const ALine: string; const AValue: Integer); + procedure TestSingleLine(const ALine: string); published - procedure TestExampleLine1; - procedure TestExampleLine2; - procedure TestExampleLine3; - procedure TestExampleLine4; - procedure TestExampleLine5; - procedure TestExampleLine6; + procedure TestExampleLine1Part1; + procedure TestExampleLine2Part1; + procedure TestExampleLine3Part1; + procedure TestExampleLine4Part1; + procedure TestExampleLine5Part1; + procedure TestExampleLine6Part1; + procedure TestExampleLine1Part2; + procedure TestExampleLine2Part2; + procedure TestExampleLine3Part2; + procedure TestExampleLine4Part2; + procedure TestExampleLine5Part2; + procedure TestExampleLine6Part2; end; implementation +procedure THotSpringsFullDataTestCase.TestPart2; +begin + AssertEquals(-1, FSolver.GetResultPart2); +end; + { THotSpringsExampleTestCase } function THotSpringsExampleTestCase.CreateSolver: ISolver; @@ -64,6 +86,11 @@ begin AssertEquals(21, FSolver.GetResultPart1); end; +procedure THotSpringsExampleTestCase.TestPart2; +begin + AssertEquals(525152, FSolver.GetResultPart2); +end; + { THotSpringsTestCase } function THotSpringsTestCase.CreateSolver: ISolver; @@ -71,42 +98,83 @@ begin Result := THotSprings.Create; end; -procedure THotSpringsTestCase.TestSingleLine(const ALine: string; const AValue: Integer); +procedure THotSpringsTestCase.TestSingleLine(const ALine: string); begin FSolver.Init; FSolver.ProcessDataLine(ALine); FSolver.Finish; - AssertEquals(AValue, FSolver.GetResultPart1); end; -procedure THotSpringsTestCase.TestExampleLine1; +procedure THotSpringsTestCase.TestExampleLine1Part1; begin - TestSingleLine('???.### 1,1,3', 1); + TestSingleLine('???.### 1,1,3'); + AssertEquals(1, FSolver.GetResultPart1); end; -procedure THotSpringsTestCase.TestExampleLine2; +procedure THotSpringsTestCase.TestExampleLine2Part1; begin - TestSingleLine('.??..??...?##. 1,1,3', 4); + TestSingleLine('.??..??...?##. 1,1,3'); + AssertEquals(4, FSolver.GetResultPart1); end; -procedure THotSpringsTestCase.TestExampleLine3; +procedure THotSpringsTestCase.TestExampleLine3Part1; begin - TestSingleLine('?#?#?#?#?#?#?#? 1,3,1,6', 1); + TestSingleLine('?#?#?#?#?#?#?#? 1,3,1,6'); + AssertEquals(1, FSolver.GetResultPart1); end; -procedure THotSpringsTestCase.TestExampleLine4; +procedure THotSpringsTestCase.TestExampleLine4Part1; begin - TestSingleLine('????.#...#... 4,1,1', 1); + TestSingleLine('????.#...#... 4,1,1'); + AssertEquals(1, FSolver.GetResultPart1); end; -procedure THotSpringsTestCase.TestExampleLine5; +procedure THotSpringsTestCase.TestExampleLine5Part1; begin - TestSingleLine('????.######..#####. 1,6,5', 4); + TestSingleLine('????.######..#####. 1,6,5'); + AssertEquals(4, FSolver.GetResultPart1); end; -procedure THotSpringsTestCase.TestExampleLine6; +procedure THotSpringsTestCase.TestExampleLine6Part1; begin - TestSingleLine('?###???????? 3,2,1', 10); + TestSingleLine('?###???????? 3,2,1'); + AssertEquals(10, FSolver.GetResultPart1); +end; + +procedure THotSpringsTestCase.TestExampleLine1Part2; +begin + TestSingleLine('???.### 1,1,3'); + AssertEquals(1, FSolver.GetResultPart2); +end; + +procedure THotSpringsTestCase.TestExampleLine2Part2; +begin + TestSingleLine('.??..??...?##. 1,1,3'); + AssertEquals(16384, FSolver.GetResultPart2); +end; + +procedure THotSpringsTestCase.TestExampleLine3Part2; +begin + TestSingleLine('?#?#?#?#?#?#?#? 1,3,1,6'); + AssertEquals(1, FSolver.GetResultPart2); +end; + +procedure THotSpringsTestCase.TestExampleLine4Part2; +begin + TestSingleLine('????.#...#... 4,1,1'); + AssertEquals(16, FSolver.GetResultPart2); +end; + +procedure THotSpringsTestCase.TestExampleLine5Part2; +begin + TestSingleLine('????.######..#####. 1,6,5'); + AssertEquals(2500, FSolver.GetResultPart2); +end; + +procedure THotSpringsTestCase.TestExampleLine6Part2; +begin + TestSingleLine('?###???????? 3,2,1'); + AssertEquals(506250, FSolver.GetResultPart2); end; initialization