Rare numbers

Revision as of 12:47, 8 September 2019 by rosettacode>Gerard Schildberger (added a new task: rare numbers, also added a REXX computer programming entry for this task.)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Rare   numbers are positive integers   n   where:

Rare numbers is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
Definitions and restrictions
  •   n   is expressed in base ten
  •   n   must be non-palindromic   ( n   ≠   r)
  •   r   is the reverse of   n     (decimal digits)
  •   (n+r)   is the   sum
  •   (n-r)   is the   difference   and must be positive
  •   the   sum   and the   difference   must be perfect squares


Task
  •   find and show the first   5   rare   numbers
  •   find and show the first   6   rare   numbers       (optional)
  •   find and show more   rare   numbers                (stretch goal)


Show all output here, on this page.


References




REXX

<lang rexx>/*REXX program to calculate and display an specified amount of rare numbers. */ numeric digits 20; w= digits() + digits() % 3 /*ensure enough decimal digs for calcs.*/ parse arg many start . /*obtain optional argument from the CL.*/ if many== | many=="," then many= 5 /*Not specified? Then use the default.*/

@dr.=0; @dr.2= 1; @dr.5=1 ; @dr.8= 1; @dr.9= 1 /*rare # must have these digital roots.*/ @ps.=0; @ps.2= 1; @ps.3= 1; @ps.7= 1; @ps.8= 1 /*perfect squares must end in these.*/ @end.=0; @end.1=1; @end.4=1; @end.6=1; @end.9=1 /*rare # must not end in these digits.*/ @dif.=0; @dif.2=1; @dif.3=1; @dif.7=1; @dif.8=1; @dif.9=1 /* A─Q must'nt be these digs.*/ @noq.=0; @noq.0=1; @noq.1=1; @noq.4=1; @noq.5=1; @noq.6=1; @noq.9=1 /*A=8, Q must'nt be*/ @149.=0; @149.1=1; @149.4=1; @149.9=1 /*values for Z that need a even Y. */

  1. = 0 /*the number of rare numbers (so far)*/

@n05.=0; do i= 1 to 9; if i==0 | i==5 then iterate; @n05.i= 1; end /*¬1 ¬5*/ @eve.=0; do i=-8 by 2 to 8; @eve.i=1; end /*define even " some are negative.*/ @odd.=0; do i=-9 by 2 to 9; @odd.i=1; end /* " odd " " " " */

                                                /*N=10, 'cause 1 dig #s are palindromic*/
   do n=10;  parse var  n  a 2 b 3  -2 p +1 q /*get 1st\2nd\penultimate\last digits. */
   if @end.q  then iterate                      /*rare numbers can't end in: 1 4 6 or 9*/
   if q==3    then iterate
      select                                    /*weed some integers based on 1st digit*/
      when a==q  then do
                      if a==2|a==8 then nop     /*if A = Q,   then A must be  2  or 8. */
                                   else iterate /*A  not two or eight?       Then skip.*/
                      if b\==p  then iterate    /*B  not equal to  P?        Then skip.*/
                      end
      when a==2  then do; if q\==2 then iterate /*A = 2?     Then  Q  must also be  2. */
                          if b\==p then iterate /*" " "      Then  B  must equal    P. */
                 end
      when a==4  then do
                      if q\==0   then iterate   /*if Q not equal to zero, then skip it.*/
                      _= b - p                  /*calculate difference between B and P.*/
                      if @eve._  then iterate   /*Positive not even?      Then skip it.*/
                      end
      when a==6  then do
                      if @n05.q  then iterate   /*Q  not a zero or five?  Then skip it.*/
                      _= b - p                  /*calculate difference between B and P.*/
                      if @eve._  then iterate
                      end
      when a==8  then do
                      if @noq.q  then iterate   /*Q  isn't one of 2, 3, 7, 8?  Skip it.*/
                        select
                        when q==2  then            if b+p\==9                then iterate
                        when q==3  then do; if b>p         then if b-p\== 7  then iterate

else if b

1 then if b+p\==11 then iterate else if b==0 then if b+p\== 1 then iterate end when q==8 then if b\==p then iterate otherwise nop end /*select*/ end /* [↓] A is an odd digit. */ otherwise n= n + 10**(length(n) - 1) - 1 /*bump N so next N starts with even dig*/ iterate /*Now, go and use the next value of N.*/ end /*select*/ _= a - q; if @dif._ then iterate /*diff of A─Q must be: 0, 1, 4, 5, or 6*/ r= reverse(n) /*obtain the reverse of the number N. */ if r>n then iterate /*Difference will be negative? Skip it*/ if n==r then iterate /*Palindromic? Then it can't be rare.*/ d= n-r; parse var d -2 y +1 z /*obtain the last 2 digs of difference.*/ if @ps.z then iterate /*Not 0, 1, 4, 5, 6, 9? Not perfect sq.*/ select when z==0 then if y\==0 then iterate /*Does Z = 0? Then Y must be zero. */ when z==5 then if y\==2 then iterate /*Does Z = 5? Then Y must be two. */ when z==6 then if y//2==0 then iterate /*Does Z = 6? Then Y must be odd. */ otherwise if @149.z then if y//2 then iterate /*Z=1,4,9? Y must be even*/ end /*select*/ s= n+r; parse var s -2 y +1 z /*obtain the last two digits of the sum*/ if @ps.z then iterate /*Not 0, 2, 5, 8, or 9? Not perfect sq.*/ select when z==0 then if y\==0 then iterate /*Does Z = 0? Then Y must be zero. */ when z==5 then if y\==2 then iterate /*Does Z = 5? Then Y must be two. */ when z==6 then if y//2==0 then iterate /*Does Z = 6? Then Y must be odd. */ otherwise if @149.z then if y//2 then iterate /*Z=1,4,9? Y must be even*/ end /*select*/ $= a + b /*a head start on figuring digital root*/ do k=3 for length(n) - 2 /*now, process the rest of the digits. */ $= $ + substr(n, k, 1) /*add the remainder of the digits in N.*/ end /*k*/ /*This REXX pgm uses 20 decimal digits.*/ do while $>9 /* [◄] Algorithm is good for 111 digs.*/ if $>9 then $= left($,1) + substr($,2,1)+ substr($,3,1,0) /*>9? Reduce to a dig*/ end /*while*/ if \@dr.$ then iterate /*Doesn't have good digital root? Skip*/ if iSqrt(s)**2 \== s then iterate /*Not a perfect square? Then skip it. */ if iSqrt(d)**2 \== d then iterate /* " " " " " " " */ #= # + 1 /*bump the counter of rare numbers. */ say right( th(#), length(#) + 9) ' rare number is: ' right( commas(n), w) if #>=many then leave /* [↑] W: the width of # with commas.*/ end /*n*/ exit /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ commas: parse arg _; do jc=length(_)-3 to 1 by -3; _=insert(',', _, jc); end; return _ th: parse arg th;return th||word('th st nd rd',1+(th//10)*(th//100%10\==1)*(th//10<4)) /*──────────────────────────────────────────────────────────────────────────────────────*/ iSqrt: parse arg x; $= 0; q= 1; do while q<=x; q= q*4 end /*while q<=x*/ do while q>1; q= q % 4; _= x-$-q; $= $ % 2 if _>=0 then do; x= _; $= $ + q end end /*while q>1*/; return $</lang>

output   when using the input of:     8
       1st  rare number is:                           65
       2nd  rare number is:                      621,770
       3rd  rare number is:                  281,089,082
       4th  rare number is:                2,022,652,202
       5th  rare number is:                2,042,832,002
       6th  rare number is:              868,591,084,757
       7th  rare number is:              872,546,974,178
       8th  rare number is:              872,568,754,178