Advent of Ada Submissions

[cantanima][23][Ada]Unstable Diffusion

[rommudoh][23][Ada] aoc2022-Ada/day23.adb at main - aoc2022-Ada - Codeberg.org

[wutka][23][SPARK] advent-of-code-2022-spark/day23.adb at 8758b412ac70e7f4a1a84c513967b286baf5b570 · wutka/advent-of-code-2022-spark · GitHub

[wutka][24][SPARK] advent-of-code-2022-spark/day24.adb at c5ff4ef9481c592fd6791597601c2aa02acf4155 · wutka/advent-of-code-2022-spark · GitHub

[Zertovitch][23][Ada]hac/aoc_2022_23.adb at fd3c20eac4f67030c0e438a28b855d1c216e1bbb · zertovitch/hac · GitHub

[cantanima][24][Ada]Blizzard Basin

[Zertovitch][24][Ada]hac/aoc_2022_24.adb at 35d1a87f7d3406eb7c4d102fa746add31cf7f81a · zertovitch/hac · GitHub

[rommudoh][24][Ada] aoc2022-Ada/day24.adb at main - aoc2022-Ada - Codeberg.org

[cantanima][25][Ada]Full of Hot Air

@Fabien.C What deadline do you want for solutions? I’ve thought of going back and converting some more Ada solutions to SPARK.

[Zertovitch][25][Ada]hac/aoc_2022_25.adb at 1219c4dd187d153e5538e3a7030519c0aaa12b87 · zertovitch/hac · GitHub

[rommudoh][25][Ada] aoc2022-Ada/day25.adb at main - aoc2022-Ada - Codeberg.org

[rocher][25][Ada]

pragma Ada_2022;

with Ada.Text_IO; use Ada.Text_IO;

with Ada.Numerics.Big_Numbers.Big_Integers;
use Ada.Numerics.Big_Numbers.Big_Integers;

procedure Day25_P1 is

   subtype Snafu_Range is Natural range 1 .. 25;
   subtype Snafu is String (Snafu_Range);

   Σ_Numbers : Big_Integer := 0;
   Input     : File_Type;

   -- align to the right and remove trailing zeros
   function Adjust (S : Snafu) return Snafu is
      N : Snafu_Range := Snafu_Range'First;
      R : Snafu       := (others => ' ');
   begin
      loop
         exit when S (N + 1) = ' ';
         N := N + 1;
      end loop;
      R (Snafu_Range'Last - N + 1 .. Snafu_Range'Last) := S (1 .. N);

      N := Snafu_Range'First;
      loop
         exit when R (N) /= ' ' and R (N) /= '0';
         R (N) := ' ';
         N     := N + 1;
      end loop;

      return R;
   end Adjust;

   function To_Big_Integer (S : Snafu) return Big_Integer is
      I     : Snafu_Range := Snafu_Range'Last;
      Value : Big_Integer := 0;
      Power : Big_Integer;
      Digit : Big_Integer := 0;
   begin
      loop
         Power := 5**(Snafu_Range'Last - I);
         Digit := 0;
         case S (I) is
            when '0' =>
               Digit := 0;
            when '1' =>
               Digit := 1;
            when '2' =>
               Digit := 2;
            when '-' =>
               Digit := -1;
            when '=' =>
               Digit := -2;
            when others =>
               null;
         end case;
         Value := @ + (Digit * Power);
         I     := I - 1;
         exit when S (I) = ' ';
      end loop;
      return Value;
   end To_Big_Integer;

   function To_Base5 (B : Big_Integer) return Big_Integer is
      Dividend  : Big_Integer := B;
      Remainder : Big_Integer;
      Quotient  : Big_Integer;
      Number    : Big_Integer := 0;
      Power     : Natural     := 0;
   begin
      loop
         Remainder := Dividend mod 5;
         Quotient  := Dividend / 5;
         Number    := Number + (Remainder * (10**Power));
         Power     := Power + 1;
         exit when Quotient < 5;
         Dividend := Quotient;
      end loop;
      Number := Number + (Quotient * (10**Power));
      return Number;
   end To_Base5;

   function To_Snafu (B : Big_Integer) return Snafu is
      S : Snafu   := (others => ' ');
      T : String  := Big_Integer'Image (To_Base5 (B));
      I : Natural := Snafu_Range'Last;

      Digit : array (0 .. T'Length) of Integer := (others => 0);

   begin
      for I in 2 .. T'Length loop
         Digit (I) := Character'Enum_Rep (T (I)) - Character'Enum_Rep ('0');
      end loop;

      for I in reverse 1 .. Digit'Last loop
         case Digit (I) is
            when 0 | 1 | 2 =>
               null;
            when others =>
               Digit (I - 1) := Digit (I - 1) + 1;
               Digit (I)     := Digit (I) - 5;
         end case;
      end loop;

      for I in 1 .. Digit'Last loop
         case Digit (I) is
            when 0 | 1 | 2 =>
               S (I) :=
                 Character'Enum_Val (Character'Enum_Rep ('0') + Digit (I));
            when -1 =>
               S (I) := '-';
            when -2 =>
               S (I) := '=';
            when others =>
               null;
         end case;
      end loop;

      return Adjust (S);
   end To_Snafu;

begin
   Open (Input, In_File, "input.txt");
   loop
      declare
         S    : Snafu  := (others => ' ');
         Line : String := Get_Line (Input);
      begin
         S (1 .. Line'Last) := Line;
         Σ_Numbers          := @ + To_Big_Integer (Adjust (S));
      end;
      exit when End_Of_File (Input);
   end loop;
   Close (Input);

   Put_Line ("Answer:" & To_Snafu (Σ_Numbers));
end Day25_P1;

Congratulations to all participants in this AoC leaderboard, with special mention to the top five who consistently finished all puzzles on time!! Great job!!

This year I wish I had more time to spend on AoC, specially during the second half.

From my side, It has been interesting to discover new things, e.g. Functional containers and what they are they for, dot-notation with -gnatX and enumerations using UTF-8 characters (rock-paper-scissors); I’ve been able to simplify even more the parsing of the input files (some of them boring and tedious); I published a solution using literate programming (Emacs + org-mode + Ada/SPARK babel support), which me think the program in a very different way; and did my first Dijkstra’s algorithm implementation in Ada.

I’ll try to finish the rest of puzzles, sooner or later, so I’ll post more solutions here (hopefully : )

5 Likes

[wutka][25][SPARK] advent-of-code-2022-spark/day25.adb at 3f627d2d86a3a9788bceeaabec8d1bd76fd071ee · wutka/advent-of-code-2022-spark · GitHub

[Neoxas][5][SPARK] GitHub - Neoxas/aoc_2022_ada: AOC 2022 solutions written in SPARK ADA!
[Neoxas][6][SPARK] GitHub - Neoxas/aoc_2022_ada: AOC 2022 solutions written in SPARK ADA!
[Neoxas][8][SPARK] GitHub - Neoxas/aoc_2022_ada: AOC 2022 solutions written in SPARK ADA!
[Neoxas][9][SPARK] GitHub - Neoxas/aoc_2022_ada: AOC 2022 solutions written in SPARK ADA!
[Neoxas][10][SPARK] GitHub - Neoxas/aoc_2022_ada: AOC 2022 solutions written in SPARK ADA!
[Neoxas][12][SPARK] GitHub - Neoxas/aoc_2022_ada: AOC 2022 solutions written in SPARK ADA!
[Neoxas][14][SPARK] GitHub - Neoxas/aoc_2022_ada: AOC 2022 solutions written in SPARK ADA!

2 Likes

[rocher][18][Ada] Boiling Boulders

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.Hashed_Sets; use Ada.Containers;

procedure Day18_P1 is

   type Position is record
      X, Y, Z : Integer;
   end record;

   function Position_Hash (P : Position) return Hash_Type is
     (Hash_Type (abs (P.X * 10_000 + P.Y * 1_000 + P.Z)));

   function "<" (P, Q : Position) return Boolean is
     ((P.X**2 + P.Y**2 + P.Z**2) < (Q.X**2 + Q.Y**2 + Q.Z**2));

   function "=" (P, Q : Position) return Boolean is
     (P.X = Q.X and then P.Y = Q.Y and then P.Z = Q.Z);

   package Droplet_Package is new Hashed_Sets
     (Element_Type        => Position, Hash => Position_Hash,
      Equivalent_Elements => "=");
   use Droplet_Package;

   Droplet : Droplet_Package.Set;
   Σ_Faces : Natural := 0;

   function "+" (C, D : Position) return Position is
     ((C.X + D.X, C.Y + D.Y, C.Z + D.Z));

   function Free_Side (P : Position) return Natural is
     (if Contains (Droplet, P) then 0 else 1);

   function Free_Sides (P : Position) return Natural is
     (Free_Side (P + (-1, 0, 0)) + Free_Side (P + (1, 0, 0)) +
      Free_Side (P + (0, -1, 0)) + Free_Side (P + (0, 1, 0)) +
      Free_Side (P + (0, 0, -1)) + Free_Side (P + (0, 0, 1)));

begin
   declare
      P     : Position;
      Input : File_Type;
      Comma : Character;
   begin
      Open (Input, In_File, "input.txt");
      loop
         Get (Input, P.X);
         Get (Input, Comma); -- skip ','
         Get (Input, P.Y);
         Get (Input, Comma); -- skip ','
         Get (Input, P.Z);
         Insert (Droplet, P);
         exit when End_Of_File (Input);
      end loop;
      Close (Input);
   end;

   for P of Droplet loop
      Σ_Faces := @ + Free_Sides (P);
   end loop;

   Put_Line ("Answer:" & Σ_Faces'Image);
end Day18_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.Hashed_Sets; use Ada.Containers;

procedure Day18_P2 is

   type Dim_Range is record
      Min, Max : Integer;
   end record;

   type Position is record
      X, Y, Z : Integer;
   end record;

   function Position_Hash (P : Position) return Hash_Type is
     (Hash_Type (abs (P.X * 10_000 + P.Y * 1_000 + P.Z)));

   function "<" (P, Q : Position) return Boolean is
     ((P.X**2 + P.Y**2 + P.Z**2) < (Q.X**2 + Q.Y**2 + Q.Z**2));

   function "=" (P, Q : Position) return Boolean is
     (P.X = Q.X and then P.Y = Q.Y and then P.Z = Q.Z);

   package Droplet_Package is new Hashed_Sets
     (Element_Type        => Position, Hash => Position_Hash,
      Equivalent_Elements => "=");
   use Droplet_Package;

   Droplet  : Droplet_Package.Set;
   External : Droplet_Package.Set;
   Dim_X    : Dim_Range := (Integer'Last, Integer'First);
   Dim_Y    : Dim_Range := (Integer'Last, Integer'First);
   Dim_Z    : Dim_Range := (Integer'Last, Integer'First);
   Σ_Faces  : Natural   := 0;

   function "+" (P, Q : Position) return Position is
     ((P.X + Q.X, P.Y + Q.Y, P.Z + Q.Z));

   function Face_At (P : Position) return Natural is
     (if Contains (Droplet, P) then 1 else 0);

   function Free_Side (P : Position) return Natural is (1 - Face_At (P));

   function Faces_At (P : Position) return Natural is
     (Face_At (P + (-1, 0, 0)) + Face_At (P + (1, 0, 0)) +
      Face_At (P + (0, -1, 0)) + Face_At (P + (0, 1, 0)) +
      Face_At (P + (0, 0, -1)) + Face_At (P + (0, 0, 1)));

   function Free_Sides (P : Position) return Natural is
     (Free_Side (P + (-1, 0, 0)) + Free_Side (P + (1, 0, 0)) +
      Free_Side (P + (0, -1, 0)) + Free_Side (P + (0, 1, 0)) +
      Free_Side (P + (0, 0, -1)) + Free_Side (P + (0, 0, 1)));

   function Is_Droplet (P : Position) return Boolean is
     (P.X >= Dim_X.Min and then P.X <= Dim_X.Max and then P.Y >= Dim_Y.Min
      and then P.Y <= Dim_Y.Max and then P.Z >= Dim_Z.Min
      and then P.Z <= Dim_Z.Max);

   function Is_Edge (P : Position) return Boolean is
     (P.X = Dim_X.Min or else P.X = Dim_X.Max or else P.Y = Dim_Y.Min
      or else P.Y = Dim_Y.Max or else P.Z = Dim_Z.Min or else P.Z = Dim_Z.Max);

   function Is_Space (P : Position) return Boolean is
     (not Contains (Droplet, P));

   procedure Search_External (P : Position) is
      procedure Check_External (Q : Position) is
      begin
         if Is_Droplet (Q) and then Is_Space (Q)
           and then not Contains (External, Q)
         then
            Insert (External, Q);
            Search_External (Q);
         end if;
      end Check_External;
   begin
      Check_External (P + (-1, 0, 0));
      Check_External (P + (+1, 0, 0));
      Check_External (P + (0, -1, 0));
      Check_External (P + (0, +1, 0));
      Check_External (P + (0, 0, -1));
      Check_External (P + (0, 0, +1));
   end Search_External;

begin
   declare
      P     : Position;
      Input : File_Type;
      Comma : Character;
   begin
      Open (Input, In_File, "input.txt");
      loop
         Get (Input, P.X);
         Get (Input, Comma); -- skip ','
         Get (Input, P.Y);
         Get (Input, Comma); -- skip ','
         Get (Input, P.Z);
         Dim_X := (Integer'Min (@.Min, P.X), Integer'Max (@.Max, P.X));
         Dim_Y := (Integer'Min (@.Min, P.Y), Integer'Max (@.Max, P.Y));
         Dim_Z := (Integer'Min (@.Min, P.Z), Integer'Max (@.Max, P.Z));
         Insert (Droplet, P);
         exit when End_Of_File (Input);
      end loop;
      Close (Input);
   end;

   declare
      Cube      : Position;
      Cube_Iter : Droplet_Package.Cursor := First (Droplet);
   begin
      while Has_Element (Cube_Iter) loop
         Cube      := Element (Cube_Iter);
         Σ_Faces   := @ + Free_Sides (Cube);
         Cube_Iter := Next (Cube_Iter);
      end loop;
   end;

   for X in Dim_X.Min .. Dim_X.Max loop
      for Y in Dim_Y.Min .. Dim_Y.Max loop
         for Z in Dim_Z.Min .. Dim_Z.Max loop
            if Is_Edge ((X, Y, Z)) and then Is_Space ((X, Y, Z)) then
               Include (External, (X, Y, Z));
               Search_External ((X, Y, Z));
            end if;
         end loop;
      end loop;
   end loop;

   for X in Dim_X.Min .. Dim_X.Max loop
      for Y in Dim_Y.Min .. Dim_Y.Max loop
         for Z in Dim_Z.Min .. Dim_Z.Max loop
            if Is_Space ((X, Y, Z)) and then not Contains (External, (X, Y, Z))
            then
               Σ_Faces := @ - Faces_At ((X, Y, Z));
            end if;
         end loop;
      end loop;
   end loop;

   Put_Line ("Answer:" & Σ_Faces'Image);
end Day18_P2;

Hello everyone, we are closing the submission for Advent of Ada/SPARK.
The results will be announced on the AdaCore blog in a few days (maybe a week or two).

Thanks to all the participants :partying_face:

Sorry I didn’t see you message. If you are still planning to do this just post here and I will update the results just before publishing the blog post.

[thvnx][1][Ada] adaventofcode/2022 at master · thvnx/adaventofcode · GitHub
[thvnx][2][Ada] adaventofcode/2022 at master · thvnx/adaventofcode · GitHub
[thvnx][3][Ada] adaventofcode/2022 at master · thvnx/adaventofcode · GitHub
[thvnx][4][Ada] adaventofcode/2022 at master · thvnx/adaventofcode · GitHub
[thvnx][5][Ada] adaventofcode/2022 at master · thvnx/adaventofcode · GitHub
[thvnx][6][Ada] adaventofcode/2022 at master · thvnx/adaventofcode · GitHub
[thvnx][7][Ada] adaventofcode/2022 at master · thvnx/adaventofcode · GitHub
[thvnx][8][Ada] adaventofcode/2022 at master · thvnx/adaventofcode · GitHub
[thvnx][9][Ada] adaventofcode/2022 at master · thvnx/adaventofcode · GitHub
[thvnx][10][Ada] adaventofcode/2022 at master · thvnx/adaventofcode · GitHub
[thvnx][11][Ada] adaventofcode/2022 at master · thvnx/adaventofcode · GitHub
[thvnx][12][Ada] adaventofcode/2022 at master · thvnx/adaventofcode · GitHub
[thvnx][13][Ada] adaventofcode/2022 at master · thvnx/adaventofcode · GitHub
[thvnx][14][Ada] adaventofcode/2022 at master · thvnx/adaventofcode · GitHub

2 Likes

Thanks. Right now I made the mistake of going back to the 2021 puzzles and am about halfway through them. I’ll try to get a couple of them done in SPARK, but now that I’m enmeshed in 2021 I’m not sure.