Skip to content

Commit

Permalink
Advent of code, day 8
Browse files Browse the repository at this point in the history
  • Loading branch information
gabr42 committed Dec 9, 2017
1 parent d612aa8 commit c4976f0
Show file tree
Hide file tree
Showing 6 changed files with 1,756 additions and 34 deletions.
51 changes: 17 additions & 34 deletions AdventOfCode2017/AdventOfCode7.dproj
Expand Up @@ -13,11 +13,6 @@
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Android' and '$(Base)'=='true') or '$(Base_Android)'!=''">
<Base_Android>true</Base_Android>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
Expand Down Expand Up @@ -55,17 +50,6 @@
<DCC_F>false</DCC_F>
<DCC_K>false</DCC_K>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Android)'!=''">
<Android_SplashImage640>$(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png</Android_SplashImage640>
<Android_LauncherIcon72>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png</Android_LauncherIcon72>
<Android_SplashImage426>$(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png</Android_SplashImage426>
<Android_SplashImage470>$(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png</Android_SplashImage470>
<Android_LauncherIcon144>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png</Android_LauncherIcon144>
<Android_LauncherIcon48>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png</Android_LauncherIcon48>
<Android_LauncherIcon96>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png</Android_LauncherIcon96>
<Android_SplashImage960>$(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png</Android_SplashImage960>
<Android_LauncherIcon36>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png</Android_LauncherIcon36>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<DCC_ConsoleTarget>true</DCC_ConsoleTarget>
Expand Down Expand Up @@ -151,27 +135,12 @@
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployClass Name="DependencyModule">
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.dll;.bpl</Extensions>
</Platform>
<DeployClass Name="ProjectiOSDeviceResourceRules">
<Platform Name="iOSDevice64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXResource">
Expand Down Expand Up @@ -550,12 +519,27 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceResourceRules">
<DeployClass Name="DependencyModule">
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.dll;.bpl</Extensions>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
</DeployClass>
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
Expand All @@ -568,7 +552,6 @@
<ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
</Deployment>
<Platforms>
<Platform value="Android">False</Platform>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
Expand Down
154 changes: 154 additions & 0 deletions AdventOfCode2017/AdventOfCode8.dpr
@@ -0,0 +1,154 @@
program AdventOfCode8;

{$APPTYPE CONSOLE}

{$R *.res}

uses
System.SysUtils, System.Generics.Collections, System.RegularExpressions, System.Math,
GpStreams, GpTextStream;

type
TRegisters = class(TDictionary<string, integer>)
public
function Max: integer;
end;

TInstruction = class
strict private
FParser: TRegEx;
FRegister: string;
FIncrement: integer;
FCondReg: string;
FCondOper: string;
FCondValue: integer;
protected
function Test(reg: TRegisters): boolean;
public
constructor Create;
procedure Parse(const s: string);
function Execute(reg: TRegisters): integer;
end;

{ TRegisters }

function TRegisters.Max: integer;
var
i: Integer;
begin
Result := 0;
for i in Values do
if i > Result then
Result := i;
end;

{ TInstruction }

constructor TInstruction.Create;
begin
FParser := TRegEx.Create('([a-z]+)\s+(dec|inc)\s+([\-0-9]+)\s+if\s+([a-z]+)\s+([^\s]+)+\s+([\-0-9]+)', [roIgnoreCase]);
end;

function TInstruction.Execute(reg: TRegisters): integer;
var
regValue: integer;
begin
if Test(reg) then begin
if not reg.TryGetValue(FRegister, regValue) then
regValue := 0;
Result := regValue + FIncrement;
reg.AddOrSetValue(FRegister, Result);
end;
end;

procedure TInstruction.Parse(const s: string);
var
match: TMatch;
mult : integer;
begin
match := FParser.Match(s);
if not match.Success then
raise Exception.Create('Invalid input: ' + s);
FRegister := match.Groups[1].Value;
mult := 1;
if SameText(match.Groups[2].Value, 'dec') then
mult := -1;
FIncrement := StrToInt(match.Groups[3].Value) * mult;
FCondReg := match.Groups[4].Value;
FCondOper := match.Groups[5].Value;
FCondValue := StrToInt(match.Groups[6].Value);
end;

function TInstruction.Test(reg: TRegisters): boolean;
var
regValue: integer;
begin
if not reg.TryGetValue(FCondReg, regValue) then
regValue := 0;
if FCondOper = '==' then
Result := regValue = FCondValue
else if FCondOper = '!=' then
Result := regValue <> FCondValue
else if FCondOper = '<' then
Result := regValue < FCondValue
else if FCondOper = '<=' then
Result := regValue <= FCondValue
else if FCondOper = '>' then
Result := regValue > FCondValue
else if FCondOper = '>=' then
Result := regValue >= FCondValue
else
raise Exception.Create('Invalid conditional test: ' + FCondOper);
end;

function PartA(const fileName: string): integer;
var
inst: TInstruction;
reg : TRegisters;
s : string;
begin
reg := TRegisters.Create;
try
inst := TInstruction.Create;
try
for s in EnumLines(AutoDestroyStream(SafeCreateFileStream(fileName, fmOpenRead)).Stream) do begin
inst.Parse(s);
inst.Execute(reg);
end;
finally FreeAndNil(inst); end;
Result := reg.Max;
finally FreeAndNil(reg); end;
end;

function PartB(const fileName: string): integer;
var
inst: TInstruction;
reg : TRegisters;
s : string;
begin
Result := 0;
reg := TRegisters.Create;
try
inst := TInstruction.Create;
try
for s in EnumLines(AutoDestroyStream(SafeCreateFileStream(fileName, fmOpenRead)).Stream) do begin
inst.Parse(s);
Result := Max(Result, inst.Execute(reg));
end;
finally FreeAndNil(inst); end;
finally FreeAndNil(reg); end;
end;

begin
try
Assert(PartA('..\..\AdventOfCode8test.txt') = 1, 'PartA test failed');
Assert(PartB('..\..\AdventOfCode8test.txt') = 10, 'PartB test failed');

Writeln(PartA('..\..\AdventOfCode8.txt'));
Writeln(PartB('..\..\AdventOfCode8.txt'));
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.

0 comments on commit c4976f0

Please sign in to comment.