with Ada.Containers.Vectors;
with Ada.Text_IO;
with PragmARC.Conversions.Unbounded_Strings;
with PragmARC.Line_Fields;
procedure AOA_05_1 is
use PragmARC.Conversions.Unbounded_Strings;
type Thing_ID is range 0 .. 2 ** 63 - 1;
type Range_Info is record
Low : Thing_ID;
High : Thing_ID;
end record;
type Mapping_Info is record
Source : Range_Info;
Dest : Thing_ID;
end record;
package Map_Sets is new Ada.Containers.Vectors (Index_Type => Positive, Element_Type => Mapping_Info);
package Map_Lists is new Ada.Containers.Vectors (Index_Type => Positive, Element_Type => Map_Sets.Vector, "=" => Map_Sets."=");
Input : Ada.Text_IO.File_Type;
Initial : PragmARC.Line_Fields.Line_Field_Info;
Set_List : Map_Sets.Vector;
Map : Map_Lists.Vector;
Source : Thing_ID;
Found : Boolean;
Dest : Thing_ID;
Min : Thing_ID := Thing_ID'Last;
begin -- AOA_05_1
Ada.Text_IO.Open (File => Input, Mode => Ada.Text_IO.In_File, Name => "input_05");
Initial := PragmARC.Line_Fields.Parsed (Ada.Text_IO.Get_Line (Input) ); -- Seed IDs start at 2
Ada.Text_IO.Skip_Line (File => Input);
Handle_EOF : begin
All_Maps : loop
Ada.Text_IO.Put_Line (Item => Ada.Text_IO.Get_Line (Input) ); -- Skip header
Set_List.Clear;
All_Sets : loop
One_Set : declare
Line : constant String := Ada.Text_IO.Get_Line (Input);
Set : Mapping_Info;
Value : PragmARC.Line_Fields.Line_Field_Info;
Src : Thing_ID;
Len : Thing_ID;
begin -- One_Set
exit All_Sets when Line = "";
Value := PragmARC.Line_Fields.Parsed (Line);
Src := Thing_ID'Value (+Value.Field.Element (2) );
Len := Thing_ID'Value (+Value.Field.Element (3) ) - 1;
Set := (Source => (Low => Src, High => Src + Len),
Dest => Thing_ID'Value (+Value.Field.Element (1) ) );
Set_List.Append (New_Item => Set);
end One_Set;
end loop All_Sets;
Map.Append (New_Item => Set_List);
end loop All_Maps;
exception -- Handle_EOF
when Ada.Text_IO.End_Error =>
null;
end Handle_EOF;
Ada.Text_IO.Close (File => Input);
All_Seeds : for I in 2 .. Initial.Field.Last_Index loop
Source := Thing_ID'Value (+Initial.Field.Element (I) );
Check_Maps : for M in 1 .. Map.Last_Index loop
Found := False;
Check_Sets : for S in 1 .. Map.Element (M).Last_Index loop
Check_Set : declare
Set : Mapping_Info renames Map.Element (M).Element (S);
begin -- Check_Set
if Source in Set.Source.Low .. Set.Source.High then
Found := True;
Dest := Set.Dest + (Source - Set.Source.Low);
exit Check_Sets;
end if;
end Check_Set;
end loop Check_Sets;
if not Found then
Dest := Source;
end if;
Source := Dest;
end loop Check_Maps;
Min := Thing_ID'Min (Min, Dest);
end loop All_Seeds;
Ada.Text_IO.Put_Line (Item => Min'Image);
end AOA_05_1;