Task: Word frequency


C++: #include <algorithm>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <iterator>
#include <string>
#include <unordered_map>
#include <vector>

int main(int ac, char** av) {
  std::ios::sync_with_stdio(false);
  int head = (ac > 1) ? std::atoi(av[1]) : 10;
  std::istreambuf_iterator<char> it(std::cin), eof;
  std::filebuf file;
  if (ac > 2) {
    if (file.open(av[2], std::ios::in), file.is_open()) {
      it = std::istreambuf_iterator<char>(&file);
    } else return std::cerr << "file " << av[2] << " open failed\n", 1;
  }
  auto alpha = [](unsigned c) { return c-'A' < 26 || c-'a' < 26; };
  auto lower = [](unsigned c) { return c | '\x20'; };
  std::unordered_map<std::string, int> counts;
  std::string word;
  for (; it != eof; ++it) {
    if (alpha(*it)) {
      word.push_back(lower(*it));
    } else if (!word.empty()) {
      ++counts[word];
      word.clear();
    }
  }
  if (!word.empty()) ++counts[word]; 
  std::vector<std::pair<const std::string,int> const*> out;
  for (auto& count : counts) out.push_back(&count);
  std::partial_sort(out.begin(),
    out.size() < head ? out.end() : out.begin() + head,
    out.end(), [](auto const* a, auto const* b) {
      return a->second > b->second;
    });
  if (out.size() > head) out.resize(head);
  for (auto const& count : out) {
    std::cout << count->first << ' ' << count->second << '\n';
  }
  return 0;
}










Ada: with Ada.Command_Line;
with Ada.Text_IO;
with Ada.Integer_Text_IO;
with Ada.Strings.Maps;
with Ada.Strings.Fixed;
with Ada.Characters.Handling;
with Ada.Containers.Indefinite_Ordered_Maps;
with Ada.Containers.Indefinite_Ordered_Sets;
with Ada.Containers.Ordered_Maps;

procedure Word_Frequency is
    package TIO renames Ada.Text_IO;

    package String_Counters is new Ada.Containers.Indefinite_Ordered_Maps(String, Natural);
    package String_Sets is new Ada.Containers.Indefinite_Ordered_Sets(String);
    package Sorted_Counters is new Ada.Containers.Ordered_Maps
      (Natural,
       String_Sets.Set,
       "=" => String_Sets."=",
       "<" => ">");
    

    procedure Increment(Key : in String; Element : in out Natural) is
    begin
        Element := Element + 1;
    end Increment;

    path : constant String := Ada.Command_Line.Argument(1);
    how_many : Natural := 10;
    set : constant Ada.Strings.Maps.Character_Set := Ada.Strings.Maps.To_Set(ranges => (('a', 'z'), ('0', '9')));
    F : TIO.File_Type;
    first : Positive;
    last : Natural;
    from : Positive;
    counter : String_Counters.Map;
    sorted_counts : Sorted_Counters.Map;
    C1 : String_Counters.Cursor;
    C2 : Sorted_Counters.Cursor;
    tmp_set : String_Sets.Set;
begin
    
    TIO.Open(F, name => path, mode => TIO.In_File);
    while not TIO.End_Of_File(F) loop
       declare
          line : constant String := Ada.Characters.Handling.To_Lower(TIO.Get_Line(F));
       begin
          from := line'First;
          loop
             Ada.Strings.Fixed.Find_Token(line(from .. line'Last), set, Ada.Strings.Inside, first, last);
             exit when last < First;
             C1 := counter.Find(line(first .. last));
             if String_Counters.Has_Element(C1) then
                counter.Update_Element(C1, Increment'Access);
             else
                counter.Insert(line(first .. last), 1);
             end if;
             from := last + 1;
          end loop;
       end;
    end loop;
    TIO.Close(F);

    
    C1 := counter.First;
    while String_Counters.Has_Element(C1) loop
       if sorted_counts.Contains(String_Counters.Element(C1)) then
          tmp_set := sorted_counts.Element(String_Counters.Element(C1));
          tmp_set.Include(String_Counters.Key(C1));
       else
          sorted_counts.Include(String_Counters.Element(C1), String_Sets.To_Set(String_Counters.Key(C1)));
       end if;
       String_Counters.Next(C1);
    end loop;

    
    C2 := sorted_counts.First;
    while Sorted_Counters.Has_Element(C2) loop
       for Item of Sorted_Counters.Element(C2) loop
          Ada.Integer_Text_IO.Put(TIO.Standard_Output, Sorted_Counters.Key(C2), width => 9);
          TIO.Put(TIO.Standard_Output, " ");
          TIO.Put_Line(Item);
       end loop;
       Sorted_Counters.Next(C2);
       how_many := how_many - 1;
       exit when how_many = 0;
    end loop;
end Word_Frequency;