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