Add solution for day 6 part 1 and part 2
This commit is contained in:
parent
45fba48ab3
commit
810777b0de
214
AoC/2015/day_6/day_6.adb
Normal file
214
AoC/2015/day_6/day_6.adb
Normal 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;
|
||||
Loading…
Reference in New Issue
Block a user