Add solution for day 6 part 1 and part 2

This commit is contained in:
Folkert Kevelam 2025-03-25 22:07:29 +01:00
parent 45fba48ab3
commit 810777b0de

214
AoC/2015/day_6/day_6.adb Normal file
View File

@ -0,0 +1,214 @@
with Ada.Text_IO; use Ada.Text_IO;
procedure Day_6 is
Parse_Error : Exception;
type Instruction is (
None,
Turn_On,
Turn_Off,
Toggle);
type Instr is
record
Inst : Instruction := None;
X0, Y0, X1, Y1 : Natural;
end record;
function Read_Coordinates( Text : String ) return Instr is
Output : Instr;
Start_Num : Natural := Text'First;
Thr : String := "through";
Thr_Idx : Natural := Thr'First;
type State is (Start, X0, Y0, Through, X1, Y1);
St : State := Start;
begin
for I in Text'Range loop
case St is
when Start =>
case Text(I) is
when '0' .. '9' =>
Start_Num := I;
St := X0;
when others =>
raise Parse_Error with "Invalid character";
end case;
when X0 =>
case Text(I) is
when '0' .. '9' =>
null;
when ',' =>
Output.X0 := Natural'Value(Text(Start_Num .. I-1));
Start_Num := I+1;
St := Y0;
when others =>
raise Parse_Error with "Invalid character";
end case;
when Y0 =>
case Text(I) is
when '0' .. '9' =>
null;
when ' ' =>
Output.Y0 := Natural'Value(Text(Start_Num .. I-1));
St := Through;
when others =>
raise Parse_Error with "Invalid character";
end case;
when Through =>
if Thr_Idx > Thr'Last then
if Text(I) = ' ' then
St := X1;
Start_Num := I+1;
else
raise Parse_Error with "Invalid character";
end if;
else
if Text(I) = Thr(Thr_Idx) then
Thr_Idx := @ + 1;
else
raise Parse_Error with "Invalid character";
end if;
end if;
when X1 =>
case Text(I) is
when '0' .. '9' =>
null;
when ',' =>
Output.X1 := Natural'Value(Text(Start_Num .. I-1));
Start_Num := I+1;
St := Y1;
when others =>
raise Parse_Error with "Invalid character";
end case;
when Y1 =>
case Text(I) is
when '0' .. '9' =>
null;
when others =>
raise Parse_Error with "Invalid character";
end case;
if I = Text'Last then
Output.Y1 := Natural'Value(Text(Start_Num .. I));
end if;
end case;
end loop;
return Output;
end Read_Coordinates;
function Read_Instruction( Text : String ) return Instr is
Idx : Natural := Text'First;
Inst : Instr;
begin
if Text(Idx .. Idx + 3) = "turn" then
if Text(Idx + 5 .. Idx + 6) = "on" then
Inst := Read_Coordinates( Text( Idx + 8 .. Text'Last));
Inst.Inst := Turn_On;
elsif Text(Idx + 5 .. Idx + 7) = "off" then
Inst := Read_Coordinates( Text( Idx + 9 .. Text'Last));
Inst.Inst := Turn_Off;
else
raise Parse_Error with "no on/off found";
end if;
elsif Text(Idx .. Idx + 5) = "toggle" then
Inst := Read_Coordinates( Text( Idx + 7 .. Text'Last));
Inst.Inst := Toggle;
else
raise Parse_Error with "Illegal Instruction";
end if;
return Inst;
end Read_Instruction;
type BMatrix is array (Natural range <>, Natural range <>) of Boolean;
type IMatrix is array (Natural range <>, Natural range <>) of Natural;
function Day_1_1( File_Name : String ) return Natural is
Sum : Natural := 0;
Lights : Bmatrix(0 .. 999, 0 .. 999 ) := (others => (others => False));
File : File_Type;
begin
Open(File, In_File, File_Name);
while not End_Of_File(File) loop
declare
Inst : Instr := Read_Instruction(Get_Line(File));
begin
for I in Inst.X0 .. Inst.X1 loop
for J in Inst.Y0 .. Inst.Y1 loop
case Inst.Inst is
when None =>
raise Parse_Error with "Cannot have none instruction";
when Toggle =>
Lights(I,J) := @ xor True;
when Turn_On =>
Lights(I,J) := True;
when Turn_Off =>
Lights(I,J) := False;
end case;
end loop;
end loop;
end;
end loop;
for I in 0 .. 999 loop
for J in 0 .. 999 loop
if Lights(I,J) = True then
Sum := @ + 1;
end if;
end loop;
end loop;
Close(File);
return Sum;
end Day_1_1;
function Day_1_2( File_Name : String ) return Natural is
Sum : Natural := 0;
Lights : Imatrix(0 .. 999, 0 .. 999 ) := (others => (others => 0));
File : File_Type;
begin
Open(File, In_File, File_Name);
while not End_Of_File(File) loop
declare
Inst : Instr := Read_Instruction(Get_Line(File));
begin
for I in Inst.X0 .. Inst.X1 loop
for J in Inst.Y0 .. Inst.Y1 loop
case Inst.Inst is
when None =>
raise Parse_Error with "Cannot have none instruction";
when Toggle =>
Lights(I,J) := @ + 2;
when Turn_On =>
Lights(I,J) := @ + 1;
when Turn_Off =>
Lights(I,J) := Natural'Max(0, @ - 1);
end case;
end loop;
end loop;
end;
end loop;
for I in 0 .. 999 loop
for J in 0 .. 999 loop
Sum := @ + Lights(I,J);
end loop;
end loop;
Close(File);
return Sum;
end Day_1_2;
File_Name : String := "input_day_6.txt";
begin
Put_Line("Christmas lights on" & Day_1_1(File_Name)'Image);
Put_Line("Christmas lights on" & Day_1_2(File_Name)'Image);
end Day_6;