2022 Day 6: Tuning Trouble

Nothing too clever on this one, just a vector and some character comparison.

I used a Set for identifying duplicates. Is there an easy way to convert an array into a Set that doesn’t involve looping?

My implementation (299 SLoC) :: Ada centric solution

  • Implementing a generic Round Robin buffer with a Protected type
  • Implementing generic of generic
  • Using Ada.Strings.Maps for the fun (beauty) of it :heart_eyes:
  • Using Ada.Text_IO.Text_Streams to handle the input (data stream as in real life)

Have a look at my puzzle_06 :wink:

In Ada 2022 you can use 'Reduce attribute, like this:

pragma Ada_2022;
pragma Extensions_Allowed (On);

with Ada.Containers.Ordered_Sets;

procedure Main is
   
   package Sets is new Ada.Containers.Ordered_Sets (Character, "<", "=");
   
   Arr : String (1 .. 5) := "abcde";
   
   S : Sets.Set := Arr'Reduce (Sets.Insert, Sets.Empty);
begin
   --  Insert code here.
   null;
end Main;

But this just hides looping.

1 Like

You could use an occurrence counter. You do a β€œ+1” for the new character and a β€œ-1” for the character the goes out of the slice which is the marker candidate.
In my solution I use a simple array, so there is an explicit loop for testing duplicates, but probably there is a smarter structure for that. Or the same structure, but an additional variable that keeps the number of characters with duplicates. If the β€œ+1” moves the number of occurrences of a given character to 2, it makes one more duplicate; if the β€œ-1” decreases that number to 1, there is a duplicate less. When the duplicates counter is 0, you stop. NB: just thinking loud, untested idea.

1 Like

It was definitely worth considering that idea :smiley:

Loop for checking duplicates Duplicates counter Gain
HAC 0.058 0.016 3.6x
GNAT 0.00056 0.00027 2x

New version here.