Pythagorean quadruples

Revision as of 01:47, 11 July 2017 by rosettacode>Gerard Schildberger (added a new draft task, along with two REXX solutions (entries).)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)


One form of   Pythagorean quadruples   is   (for positive integers   a,   b,   c,   and   d):

Pythagorean quadruples 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.


  a2   +   b2   +   c2     =     d2


Task

For positive integers up   2,200   (inclusive),   for all values of   a,   b,   and   c,
find   (and show here)   those values of   d   that   can't   be represented.

Show the values of   d   on one line of output   (optionally with a title).

REXX

brute force

This version is a brute force algorithm, with some optimization (to save compute time)
which pre-computes the squares of the positive integers used in the search. <lang rexx>/*REXX program computes/displays integers that aren't possible for: a² + b² + c² = d² */ parse arg hi . /*obtain optional argument from the CL.*/ if hi== | hi=="," then hi=2200 /*Not specified? Then use the default.*/ @.=. /*array of integers to be squared. */ !.=. /* " " " squared. */

      do j=1  for hi**2 + (hi-2)**2 + (hi-3)**2 /*precompute possible squares (to max).*/
      jj=j*j;   !.jj=j;   if j<=hi  then @.j=jj /*define a square; D  value; squared # */
      end   /*j*/

d.=. /*array of possible solutions (D) */

      do     a=1  for hi-2                      /*go hunting for solutions to equation.*/
         do   b=a   to hi-1;    ab = @.a + @.b  /*calculate sum of  2  (A,B)   squares.*/
            do c=b   to hi;     abc= ab  + @.c  /*    "      "   "  3  (A,B,C)    "    */
            if !.abc==.  then iterate           /*Not a (perfect) square? Then skip it.*/
            s=!.abc;            d.s=            /*define this D solution as being found*/
            end   /*c*/
         end      /*b*/
      end         /*a*/

say say 'Not possible positive integers for d ≤' hi " using equation: a² + b² + c² = d²" say $= /* [↓] find all the "not possibles". */

      do p=1  for hi;   if d.p==.  then $=$ p   /*Not possible? Then add it to the list*/
      end   /*p*/                               /* [↓]  display list of not-possibles. */

say substr($, 2) /*stick a fork in it, we're all done. */</lang>

output   when using the default input:
Not possible positive integers for   d ≤ 2200   using equation:  a² + b² + c²  =  d²

1 2 4 5 8 10 16 20 32 40 64 80 128 160 256 320 512 640 1024 1280 2048

optimized

This REXX version is an optimized version, it solves the formula:

  a2   +   b2     =     d2   -   c2

This REXX version is over thirty times faster then the previous version. <lang rexx>/*REXX program computes/displays integers that aren't possible for: a² + b² + c² = d² */ parse arg hi . /*obtain optional argument from the CL.*/ if hi== | hi=="," then hi=2200 /*Not specified? Then use the default.*/ high=hi * 3 /*D can be three times the HI (max).*/ @.=. /*array of integers to be squared. */ !.=. /* " " " squared. */ dbs.=. /* differences between squares.*/

      do s=1  for high                          /*process up to three times the maximum*/
      ss=s*s;   r.ss=s                          /*precompute squares and square roots. */
      if s<=hi  then @.s=ss                     /*only define    @.s   if within range.*/
      end  /*s*/
      do    c=1   for high;     cc=c*c          /*precompute possible differences.     */
         do d=c+1  to high;     dif=d*d - cc    /*process  D  squared; calc differences*/
         if dbs.dif==.  then do;  dbs.dif=cc;  iterate;  end    /*No list yet?  Add it.*/
         if wordpos(cc,dbs.dif)==0  then dbs.dif=dbs.dif cc     /*Not in list?  Add it.*/
         end   /*d*/
      end      /*c*/

d.=. /*array of possible solutions (D) */

      do     a=1  for hi-2                      /*go hunting for solutions to equation.*/
         do   b=a   to hi-1;     ab=@.a + @.b   /*calculate sum of  2  (A,B)   squares.*/
         if dbs.ab==.  then iterate             /*Not a difference?   Then ignore it.  */
            do n=1  for words(dbs.ab)           /*handle all ints that satisfy equation*/
            x=word(dbs.ab, n)                   /*get a C integer from the DBS.AB list.*/
            abc=ab + x                          /*add the  C²  integer  to  A²  +  B²  */
            _=r.abc                             /*retrieve the square root  of  C²     */
            d._=                                /*mark the  D  integer as being found. */
            end   /*n*/
         end      /*b*/
      end         /*a*/

say say 'Not possible positive integers for d ≤' hi " using equation: a² + b² + c² = d²" say $= /* [↓] find all the "not possibles". */

      do p=1  for hi;   if d.p==.  then $=$ p   /*Not possible? Then add it to the list*/
      end   /*p*/                               /* [↓]  display list of not-possibles. */

say substr($, 2) /*stick a fork in it, we're all done. */</lang>

output   is the same as the 1st REXX version.