aoa_23_20230119.0.0_38d1c7e5/src/aoa_12_1.adb

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
with Ada.Strings.Fixed;
with Ada.Text_IO;
with PragmARC.Conversions.Unbounded_Strings;
with PragmARC.Images;
with PragmARC.Line_Fields;

procedure AOA_12_1 is
   use PragmARC.Conversions.Unbounded_Strings;

   function Count_Of (Text : in String; Char : in Character) return Natural;
   -- Returns the number of Char in Text

   function Sum_Over (List : in PragmARC.Line_Fields.Field_Lists.Vector) return Natural;
   -- Converts the strings in list to integers and sums them

   type Bitmap is mod 2 ** 32;

   function Image is new PragmARC.Images.Modular_Image (Number => Bitmap);

   function One_Count (Value : in Bitmap) return Natural;
   -- Returns the number of 1 bits in value

   function Valid (Bit : in Bitmap; Text : in String; Num_Q : in Natural; Count : in PragmARC.Line_Fields.Field_Lists.Vector)
   return Boolean;
   -- After replacing Num_Q occurrences of '?' in Text with the corresponding Characters for Bit according to
   --   0 => '.'
   --   1 => '#'
   -- Returns True if that is a valid condition record for the run lengths in Count

   function Count_Of (Text : in String; Char : in Character) return Natural is
      Result : Natural := 0;
   begin -- Count_Of
      Sum : for C of Text loop
         if C = Char then
            Result := Result + 1;
         end if;
      end loop Sum;

      return Result;
   end Count_Of;

   function Sum_Over (List : in PragmARC.Line_Fields.Field_Lists.Vector) return Natural is
      Result : Natural := 0;
   begin -- Sum_Over
      Sum : for I in 1 .. List.Last_Index loop
         Result := Result + Integer'Value (+List.Element (I) );
      end loop Sum;

      return Result;
   end Sum_Over;

   function One_Count (Value : in Bitmap) return Natural is
      Text : constant String := Image (Value, Base => 2);

      Result : Natural := 0;
   begin -- One_Count
      All_Bits : for C of Text loop
         if C = '1' then
            Result := Result + 1;
         end if;
      end loop All_Bits;

      return Result;
   end One_Count;

   function Valid (Bit : in Bitmap; Text : in String; Num_Q : in Natural; Count : in PragmARC.Line_Fields.Field_Lists.Vector)
   return Boolean is
      function Replaced return String;
      -- Returns Text with '?' replaced according to the bits in Bit

      function Replaced return String is
         Result : String   := Text;
         Pos    : Natural := Result'First;
      begin -- Replaced
         All_Powers : for P in reverse 0 .. Num_Q - 1 loop
            Pos := Ada.Strings.Fixed.Index (Result, "?", From => Pos);

            exit All_Powers when Pos = 0;

            Result (Pos) := (if (Bit and 2 ** P) = 0 then '.' else '#');
            Pos := Pos + 1;
         end loop All_Powers;

         return Result;
      end Replaced;

      Full : constant String := Replaced;

      Start : Positive := Full'First;
      Stop  : Natural;
   begin -- Valid
      All_Runs : for I in 1 .. Count.Last_Index loop
         Start := Ada.Strings.Fixed.Index (Full, "#", From => Start);
         Stop := Ada.Strings.Fixed.Index (Full, ".", From => Start + 1);

         if Stop = 0 then
            Stop := Full'Last + 1;
         end if;

         if Stop - Start /= Integer'Value (+Count.Element (I) ) then
            return False;
         end if;

         Start := Stop + 1;
      end loop All_Runs;

      return True;
   end Valid;

   Input : Ada.Text_IO.File_Type;
   Sum   : Natural := 0;
begin -- AOA_12_1
   Ada.Text_IO.Open (File => Input, Mode => Ada.Text_IO.In_File, Name => "input_12");

   All_Lines : loop
      exit All_Lines when Ada.Text_IO.End_Of_File (Input);

      One_Line : declare
         Line  : constant String                               := Ada.Text_IO.Get_Line (Input);
         Text  : constant PragmARC.Line_Fields.Line_Field_Info := PragmARC.Line_Fields.Parsed (Line);
         Count : constant PragmARC.Line_Fields.Line_Field_Info := PragmARC.Line_Fields.Parsed (+Text.Field.Element (2), ',');
         Field : constant String                               := +Text.Field.Element (1);
         Num_Q : constant Natural                              := Count_Of (Field, '?');
         Need  : constant Natural                              := Sum_Over (Count.Field) - Count_Of (Field, '#');
      begin -- One_Line
         All_Possible : for I in Bitmap range 0 .. 2 ** Num_Q - 1 loop
            if One_Count (I) = Need and then Valid (I, Field, Num_Q, Count.Field) then
               Sum := Sum + 1;
            end if;
         end loop All_Possible;
      end One_Line;
   end loop All_Lines;

   Ada.Text_IO.Close (File => Input);
   Ada.Text_IO.Put_Line (Item => Sum'Image);
end AOA_12_1;