PageRenderTime 33ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/euler003/Euler003.adb

http://github.com/darkestkhan/project_euler
Ada | 101 lines | 65 code | 7 blank | 29 comment | 9 complexity | 65ba66094cb60652a622d7ac3fa0ecfa MD5 | raw file
  1. pragma 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. ------------------------------------------------------------------------------
  22. with TTY;
  23. with Ada.Numerics.Long_Elementary_Functions;
  24. with Ada.Command_Line;
  25. with Ada.Task_Identification;
  26. with Ada.IO_Exceptions;
  27. procedure Euler003 is
  28. Argc: constant Integer := Ada.Command_Line.Argument_Count;
  29. Terminal: TTY.TTY;
  30. task type Largest_Factor ( To_Factorize: Long_Integer );
  31. task body Largest_Factor is
  32. Largest_Found: Long_Integer := 1;
  33. Search_Bound: constant Long_Integer := Long_Integer ( Ada.Numerics.Long_Elementary_Functions.Sqrt ( Long_Float ( To_Factorize ) ) ) + 1;
  34. -- conversion from float to long_integer may cause rounding error, in which case number that would be properly factored won't be ( consider 169 )
  35. Divisor: Long_Integer := 3;
  36. Number: Long_Integer := To_Factorize;
  37. begin
  38. if Number mod 2 = 0 then
  39. Largest_Found := 2;
  40. end if;
  41. while Number mod 2 = 0 loop
  42. Number := Number / 2;
  43. end loop;
  44. -- check for divisibility by 2
  45. while Divisor < Search_Bound and then Number /= 1 loop
  46. if Number mod Divisor = 0 then
  47. if Divisor > Largest_Found then
  48. Largest_Found := Divisor;
  49. end if;
  50. -- factor may be bigger than the one previously found
  51. while Number mod Divisor = 0 loop
  52. Number := Number / Divisor;
  53. end loop;
  54. -- number may be factored even many times by given factor, not factoring may result in false result ( consider 27 )
  55. end if;
  56. -- number was checked given ( possible ) factor so move on next
  57. Divisor := Divisor + 2;
  58. end loop;
  59. -- factorize ( trial division )
  60. if Number > Largest_Found then
  61. Largest_Found := Number;
  62. end if;
  63. -- it may be possible that to_factorize is prime number in which case it itself is the largest factor ( consider 13 )
  64. -- it may be also possible that it was coprime ( consider 26 )
  65. Terminal.Write_Line ( "Largest factor of " & To_Factorize'img & " is " & Largest_Found'img );
  66. Ada.Task_Identification.Abort_Task ( Ada.Task_Identification.Current_Task );
  67. end Largest_Factor;
  68. function Create ( To_Factorize: in Long_Integer ) return access Largest_Factor is
  69. begin
  70. return new Largest_Factor ( To_Factorize => To_Factorize );
  71. end Create;
  72. type Factorizing_Array is array ( Integer range <> ) of access Largest_Factor;
  73. Factorizers: Factorizing_Array ( 1 .. Argc );
  74. task type Creator;
  75. task body Creator is
  76. To_Factorize: Long_Integer;
  77. begin
  78. if Argc = 0 then
  79. Terminal.Write_Line ( "Usage: " & Ada.Command_Line.Command_Name & " [int] ... " );
  80. Ada.Task_Identification.Abort_Task ( Ada.Task_Identification.Current_Task );
  81. else
  82. for Index in 1 .. Argc loop
  83. To_Factorize := Long_Integer'Value ( Ada.Command_Line.Argument ( Index ) );
  84. Factorizers ( Index ) := Create ( To_Factorize => To_Factorize );
  85. end loop;
  86. end if;
  87. exception
  88. when Ada.IO_Exceptions.Data_Error => Terminal.Write_Line ( "One of arguments was too big. Aborting. Aborting." );
  89. end Creator;
  90. God: Creator;
  91. -- devil: destructor;
  92. begin
  93. null;
  94. end Euler003;