PageRenderTime 113ms CodeModel.GetById 35ms app.highlight 24ms RepoModel.GetById 11ms app.codeStats 1ms

/euler003/Euler003.adb

http://github.com/darkestkhan/project_euler
Ada | 101 lines | 65 code | 7 blank | 29 comment | 9 complexity | 65ba66094cb60652a622d7ac3fa0ecfa MD5 | raw file
  1pragma License ( GPL );
  2------------------------------------------------------------------------------
  3-- Author: darkestkhan                                                      --
  4-- Email:  darkestkhan@gmail.com                                            --
  5-- License: GNU GPLv3 or any later as published by Free Software Foundation --
  6-- ( see license.txt file )                                                 --
  7-- Copyright Š 2011 darkestkhan                                             --
  8------------------------------------------------------------------------------
  9-- This Program is Free Software: You Can Redistribute It and/or Modify     --
 10-- It Under The Terms of The GNU General Public License As Published By     --
 11-- The Free Software Foundation, Either Version 3 of The License, or        --
 12-- (at Your Option) Any Later Version.                                      --
 13--                                                                          --
 14-- This Program is Distributed in The Hope That It Will Be Useful,          --
 15-- But WITHOUT ANY WARRANTY; Without Even The Implied Warranty of           --
 16-- MERCHANTABILITY or FITNESS for A PARTICULAR PURPOSE.  See The            --
 17-- GNU General Public License for More Details.                             --
 18--                                                                          --
 19-- You Should Have Received A Copy of The GNU General Public License        --
 20-- Along with This Program.  if not, See <Http://Www.Gnu.Org/Licenses/>.    --
 21------------------------------------------------------------------------------
 22with TTY;
 23with Ada.Numerics.Long_Elementary_Functions;
 24with Ada.Command_Line;
 25with Ada.Task_Identification;
 26with Ada.IO_Exceptions;
 27procedure Euler003 is
 28
 29  Argc: constant Integer := Ada.Command_Line.Argument_Count;
 30  Terminal: TTY.TTY;
 31
 32  task type Largest_Factor ( To_Factorize: Long_Integer );
 33  task body Largest_Factor is
 34    Largest_Found: Long_Integer := 1;
 35    Search_Bound: constant Long_Integer := Long_Integer ( Ada.Numerics.Long_Elementary_Functions.Sqrt ( Long_Float ( To_Factorize ) ) ) + 1;
 36    -- conversion from float to long_integer may cause rounding error, in which case number that would be properly factored won't be ( consider 169 )
 37    Divisor: Long_Integer := 3;
 38    Number: Long_Integer := To_Factorize;
 39  begin
 40    if Number mod 2 = 0 then
 41      Largest_Found := 2;
 42    end if;
 43    while Number mod 2 = 0 loop
 44      Number := Number / 2;
 45    end loop;
 46    -- check for divisibility by 2
 47    while Divisor < Search_Bound and then Number /= 1 loop
 48      if Number mod Divisor = 0 then
 49        if Divisor > Largest_Found then
 50          Largest_Found := Divisor;
 51        end if;
 52        -- factor may be bigger than the one previously found
 53        while Number mod Divisor = 0 loop
 54          Number := Number / Divisor;
 55        end loop;
 56        -- number may be factored even many times by given factor, not factoring may result in false result ( consider 27 )
 57      end if;
 58      -- number was checked given ( possible ) factor so move on next
 59      Divisor := Divisor + 2;
 60    end loop;
 61    -- factorize ( trial division )
 62    if Number > Largest_Found then
 63      Largest_Found := Number;
 64    end if;
 65    -- it may be possible that to_factorize is prime number in which case it itself is the largest factor ( consider 13 )
 66    -- it may be also possible that it was coprime ( consider 26 )
 67    Terminal.Write_Line ( "Largest factor of " & To_Factorize'img & " is " & Largest_Found'img ); 
 68    Ada.Task_Identification.Abort_Task ( Ada.Task_Identification.Current_Task );
 69  end Largest_Factor;
 70
 71  function Create ( To_Factorize: in Long_Integer ) return access Largest_Factor is
 72  begin
 73    return new Largest_Factor ( To_Factorize => To_Factorize );
 74  end Create;
 75
 76  type Factorizing_Array is array ( Integer range <> ) of access Largest_Factor;
 77  Factorizers: Factorizing_Array ( 1 .. Argc );
 78
 79  task type Creator;
 80  task body Creator is
 81    To_Factorize: Long_Integer;
 82  begin
 83    if Argc = 0 then
 84      Terminal.Write_Line ( "Usage: " & Ada.Command_Line.Command_Name & " [int] ... " );
 85      Ada.Task_Identification.Abort_Task ( Ada.Task_Identification.Current_Task );
 86    else
 87      for Index in 1 .. Argc loop
 88        To_Factorize := Long_Integer'Value ( Ada.Command_Line.Argument ( Index ) );
 89        Factorizers ( Index ) := Create ( To_Factorize => To_Factorize );
 90      end loop;
 91    end if;
 92  exception
 93    when Ada.IO_Exceptions.Data_Error => Terminal.Write_Line ( "One of arguments was too big. Aborting. Aborting." );
 94  end Creator;
 95
 96  God: Creator;
 97  -- devil: destructor;
 98
 99begin
100  null;
101end Euler003;