An aliquot sequence of a positive integer K is defined recursively as the first member
being K and subsequent members being the sum of the Proper divisors of the previous term.

 If the terms eventually reach 0 then the series for K is said to terminate.

There are several classifications for non termination:
 If the second term is K then all future terms are also K and so the sequence repeats from the first term with period 1 and K is called perfect.
 If the third term would be repeating K then the sequence repeats with period 2 and K is called amicable.
 If the Nth term would be repeating K for the first time, with N > 3 then the sequence repeats with period N - 1 and K is called sociable.

Perfect, amicable and sociable numbers eventually repeat the original number K; there are other repetitions...
 Some K have a sequence that eventually forms a periodic repetition of period 1 but of a number other than K, for example 95 which forms the sequence 95, 25, 6, 6, 6, ... such K are called aspiring.
 K that have a sequence that eventually forms a periodic repetition of period >= 2 but of a number other than K, for example 562 which forms the sequence 562, 284, 220, 284, 220, ... such K are called cyclic.

And finally:
 Some K form aliquot sequences that are not known to be either terminating or periodic; these K are to be called non-terminating. 
For the purposes of this task, K is to be classed as non-terminating if it has not been otherwise classed after generating 16 terms or if any term of the sequence is greater than 2**47 = 140,737,488,355,328. 


Task

 Create routine(s) to generate the aliquot sequence of a positive integer enough to classify it according to the classifications given above.
 Use it to display the classification and sequences of the numbers one to ten inclusive.
 Use it to show the classification and sequences of the following integers, in order:
 11, 12, 28, 496, 220, 1184, 12496, 1264460, 790, 909, 562, 1064, 1488, and optionally 15355717786080.
Show all output on this page.



Related tasks

   Abundant, deficient and perfect number classifications. (Classifications from only the first two members of the whole sequence).
   Proper divisors
   Amicable pairs


BEGIN
    # aliquot sequence classification                                         #
    # maximum sequence length we consider                                     #
    INT max sequence length = 16;
    # possible classifications                                                #
    STRING         perfect classification    = "perfect        ";
    STRING        amicable classification    = "amicable       ";
    STRING        sociable classification    = "sociable       ";
    STRING        aspiring classification    = "aspiring       ";
    STRING          cyclic classification    = "cyclic         ";
    STRING     terminating classification    = "terminating    ";
    STRING non terminating classification    = "non terminating";
    # structure to hold an aliquot sequence and its classification            #
    MODE ALIQUOT = STRUCT( STRING                              classification
                         , [ 1 : max sequence length ]LONG INT sequence
                         , INT                                 length
                         );
    # maximum value for sequence elements - if any element is more than this, #
    # we assume it is non-teriminating                                        #
    LONG INT max element = 140 737 488 355 328;
    # returns the sum of the proper divisors of n                             #
    OP DIVISORSUM = ( LONG INT n )LONG INT:
       BEGIN
            LONG INT abs n = ABS n;
            IF abs n < 2 THEN
                0 # -1, 0 and 1 have no proper divisors                       #
            ELSE
                # have a number with possible divisors                        #
               LONG INT result := 1; # 1 is always a divisor                  #
               # a FOR loop counter can only be an INT, hence the WHILE loop  #
               LONG INT d      := ENTIER long sqrt( abs n );
               WHILE d > 1 DO
                   IF abs n MOD d = 0 THEN
                       # found another divisor                                #
                       result +:= d;
                       IF d * d /= abs n THEN
                           # add the other divisor                            #
                           result +:= abs n OVER d
                       FI
                   FI;
                   d -:= 1
               OD;
               result
            FI
       END # DIVISORSUM # ;
    # generates the aliquot sequence of the number k and its classification   #
    # at most max elements of the sequence are considered                     #
    OP CLASSIFY = ( LONG INT k )ALIQUOT :
       BEGIN
           ALIQUOT result;
           classification OF result := "non-terminating";
           INT lb = LWB sequence OF result;
           INT ub = UPB sequence OF result;
           ( sequence OF result )[ lb ] := k; # the first element is always k #
           length     OF result         := 1;
           FOR i FROM lb + 1 TO ub DO
               ( sequence OF result )[ i ] := 0
           OD;
           BOOL classified := FALSE;
           LONG INT prev k := k;
           FOR i FROM lb + 1 TO ub WHILE NOT classified DO
               length OF result +:= 1;
               LONG INT next k := ( sequence OF result )[ i ] := DIVISORSUM prev k;
               classified := TRUE;
               IF   next k = 0 THEN # the sequence terminates                 #
                    classification OF result := terminating classification
               ELIF next k > max element THEN # the sequence gets too large   #
                    classification OF result := non terminating classification
               ELIF next k = k THEN # the sequence that returns to k          #
                   classification OF result
                       := IF   i = lb + 1 THEN  perfect classification
                          ELIF i = lb + 2 THEN amicable classification
                          ELSE                 sociable classification
                          FI
               ELIF next k = prev k THEN # the sequence repeats with non-k    #
                   classification OF result := aspiring classification
               ELSE # check for repeating sequence with a period more than 1  #
                   classified := FALSE;
                   FOR prev pos FROM lb TO i - 2 WHILE NOT classified DO
                       IF classified := ( sequence OF result )[ prev pos ] = next k THEN
                           # found a repeatition                              #
                           classification OF result := cyclic classification
                       FI
                   OD
               FI;
               prev k := next k
           OD;
           result
       END # CLASSIFY # ;
    # test cases as per the task                                              #
    []LONG INT test cases =
        (   1,    2,   3,   4,   5,    6,     7,       8,   9,  10
        ,  11,   12,  28, 496, 220, 1184, 12496, 1264460, 790, 909
        , 562, 1064, 1488
        ,  15355717786080
        );
    FOR i FROM LWB test cases TO UPB test cases DO
        LONG INT k   := test cases[ i ];
        ALIQUOT  seq  = CLASSIFY k;
        print( ( whole( k, -14 ), ": ", classification OF seq, ":" ) );
        FOR e FROM LWB sequence OF seq + 1 TO length OF seq DO
            print( ( " ", whole( ( sequence OF seq )[ e ], 0 ) ) )
        OD;
        print( ( newline ) )
    OD
END