[rocher][5][Ada]
I use Double_Linked_Lists, but I miss a subprogram to concatenate to lists. Is there a better way to do part 2? without using a temporary list?
Part 1:
pragma Ada_2022;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Containers.Doubly_Linked_Lists;
procedure Day05_P1 is
package Crate_Stack is new Ada.Containers.Doubly_Linked_Lists (Character);
use Crate_Stack;
Num_Stacks : constant Natural := 9;
Tops : String (1 .. Num_Stacks);
Stack : array (1 .. Num_Stacks) of Crate_Stack.List;
Input : File_Type;
procedure Read_Stacks is
Finished : Boolean := False;
begin
loop
declare
Pos : Natural := 2;
Line : String := Get_Line (Input);
begin
if Line (Pos) /= '1' then
for I in 1 .. Num_Stacks loop
if Line (Pos) in 'A' .. 'Z' then
Stack (I).Append (Line (Pos));
end if;
Pos := @ + 4; -- jump to next stack
end loop;
else
Finished := True;
end if;
end;
exit when Finished;
end loop;
end Read_Stacks;
procedure Move (Qty, From, To : Natural) is
begin
for I in 1 .. Qty loop
Stack (To).Prepend (Stack (From).First_Element);
Stack (From).Delete_First;
end loop;
end Move;
begin
Open (Input, In_File, "input.txt");
Read_Stacks;
loop
declare
Separator : String (1 .. 5);
Qty, From, To : Natural;
begin
Get (Input, Separator); -- skip 'move '
Get (Input, Qty);
Get (Input, Separator); -- skip ' from'
Get (Input, From);
Get (Input, Separator (1 .. 4)); -- skip ' to '
Get (Input, To);
Move (Qty, From, To);
end;
exit when End_Of_File (Input);
end loop;
Close (Input);
for I in 1 .. Num_Stacks loop
if Stack (I).Is_Empty then
Tops (I) := ' ';
else
Tops (I) := Stack (I).First_Element;
end if;
end loop;
Put_Line ("Answer: " & Tops);
end Day05_P1;
Part 2:
pragma Ada_2022;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Containers.Doubly_Linked_Lists;
procedure Day05_P2 is
package Crate_Stack is new Ada.Containers.Doubly_Linked_Lists (Character);
use Crate_Stack;
Num_Stacks : constant Natural := 9;
Tops : String (1 .. Num_Stacks);
Stack : array (1 .. Num_Stacks) of Crate_Stack.List;
Input : File_Type;
procedure Read_Stacks is
Finished : Boolean := False;
begin
loop
declare
Pos : Natural := 2;
Line : String := Get_Line (Input);
begin
if Line (Pos) /= '1' then
for I in 1 .. Num_Stacks loop
if Line (Pos) in 'A' .. 'Z' then
Stack (I).Append (Line (Pos));
end if;
Pos := @ + 4; -- jump to next stack
end loop;
else
Finished := True;
end if;
end;
exit when Finished;
end loop;
end Read_Stacks;
procedure Move_Stack (Qty, From, To : Natural) is
Temp : Crate_Stack.List;
begin
for I in 1 .. Qty loop
Temp.Prepend (Stack (From).First_Element);
Stack (From).Delete_First;
end loop;
for I in 1 .. Qty loop
Stack (To).Prepend (Temp.First_Element);
Temp.Delete_First;
end loop;
end Move_Stack;
begin
Open (Input, In_File, "input.txt");
Read_Stacks;
loop
declare
Separator : String (1 .. 5);
Qty, From, To : Natural;
begin
Get (Input, Separator); -- skip 'move '
Get (Input, Qty);
Get (Input, Separator); -- skip ' from'
Get (Input, From);
Get (Input, Separator (1 .. 4)); -- skip ' to '
Get (Input, To);
Move_Stack (Qty, From, To);
end;
exit when End_Of_File (Input);
end loop;
Close (Input);
for I in 1 .. Num_Stacks loop
if Stack (I).Is_Empty then
Tops (I) := ' ';
else
Tops (I) := Stack (I).First_Element;
end if;
end loop;
Put_Line ("Answer: " & Tops);
end Day05_P2;