Task: Last letter-first letter


C++: #include <iostream>
#include <string>
#include <vector>

struct last_letter_first_letter {
    size_t max_path_length = 0;
    size_t max_path_length_count = 0;
    std::vector<std::string> max_path_example;

    void search(std::vector<std::string>& names, size_t offset) {
        if (offset > max_path_length) {
            max_path_length = offset;
            max_path_length_count = 1;
            max_path_example.assign(names.begin(), names.begin() + offset);
        } else if (offset == max_path_length) {
            ++max_path_length_count;
        }
        char last_letter = names[offset - 1].back();
        for (size_t i = offset, n = names.size(); i < n; ++i) {
            if (names[i][0] == last_letter) {
                names[i].swap(names[offset]);
                search(names, offset + 1);
                names[i].swap(names[offset]);
            }
        }
    }

    void find_longest_chain(std::vector<std::string>& names) {
        max_path_length = 0;
        max_path_length_count = 0;
        max_path_example.clear();
        for (size_t i = 0, n = names.size(); i < n; ++i) {
            names[i].swap(names[0]);
            search(names, 1);
            names[i].swap(names[0]);
        }
    }
};

int main() {
    std::vector<std::string> names{"audino", "bagon", "baltoy", "banette",
        "bidoof", "braviary", "bronzor", "carracosta", "charmeleon",
        "cresselia", "croagunk", "darmanitan", "deino", "emboar",
        "emolga", "exeggcute", "gabite", "girafarig", "gulpin",
        "haxorus", "heatmor", "heatran", "ivysaur", "jellicent",
        "jumpluff", "kangaskhan", "kricketune", "landorus", "ledyba",
        "loudred", "lumineon", "lunatone", "machamp", "magnezone",
        "mamoswine", "nosepass", "petilil", "pidgeotto", "pikachu",
        "pinsir", "poliwrath", "poochyena", "porygon2", "porygonz",
        "registeel", "relicanth", "remoraid", "rufflet", "sableye",
        "scolipede", "scrafty", "seaking", "sealeo", "silcoon",
        "simisear", "snivy", "snorlax", "spoink", "starly", "tirtouga",
        "trapinch", "treecko", "tyrogue", "vigoroth", "vulpix",
        "wailord", "wartortle", "whismur", "wingull", "yamask"};
    last_letter_first_letter solver;
    solver.find_longest_chain(names);
    std::cout << "Maximum path length: " << solver.max_path_length << '\n';
    std::cout << "Paths of that length: " << solver.max_path_length_count << '\n';
    std::cout << "Example path of that length:\n  ";
    for (size_t i = 0, n = solver.max_path_example.size(); i < n; ++i) {
        if (i > 0 && i % 7 == 0)
            std::cout << "\n  ";
        else if (i > 0)
            std::cout << ' ';
        std::cout << solver.max_path_example[i];
    }
    std::cout << '\n';
}










Ada: with Ada.Containers.Indefinite_Vectors, Ada.Text_IO;

procedure Lalefile is

   package Word_Vec is new Ada.Containers.Indefinite_Vectors
     (Index_Type   => Positive,
      Element_Type => String);

   use type Word_Vec.Vector, Ada.Containers.Count_Type;

   type Words_Type is array (Character) of Word_Vec.Vector;

   procedure Read(Words: out Words_Type) is
      F: Ada.Text_IO.File_Type;
   begin
      Ada.Text_IO.Open(File => F, 
                       Name => "pokemon70.txt",
                       Mode => Ada.Text_IO.In_File);
      loop
         declare
            Word: String := Ada.Text_IO.Get_Line(F);
         begin
            exit when Word = "";
            Words(Word(Word'First)).Append(Word);
         end;
      end loop;
   exception
      when Ada.Text_IO.End_Error => null;
   end Read;

   procedure Write (List: Word_Vec.Vector; Prefix: String := "   ") is
      Copy: Word_Vec.Vector := List;
   begin
      loop
         exit when Copy.Is_Empty;
         Ada.Text_IO.Put_Line(Prefix & Copy.First_Element);
         Copy.Delete_First;
      end loop;
   end Write;

   function Run(Start: Character; Words: Words_Type) return Word_Vec.Vector is
      Result: Word_Vec.Vector := Word_Vec.Empty_Vector;
   begin
      for I in Words(Start).First_Index .. Words(Start).Last_Index loop
         declare
            Word: String := Words(Start).Element(I);
            Dupl: Words_Type := Words;
            Alternative : Word_Vec.Vector;
         begin
            Dupl(Start).Delete(I);
            Alternative := Word & Run(Word(Word'Last), Dupl);
            if Alternative.Length > Result.Length then
               Result := Alternative;
            end if;
         end;
      end loop;
      return Result;
   end Run;

   W: Words_Type;
   A_Vector: Word_Vec.Vector;
   Best: Word_Vec.Vector := Word_Vec.Empty_Vector;

begin
   Read(W);
   Ada.Text_IO.Put("Processing ");
   for Ch in Character range 'a' .. 'z' loop
      Ada.Text_IO.Put(Ch & ", ");
      A_Vector := Run(Ch, W);
      if A_Vector.Length > Best.Length then
         Best := A_Vector;
      end if;
   end loop;
   Ada.Text_IO.New_Line;
   Ada.Text_IO.Put_Line("Length of longest Path:" &
                          Integer'Image(Integer(Best.Length)));
   Ada.Text_IO.Put_Line("One such path:");
   Write(Best);
end Lalefile;