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.Mapsfor the fun (beauty) of it
 - Using 
Ada.Text_IO.Text_Streamsto handle the input (data stream as in real life) 
Have a look at my puzzle_06 ![]()
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.
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.
It was definitely worth considering that idea ![]()
Loop for checking duplicates Duplicates counter Gain HAC 0.058 0.016 3.6x GNAT 0.00056 0.00027 2x 
New version here.