We need a standard package to read the input.
with Ada.Text_IO;
Define a space grid:
Initial : constant := 8;
Turns : constant := 6;
Max : constant := Initial + Turns;
Min : constant := -Turns;
type Space_Grid is array
(Min .. Max, Min .. Max, Min .. Max, Min .. Max) of Boolean;
Space : Space_Grid := (others => (others => (others => (others => False))));
Input : Ada.Text_IO.File_Type;
A one game round cycle:
procedure Round (Space : in out Space_Grid) is
Copy : constant Space_Grid := Space;
function Neighbors (X, Y, Z, U : Integer) return Natural is
Result : Natural := 0;
begin
for DX in Integer'Max (Copy'First (1), X - 1) ..
Integer'Min (Copy'Last (1), X + 1)
loop
for DY in Integer'Max (Copy'First (2), Y - 1) ..
Integer'Min (Copy'Last (2), Y + 1)
loop
for DZ in Integer'Max (Copy'First (3), Z - 1) ..
Integer'Min (Copy'Last (3), Z + 1)
loop
for DU in Integer'Max (Copy'First (4), U - 1) ..
Integer'Min (Copy'Last (4), U + 1)
loop
Result := Result + Boolean'Pos (Copy (DX, DY, DZ, DU));
end loop;
end loop;
end loop;
end loop;
return Result - Boolean'Pos (Copy (X, Y, Z, U));
end Neighbors;
begin
for X in Copy'Range (1) loop
for Y in Copy'Range (2) loop
for Z in Copy'Range (3) loop
for U in Copy'Range (4) loop
if Copy (X, Y, Z, U) and then
Neighbors (X, Y, Z, U) not in 2 | 3
then
Space (X, Y, Z, U) := False;
elsif not Copy (X, Y, Z, U) and then
Neighbors (X, Y, Z, U) = 3
then
Space (X, Y, Z, U) := True;
end if;
end loop;
end loop;
end loop;
end loop;
end Round;
Read the input
Ada.Text_IO.Open (Input, Ada.Text_IO.In_File, "/home/jovyan/md/17/input");
for Y in 1 .. Initial loop
declare
Line : constant String := Ada.Text_IO.Get_Line (Input);
begin
pragma Assert (Line'Length = Initial);
for X in 1 .. Initial loop
Space (X, Y, 1, 1) := Line (X) = '#';
end loop;
end;
end loop;
Loop over all rounds
for J in 1 .. Turns loop
Round (Space);
end loop;
And print the result
declare
Result : Natural := 0;
begin
for X of Space loop
Result := Result + Boolean'Pos (X);
end loop;
Ada.Text_IO.Put_Line (Result'Image);
end;
2572