Task: Box the compass


C++: #include <string>
#include <boost/array.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/format.hpp>
#include <boost/foreach.hpp>
#include <iostream>
#include <math.h>
using std::string;
using namespace boost::assign;

int get_Index(float angle)
{
   return static_cast<int>(floor(angle / 11.25 +0.5 )) % 32 + 1;
}

string get_Abbr_From_Index(int i)
{
    static boost::array<std::string, 32> points(list_of
            ("N")("NbE")("NNE")("NEbN")("NE")("NEbE")("ENE")("EbN")
            ("E")("EbS")("ESE")("SEbE")("SE")("SEbS")("SSE")("SbE")
            ("S")("SbW")("SSW")("SWbS")("SW")("SWbW")("WSW")("WbS")
            ("W")("WbN")("WNW")("NWbW")("NW")("NWbN")("NNW")("NbW"));
    return points[i-1];
}

string Build_Name_From_Abbreviation(string a)
{
    string retval;
    for (int i = 0; i < a.size(); ++i){
        if ((1 == i) && (a[i] != 'b') && (a.size() == 3)) retval += "-";
        switch (a[i]){
            case 'N' : retval += "north"; break; 
            case 'S' : retval += "south"; break; 
            case 'E' : retval += "east";  break; 
            case 'W' : retval += "west";  break; 
            case 'b' : retval += " by ";  break;
        }
    }
    retval[0] = toupper(retval[0]);
    return retval;
}

int main()
{
    boost::array<float,33> headings(list_of
            (0.0)(16.87)(16.88)(33.75)(50.62)(50.63)(67.5)(84.37)(84.38)(101.25)
            (118.12)(118.13)(135.0)(151.87)(151.88)(168.75)(185.62)(185.63)(202.5)
            (219.37)(219.38)(236.25)(253.12)(253.13)(270.0)(286.87)(286.88)(303.75)
            (320.62)(320.63)(337.5)(354.37)(354.38));
    int i;
    boost::format f("%1$4d %2$-20s %3$_7.2f");

    BOOST_FOREACH(float a, headings)
    {
        i = get_Index(a);
        std::cout << f % i %  Build_Name_From_Abbreviation(get_Abbr_From_Index(i)) % a << std::endl;
    }
    return 0;
}










Ada: with Ada.Text_IO;

procedure Box_The_Compass is

   type Degrees is digits 5 range 0.00 .. 359.99;
   type Index_Type is mod 32;

   function Long_Name(Short: String) return String is

      function Char_To_Name(Char: Character) return String is
      begin
         case Char is
            when 'N' | 'n' => return Char & "orth";
            when 'S' | 's' => return Char & "outh";
            when 'E' | 'e' => return Char & "ast";
            when 'W' | 'w' => return Char & "est";
            when 'b' => return " by ";
            when '-' => return "-";
            when others => raise Constraint_Error;
         end case;
      end Char_To_Name;

   begin
      if Short'Length = 0 or else Short(Short'First)=' ' then
         return "";
      else
         return Char_To_Name(Short(Short'First))
           & Long_Name(Short(Short'First+1 .. Short'Last));
      end if;
   end Long_Name;

   procedure Put_Line(Angle: Degrees) is

      function Index(D: Degrees) return Index_Type is
      begin
         return Index_Type(Integer(Degrees'Rounding(D/11.25)) mod 32);
      end Index;

      I: Integer := Integer(Index(Angle))+1;
      package DIO is new Ada.Text_IO.Float_IO(Degrees);
      Abbr: constant array(Index_Type) of String(1 .. 4)
        := ("N   ", "Nbe ", "N-ne", "Nebn", "Ne  ", "Nebe", "E-ne", "Ebn ",
            "E   ", "Ebs ", "E-se", "Sebe", "Se  ", "Sebs", "S-se", "Sbe ",
            "S   ", "Sbw ", "S-sw", "Swbs", "Sw  ", "Swbw", "W-sw", "Wbs ",
            "W   ", "Wbn ", "W-nw", "Nwbw", "Nw  ", "Nwbn", "N-nw", "Nbw ");

   begin
      DIO.Put(Angle, Fore => 3, Aft => 2, Exp => 0); 
      Ada.Text_IO.Put(" |");
      if I <= 9 then
         Ada.Text_IO.Put(" ");
      end if;
      Ada.Text_IO.Put_Line(" "  & Integer'Image(I) & " | "
                             & Long_Name(Abbr(Index(Angle))));
   end Put_Line;

   Difference: constant array(0..2) of Degrees'Base
     := (0=> 0.0, 1=> +5.62, 2=> - 5.62);

begin
   Ada.Text_IO.Put_Line(" angle | box | compass point");
   Ada.Text_IO.Put_Line(" 
   for I in 0 .. 32 loop
      Put_Line(Degrees(Degrees'Base(I) * 11.25 + Difference(I mod 3)));
   end loop;
end Box_The_Compass;