简体   繁体   中英

Draw a ruler by writing a recursive program (Ada)

By using recursion, I need to write a program that allows the user to write how many sections and how long each section of the ruler should be. And then, based on that information, the program should be able to display the ruler that the user wants. In my code, I have managed to display the size of the ruler. However, I have some difficulty, writing a recursion that displays the length of each section. It seems like my second function (function Count) is somehow invisible because it does not affect the code, whether it exists or not.

with Ada.Text_IO;                    use Ada.Text_IO;
with Ada.Integer_Text_IO;            use Ada.Integer_Text_IO;

 Procedure Ruler is
  section, length,Y: Positive;

  function Factorial(value, value1: Natural) return Natural is   --length of 
 begin                                                           --the ruler   
  Put("|");
  if value > 1 then
  return Factorial((value * value1)-1,1);
  end if; 
  end Factorial;

  function Count(value,value1: Natural) return natural is   --Length of each 
  Calc: Natural;                                            --section     
begin
  Calc:= (value*value1)/value;    
  Set_Col(Positive_Count(Calc));
  Put("|");
  return Count(1, calc+value1); 
  end Count;   
begin
 Put("The number of sections and the length of each section: ");
 Get(section); Get(length);
 Y:= Factorial(section, length);
 Y:= Count(section, length);
 end Ruler; 

Here is a picture of a ruler with 4 sections and each section is 10 cm long: 在此处输入图片说明

So, I'm not sure why recursion is required, but below is an example that does the job. I must admit that it's not the most simple piece of code. The recursion is only a small portion of the code (see the Put_Rec function).

rulers.ads

package Rulers is

   procedure Put_Ruler (Length, Minor_Tick, Major_Tick : Positive);
   --  Draws a ruler of a given length.

end Rulers;

rulers.adb

with Ada.Strings.Fixed;
with Ada.Text_IO;        
with Ada.Integer_Text_IO;

package body Rulers is
   
   type On_Step_Fcn is access procedure (Buffer : out String; 
                                         Count  : Natural);
      
   --------------------
   -- Put_Ruler_Part --
   --------------------
      
   procedure Put_Ruler_Part 
     (Step     : Integer;
      Last     : Integer;
      On_First : String;
      On_Step  : On_Step_Fcn;
      On_Last  : String)
   is      
      use Ada.Text_IO;
      
      procedure Put_Rec (Count : Natural) is
         Buffer : String (1 .. Step);
      begin
         if Count <= Last then         --  Check continuation predicate.
            On_Step (Buffer, Count);
            Put (Buffer);
            Put_Rec (Count + Step);    --  Recurse.
         end if;
      end Put_Rec;
     
   begin      
      Put (On_First);
      Put_Rec (Step);                  --  Initiate recursion.
      Put (On_Last);
      New_Line;
   end Put_Ruler_Part;      
      
   
   ---------------------
   --  Step functions --
   ---------------------

   --  Functions that will be called on each recursion. The size of the 
   --  buffer is dictated by the (step-size known by the) calling function.

   use Ada.Strings;
   use Ada.Strings.Fixed;
      
   procedure Image_Minor_Tick (Buffer : out String; Count : Natural) is
      pragma Unreferenced (Count);
   begin
      Move ("|", Buffer, Justify => Right);
   end Image_Minor_Tick;
   
      
   procedure Image_Major_Tick (Buffer : out String; Count : Natural) is
      pragma Unreferenced (Count);
   begin
      Move ("|", Buffer, Justify => Right);
   end Image_Major_Tick;
            
      
   procedure Image_Number (Buffer : out String; Count : Natural) is 
   begin
      Move (Count'Image, Buffer, Justify => Right, Drop => Left);
   end Image_Number;
   
   
   ---------------
   -- Put_Ruler --
   ---------------
   
   procedure Put_Ruler (Length, Minor_Tick, Major_Tick : Positive) is
   begin
      
      --  Minor scale.
      Put_Ruler_Part
        (Step     => Minor_Tick,
         Last     => Length,
         On_First => "|",
         On_Step  => Image_Minor_Tick'Access,
         On_Last  => "");        
        
      --  Major scale.
      Put_Ruler_Part
        (Step     => Major_Tick,
         Last     => Length,
         On_First => "|",
         On_Step  => Image_Major_Tick'Access,
         On_Last  => "");
      
      --  Numbers.
      Put_Ruler_Part
        (Step     => Major_Tick,
         Last     => Length,
         On_First => "0",
         On_Step  => Image_Number'Access,
         On_Last  => " cm");
      
   end Put_Ruler;

end Rulers;

main.adb

with Ada.Text_IO; use Ada.Text_IO;
with Rulers;      use Rulers;

procedure Main is
begin

   Rulers.Put_Ruler
     (Length     => 40,
      Minor_Tick => 1,
      Major_Tick => 10);
   New_Line;

   Rulers.Put_Ruler
     (Length     => 40,
      Minor_Tick => 2,
      Major_Tick => 5);
   New_Line;

   Rulers.Put_Ruler
     (Length     => 40,
      Minor_Tick => 1,
      Major_Tick => 1);
   New_Line;

end Main;

output

|||||||||||||||||||||||||||||||||||||||||
|         |         |         |         |
0        10        20        30        40 cm

| | | | | | | | | | | | | | | | | | | | |
|    |    |    |    |    |    |    |    |
0    5   10   15   20   25   30   35   40 cm

|||||||||||||||||||||||||||||||||||||||||
|||||||||||||||||||||||||||||||||||||||||
01234567890123456789012345678901234567890 cm

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM