RosettaCodeData/Task/Self-referential-sequence/Ada/self-referential-sequence.ada

63 lines
1.9 KiB
Ada

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Containers.Vectors;
procedure SelfRef is
subtype Seed is Natural range 0 .. 1_000_000;
subtype Num is Natural range 0 .. 10;
type NumList is array (0 .. 10) of Num;
package IO is new Ada.Text_IO.Integer_IO (Natural);
package DVect is new Ada.Containers.Vectors (Positive, NumList);
function Init (innum : Seed) return NumList is
list : NumList := (others => 0);
number : Seed := innum; d : Num;
begin
loop
d := Num (number mod 10);
list (d) := list (d) + 1;
number := number / 10; exit when number = 0;
end loop; return list;
end Init;
procedure Next (inoutlist : in out NumList) is
list : NumList := (others => 0);
begin
for i in list'Range loop
if inoutlist (i) /= 0 then
list (i) := list (i) + 1;
list (inoutlist (i)) := list (inoutlist (i)) + 1;
end if;
end loop; inoutlist := list;
end Next;
procedure Show (list : NumList) is begin
for i in reverse list'Range loop
if list (i) > 0 then
IO.Put (list (i), Width => 1); IO.Put (i, Width => 1);
end if;
end loop; New_Line;
end Show;
function Iterate (theseed : Seed; p : Boolean) return Natural is
list : NumList := Init (theseed);
vect : DVect.Vector;
begin
vect.Append (list);
loop
if p then Show (list); end if;
Next (list); exit when vect.Contains (list); vect.Append (list);
end loop;
return Integer (DVect.Length (vect)) + 1;
end Iterate;
mseed : Seed;
len, maxlen : Natural := 0;
begin
for i in Seed'Range loop
len := Iterate (i, False);
if len > maxlen then mseed := i; maxlen := len; end if;
end loop;
IO.Put (maxlen, Width => 1); Put_Line (" Iterations:");
IO.Put (mseed, Width => 1); New_Line;
len := Iterate (mseed, True);
end SelfRef;