Add solutions for day 3 part 1 and part 2
This commit is contained in:
parent
9539d40c74
commit
60c80cf946
120
AoC/2015/day_3/day_3.adb
Normal file
120
AoC/2015/day_3/day_3.adb
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
with Ada.Text_IO; use Ada.Text_IO;
|
||||||
|
with Ada.Containers; use Ada.Containers;
|
||||||
|
with Ada.Containers.Hashed_Sets;
|
||||||
|
|
||||||
|
procedure Day_3 is
|
||||||
|
|
||||||
|
type Uint32 is mod 2**32;
|
||||||
|
|
||||||
|
type Coordinate is
|
||||||
|
record
|
||||||
|
X : Uint32;
|
||||||
|
Y : Uint32;
|
||||||
|
end record;
|
||||||
|
|
||||||
|
function "=" (A,B : Coordinate) return Boolean is
|
||||||
|
begin
|
||||||
|
return A.X = B.X and A.Y = B.Y;
|
||||||
|
end "=";
|
||||||
|
|
||||||
|
type Coordinates is array (Natural range <>) of Coordinate;
|
||||||
|
|
||||||
|
function Hash(A : Uint32) return Uint32 is
|
||||||
|
Key : Uint32 := A;
|
||||||
|
begin
|
||||||
|
Key := (not @) + (@ * 2**15);
|
||||||
|
Key := @ or (@ / 2**12);
|
||||||
|
Key := @ + (@ * 2**2);
|
||||||
|
Key := @ or (@ / 2**4);
|
||||||
|
Key := @ * 2057;
|
||||||
|
Key := @ or (Key / 2**16);
|
||||||
|
return Key;
|
||||||
|
end Hash;
|
||||||
|
|
||||||
|
function Hash(A : Coordinate) return Hash_Type is
|
||||||
|
Result : UInt32 := Hash((53 + Hash(A.X)) * 53 + Hash(A.Y));
|
||||||
|
begin
|
||||||
|
return Hash_Type(Integer(Result/2));
|
||||||
|
end Hash;
|
||||||
|
|
||||||
|
package Set is new Ada.Containers.Hashed_Sets(
|
||||||
|
Element_Type => Coordinate,
|
||||||
|
Hash => Hash,
|
||||||
|
Equivalent_Elements => "=");
|
||||||
|
|
||||||
|
function Read_File(File_Name : String) return Set.Set is
|
||||||
|
S : Set.Set;
|
||||||
|
Base : Coordinate := ( X => 0, Y => 0);
|
||||||
|
File : File_Type;
|
||||||
|
begin
|
||||||
|
S.Insert(Base);
|
||||||
|
Open(File, In_File, File_Name);
|
||||||
|
|
||||||
|
main_loop:
|
||||||
|
while not End_Of_File(File) loop
|
||||||
|
declare
|
||||||
|
Line : String := Get_Line(File);
|
||||||
|
begin
|
||||||
|
for I in Line'Range loop
|
||||||
|
case Line(I) is
|
||||||
|
when '^' => Base.Y := @ + 1;
|
||||||
|
when 'v' => Base.Y := @ - 1;
|
||||||
|
when '>' => Base.X := @ + 1;
|
||||||
|
when '<' => Base.X := @ - 1;
|
||||||
|
when others => exit main_loop;
|
||||||
|
end case;
|
||||||
|
if not S.Contains(Base) then
|
||||||
|
S.Insert(Base);
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
end;
|
||||||
|
end loop main_loop;
|
||||||
|
|
||||||
|
Close(File);
|
||||||
|
|
||||||
|
return S;
|
||||||
|
end Read_File;
|
||||||
|
|
||||||
|
function Read_File_Part_Two(File_Name : String) return Set.Set is
|
||||||
|
S : Set.Set;
|
||||||
|
Base : Coordinates(0 .. 1) :=
|
||||||
|
(others => (X => 0, Y => 0));
|
||||||
|
File : File_Type;
|
||||||
|
Santa : Natural := 0;
|
||||||
|
begin
|
||||||
|
S.Insert(Base(0));
|
||||||
|
Open(File, In_File, File_Name);
|
||||||
|
|
||||||
|
main_loop:
|
||||||
|
while not End_Of_File(File) loop
|
||||||
|
declare
|
||||||
|
Line : String := Get_Line(File);
|
||||||
|
begin
|
||||||
|
for I in Line'Range loop
|
||||||
|
case Line(I) is
|
||||||
|
when '^' => Base(Santa).Y := @ + 1;
|
||||||
|
when 'v' => Base(Santa).Y := @ - 1;
|
||||||
|
when '>' => Base(Santa).X := @ + 1;
|
||||||
|
when '<' => Base(Santa).X := @ - 1;
|
||||||
|
when others => exit main_loop;
|
||||||
|
end case;
|
||||||
|
if not S.Contains(Base(Santa)) then
|
||||||
|
S.Insert(Base(Santa));
|
||||||
|
end if;
|
||||||
|
Santa := (@ + 1) mod 2;
|
||||||
|
end loop;
|
||||||
|
end;
|
||||||
|
end loop main_loop;
|
||||||
|
|
||||||
|
Close(File);
|
||||||
|
return S;
|
||||||
|
end Read_File_Part_Two;
|
||||||
|
|
||||||
|
File_Name : String := "input_day_3.txt";
|
||||||
|
S : Set.Set;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
Put_Line(Read_File_Part_Two(File_Name).Length'Image);
|
||||||
|
|
||||||
|
end Day_3;
|
||||||
Loading…
Reference in New Issue
Block a user