Task: Abbreviations, automatic



C#: using System;
using System.Collections.Generic;

namespace Abbreviations {
    class Program {
        static void Main(string[] args) {
            string[] lines = System.IO.File.ReadAllLines("days_of_week.txt");
            int i = 0;

            foreach (string line in lines) {
                i++;
                if (line.Length > 0) {
                    var days = line.Split();
                    if (days.Length != 7) {
                        throw new Exception("There aren't 7 days in line " + i);
                    }

                    Dictionary<string, int> temp = new Dictionary<string, int>();
                    foreach (string day in days) {
                        if (temp.ContainsKey(day)) {
                            Console.WriteLine(" ∞  {0}", line);
                            continue;
                        }
                        temp.Add(day, 1);
                    }

                    int len = 1;
                    while (true) {
                        temp.Clear();
                        foreach(string day in days) {
                            string key;
                            if (len < day.Length) {
                                key = day.Substring(0, len);
                            } else {
                                key = day;
                            }
                            if (temp.ContainsKey(key)) {
                                break;
                            }
                            temp.Add(key, 1);
                        }
                        if (temp.Count == 7) {
                            Console.WriteLine("{0,2:D}  {1}", len, line);
                            break;
                        }
                        len++;
                    }
                }
            }
        }
    }
}









Ada: with Ada.Containers.Indefinite_Vectors;
with Ada.Strings.Fixed;
with Ada.Strings.Maps;
with Ada.Text_IO;

procedure Abbreviations is

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

   function Split (Line : String) return Vector is
      Result : Vector;
      First  : Natural;
      Last   : Natural := Line'First - 1;
   begin
      while Last + 1 in Line'Range loop
         Ada.Strings.Fixed.Find_Token
           (Line, Ada.Strings.Maps.To_Set (" "), Last + 1,
            Ada.Strings.Outside, First, Last);
         exit when Last = 0;
         Append (Result, Line (First .. Last));
      end loop;
      return Result;
   end Split;

   function Abbrev_Length (Items : Vector) return Natural is
      use type Ada.Containers.Count_Type;
      Max     : Natural := 0;
      Abbrevs : Vector;
   begin
      for Item of Items loop
         Max := Natural'Max (Max, Item'Length);
      end loop;

      for Length in 1 .. Max loop
         Abbrevs := Empty_Vector;
         for Item of Items loop
            declare
               Last : constant Natural
                 := Natural'Min (Item'Last, Item'First + Length - 1);

               Abbrev : String renames Item (Item'First .. Last);
            begin
               exit when Abbrevs.Contains (Abbrev);
               Abbrevs.Append (Abbrev);
            end;
         end loop;
         if Abbrevs.Length = Items.Length then
            return Length;
         end if;
      end loop;
      return 0;
   end Abbrev_Length;

   procedure Process (Line : String) is
      package Natural_IO is new Ada.Text_IO.Integer_IO (Natural);
      Words  : constant Vector  := Split (Line);
      Length : constant Natural := Abbrev_Length (Words);
   begin
      Natural_IO.Put (Length, Width => 2);
      Put (" ");
      Put_Line (Line);
   end Process;

begin
   while not End_Of_File loop
      Process (Get_Line);
   end loop;
end Abbreviations;