Pythagorean quadruples: Difference between revisions

From Rosetta Code
Content added Content deleted
(Added Kotlin)
m (→‎{{header|Kotlin}}: added C header)
Line 29: Line 29:
*   [[Euler's sum of powers conjecture]].
*   [[Euler's sum of powers conjecture]].
<br><br>
<br><br>

=={{header|C}}==
<lang C></lang>
{{out}}
<pre>
</pre>


=={{header|Kotlin}}==
=={{header|Kotlin}}==

Revision as of 15:12, 12 July 2017

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.


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


  a2   +   b2   +   c2     =     d2


An example:

  22   +   32   +   62     =     72
which is:
  4   +   9   +   36     =     49


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).


Related task



C

<lang C></lang>

Output:

Kotlin

This uses a similar approach to the REXX optimized version. Runs in about 8 seconds on my modest laptop which is about 4 times as fast as the brute force version would have been: <lang scala>// version 1.1.3

const val MAX = 2200 const val MAX2 = MAX * MAX - 1

fun main(args: Array<String>) {

   val found = BooleanArray(MAX + 1)       // all false by default
   val p2 = IntArray(MAX + 1) { it * it }  // pre-compute squares
   // compute all possible positive values of d * d - c * c and map them back to d
   val dc = mutableMapOf<Int, MutableList<Int>>()
   for (d in 1..MAX) {
       for (c in 1 until d) {
           val diff = p2[d] - p2[c]              
           val v = dc[diff]
           if (v == null)
               dc.put(diff, mutableListOf(d))
           else if (d !in v)
               v.add(d)
       }
   }
 
   for (a in 1..MAX) {
       for (b in 1..a) {
           val sum = p2[a] + p2[b]
           if (sum > MAX2) continue
           val v = dc[sum]
           if (v != null) v.forEach { found[it] = true }
       }
   }
   println("The values of d <= $MAX which can't be represented:")
   for (i in 1..MAX) if (!found[i]) print("$i ")
   println()

}</lang>

Output:
The values of d <= 2200 which can't be represented:
1 2 4 5 8 10 16 20 32 40 64 80 128 160 256 320 512 640 1024 1280 2048 

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.