{ Solutions to the Advent Of Code. Copyright (C) 2023 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 UCosmicExpansion; {$mode ObjFPC}{$H+} interface uses Classes, SysUtils, Generics.Collections, Math, USolver; const CGalaxyChar = '#'; CEmptySpaceFactor = 1; CNonEmptySpaceFactor = 0; type { TCosmicExpansion } TCosmicExpansion = class(TSolver) private FExpansionFactor: Integer; FColumnExpansion, FRowExpansion: specialize TList; FGalaxies: specialize TList; procedure InitColumnExpansion(const ASize: Integer); public constructor Create(const AExpansionFactor: Integer = 999999); destructor Destroy; override; procedure ProcessDataLine(const ALine: string); override; procedure Finish; override; function GetDataFileName: string; override; function GetPuzzleName: string; override; end; implementation { TCosmicExpansion } procedure TCosmicExpansion.InitColumnExpansion(const ASize: Integer); var i: Integer; begin if FColumnExpansion.Count = 0 then begin FColumnExpansion.Capacity := ASize; for i := 1 to ASize do FColumnExpansion.Add(CEmptySpaceFactor); end; end; constructor TCosmicExpansion.Create(const AExpansionFactor: Integer); begin FExpansionFactor := AExpansionFactor; FColumnExpansion := specialize TList.Create; FRowExpansion := specialize TList.Create; FGalaxies := specialize TList.Create; end; destructor TCosmicExpansion.Destroy; begin FColumnExpansion.Free; FRowExpansion.Free; FGalaxies.Free; inherited Destroy; end; procedure TCosmicExpansion.ProcessDataLine(const ALine: string); var empty: Boolean; i : Integer; begin InitColumnExpansion(Length(ALine)); empty := True; for i := 1 to Length(ALine) do if ALine[i] = CGalaxyChar then begin FGalaxies.Add(Point(i, FRowExpansion.Count)); empty := False; FColumnExpansion[i - 1] := CNonEmptySpaceFactor; end; if empty then FRowExpansion.Add(CEmptySpaceFactor) else FRowExpansion.Add(CNonEmptySpaceFactor); end; procedure TCosmicExpansion.Finish; var i, j, k: Integer; begin for i := 0 to FGalaxies.Count - 1 do for j := i + 1 to FGalaxies.Count - 1 do begin for k := Min(FGalaxies[i].X, FGalaxies[j].X) to Max(FGalaxies[i].X, FGalaxies[j].X) - 1 do begin Inc(FPart1, 1 + FColumnExpansion[k]); Inc(FPart2, 1 + FColumnExpansion[k] * FExpansionFactor); end; for k := Min(FGalaxies[i].Y, FGalaxies[j].Y) + 1 to Max(FGalaxies[i].Y, FGalaxies[j].Y) do begin Inc(FPart1, 1 + FRowExpansion[k]); Inc(FPart2, 1 + FRowExpansion[k] * FExpansionFactor); end; end; end; function TCosmicExpansion.GetDataFileName: string; begin Result := 'cosmic_expansion.txt'; end; function TCosmicExpansion.GetPuzzleName: string; begin Result := 'Day 11: Cosmic Expansion'; end; end.