/*REXX program finds and displays  N  number of anti-primes or highly-composite numbers.*/
parse arg N .                                    /*obtain optional argument from the CL.*/
if N=='' | N==","  then N= 20                    /*Not specified?  Then use the default.*/
maxD= 0                                          /*the maximum number of divisors so far*/
say '-index- --anti-prime--'                     /*display a title for the numbers shown*/
#= 0                                             /*the count of anti-primes found  "  " */
     do once=1  for 1
        do i=1  for 59                           /*step through possible numbers by twos*/
        d= #divs(i);  if d<=maxD  then iterate   /*get # divisors;  Is too small?  Skip.*/
        #= # + 1;     maxD= d                    /*found an anti-prime #;  set new minD.*/
        say center(#, 7)  right(i, 10)           /*display the index and the anti-prime.*/
        if #>=N  then leave once                 /*if we have enough anti-primes, done. */
        end   /*i*/

        do j=60  by 20                           /*step through possible numbers by 20. */
        d= #divs(j);  if d<=maxD  then iterate   /*get # divisors;  Is too small?  Skip.*/
        #= # + 1;     maxD= d                    /*found an anti-prime #;  set new minD.*/
        say center(#, 7)  right(j, 10)           /*display the index and the anti-prime.*/
        if #>=N  then leave once                 /*if we have enough anti-primes, done. */
        end   /*j*/
     end      /*once*/
exit
/*--------------------------------------------------------------------------------------*/
#divs: procedure; parse arg x 1 y                /*X and Y:  both set from 1st argument.*/
       if x<3   then return x                    /*handle special cases for one and two.*/
       if x==4  then return 3                    /*   "      "      "   "  four.        */
       if x<6   then return 2                    /*   "      "      "   "  three or five*/
       odd= x // 2                               /*check if   X   is  odd  or not.      */
       if odd  then do;  #= 1;             end   /*Odd?   Assume  Pdivisors  count of 1.*/
               else do;  #= 3;    y= x%2;  end   /*Even?     "        "        "    " 3.*/
                                                 /* [?]   start with known num of Pdivs.*/
                  do k=3  for x%2-3  by 1+odd  while k<y  /*for odd numbers, skip evens.*/
                  if x//k==0  then do            /*if no remainder, then found a divisor*/
                                   #=#+2;  y=x%k /*bump  #  Pdivs,  calculate limit  Y. */
                                   if k>=y  then do;  #= #-1;  leave;  end      /*limit?*/
                                   end                                          /*  ___ */
                              else if k*k>x  then leave        /*only divide up to v x  */
                  end   /*k*/                    /* [?]  this form of DO loop is faster.*/
       return #+1                                /*bump "proper divisors" to "divisors".*/