Maximum difference between adjacent elements of list

Revision as of 22:41, 18 July 2021 by Wherrera (talk | contribs) (→‎{{header|Julia}}: expand types)

Find maximum difference between adjacent elements of list.

Maximum difference between adjacent elements of list 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.
Task

The list may have negative values, zero values, real numbers.


List   =   [1,8,2,-3,0,1,1,-2.3,0,5.5,8,6,2,9,11,10,3]


Output would be   (could have more verbiage):

  2,9 ==> 7
  1,8 ==> 7
  10,3 ==> 7



ALGOL 68

<lang algol68>BEGIN # find the maximum difference between consecutive list elements #

   # returns the maximum difference between pairs of elements of list        #
   OP   MAXDELTA = ( []REAL list )REAL:
        BEGIN
           REAL max diff := 0;
           FOR i FROM LWB list TO UPB list - 1 DO
               REAL delta = ABS ( list[ i ] - list[ i + 1 ] );
               IF delta > max diff THEN
                   max diff := delta # found a higher difference             #
               FI
           OD;
           max diff
        END; # MAXDELTA #
   # returns r converted to a string with trailing 0 decimal places removed  #
   OP   TOSTRING = ( REAL r )STRING:
        BEGIN
           STRING result  := fixed( r, 0, 10 );
           IF result[ LWB result ] = "." THEN result := "0" + result FI;
           INT    r end   := UPB result;
           INT    r start := LWB result;
           WHILE IF r end <= r start THEN FALSE ELSE result[ r end ] = "0" FI DO
              r end -:= 1
           OD;
           IF r end > LWB result THEN
               # if all decimal places were "0", remove the "." as well      #
               IF result[ r end ] = "." THEN r end -:= 1 FI
           FI;
           result[ r start : r end ]
        END; # TOSTRING #
   # test the MAXDELTA operator                                              #
   PROC test max delta = ( []REAL list )VOID:
        BEGIN
           REAL max diff = MAXDELTA list;
           print( ( "Max difference [" ) );
           FOR i FROM LWB list TO UPB list DO
               print( ( " ", TOSTRING list[ i ] ) )
           OD;
           print( ( " ] is ", TOSTRING max diff, ":",  newline ) );
           FOR i FROM LWB list TO UPB list - 1 DO
               IF REAL diff = ABS ( list[ i ] - list[ i + 1 ] );
                  diff = max diff
               THEN
                   print( ( "    ", TOSTRING list[ i ], ", ", TOSTRING list[ i + 1 ]
                          , " ==> ", TOSTRING diff
                          , newline
                          )
                        )
               FI
           OD
        END; # test max delta #
   # task test case                                                          #
   test max delta( ( 1, 8, 2, -3, 0, 1, 1, -2.3, 0, 5.5, 8, 6, 2, 9, 11, 10, 3 ) );
   # additional test cases                                                   #
   test max delta( ( -1.1, -1.2 ) ); test max delta( ( pi, pi, pi ) );
   test max delta( ( )            ); test max delta( ( 776.591 )    )

END</lang>

Output:
Max difference [ 1 8 2 -3 0 1 1 -2.3 0 5.5 8 6 2 9 11 10 3 ] is 7:
    1, 8 ==> 7
    2, 9 ==> 7
    10, 3 ==> 7
Max difference [ -1.1 -1.2 ] is 0.1:
    -1.1, -1.2 ==> 0.1
Max difference [ 3.1415926536 3.1415926536 3.1415926536 ] is 0:
    3.1415926536, 3.1415926536 ==> 0
    3.1415926536, 3.1415926536 ==> 0
Max difference [ ] is 0:
Max difference [ 776.591 ] is 0:

ALGOL W

<lang algolw>begin % find the maximum difference between consecutive list elements  %

   % returns the maximum difference between pairs of elements of list        %
   %         the lower and upper bounds of list must be specified in lb & ub %
   real procedure maxDelta ( real    array list ( * )
                           ; integer value lb, ub
                           ) ;
   begin
       real maxDiff;
       maxDiff := 0;
       for i := lb until ub - 1 do begin
           real delta;
           delta := abs ( list( i ) - list( i + 1 ) );
           if delta > maxDiff then maxDiff := delta % found a higher difference %
       end for_i;
       maxDiff
   end maxDelta;
   % test the maxDelta procedure                                             %
   procedure testMaxDelta ( real    array list ( * )
                          ; integer value lb, ub, rw, dp
                          ) ;
   begin
       real maxDiff;
       maxDiff := maxDelta( list, lb, ub );
       write( s_w := 0, "Max difference [" );
       for i := lb until ub do begin
           writeon( r_format := "A", r_w := rw, r_d := dp, s_w := 0, " ", list( i ) );
       end for_i;
       writeon( r_format := "A", r_w := rw, r_d := dp, s_w := 0, " ] is ", maxDiff, ":" );
       for i := lb until ub - 1 do begin
           real diff;
           diff := abs ( list( i ) - list( i + 1 ) );
           if diff = maxDiff then begin
               write( r_format := "A", r_w := rw, r_d := dp, s_w := 0, "    ", list( i ), ", ", list( i + 1 ), " ==> ", diff );
           end if_diff_eq_maxDiff
        end for_i
   end testMaxDelta;
   begin % task test case                                                    %
       integer tPos;
       real array tc( 1 :: 17 );
       tPos := 0;
       for i := 1, 8, 2, -3, 0, 1, 1, -23, 0, 55, 8, 6, 2, 9, 11, 10, 3 do begin
           tPos       := tPos + 1;
           tc( tPos ) := i
       end for_i;
       tc( 8 ) := -2.3; tc( 10 ) := 5.5;
       testMaxDelta( tc, 1, 17, 4, 1 )
   end;
   begin % additional test cases                                             %
       integer tPos;
       real array tc( 1 :: 3 );
       tc( 1 ) := -1.1; tc( 2 ) := -1.2; testMaxDelta( tc, 1, 2, 4, 1  );
       for i := 1 until 3 do tc( i ) := pi;
       testMaxDelta( tc, 1, 3, 6, 4 );
       testMaxDelta( tc, 1, 0, 3, 1 );
       tc( 1 ) := 776.591;
       testMaxDelta( tc, 1, 1, 6, 3 )
   end

end.</lang>

Output:
Max difference [  1.0  8.0  2.0 -3.0  0.0  1.0  1.0 -2.3  0.0  5.5  8.0  6.0  2.0  9.0 11.0 10.0  3.0 ] is  7.0:
     1.0,  8.0 ==>  7.0
     2.0,  9.0 ==>  7.0
    10.0,  3.0 ==>  7.0
Max difference [ -1.1 -1.2 ] is  0.1:
    -1.1, -1.2 ==>  0.1
Max difference [ 3.1416 3.1416 3.1416 ] is 0.0000:
    3.1416, 3.1416 ==> 0.0000
    3.1416, 3.1416 ==> 0.0000
Max difference [ ] is 0.0:
Max difference [ 776.591 ] is  0.000:

Factor

Works with: Factor version 0.99 2021-06-02

<lang factor>USING: assocs grouping math prettyprint sequences ;

max-diff ( seq -- assoc )
   2 clump [ first2 - abs ] collect-by >alist supremum ;

{ 1 8 2 -3 0 1 1 -2.3 0 5.5 8 6 2 9 11 10 3 } max-diff .</lang>

Output:
{ 7 V{ { 1 8 } { 2 9 } { 10 3 } } }

Go

<lang go>package main

import (

   "fmt"
   "math"

)

func main() {

   list := []float64{1, 8, 2, -3, 0, 1, 1, -2.3, 0, 5.5, 8, 6, 2, 9, 11, 10, 3}
   maxDiff := -1.0
   var maxPairs [][2]float64
   for i := 1; i < len(list); i++ {
       diff := math.Abs(list[i-1] - list[i])
       if diff > maxDiff {
           maxDiff = diff
           maxPairs = [][2]float64{{list[i-1], list[i]}}
       } else if diff == maxDiff {
           maxPairs = append(maxPairs, [2]float64{list[i-1], list[i]})
       }
   }
   fmt.Println("The maximum difference between adjacent pairs of the list is:", maxDiff)
   fmt.Println("The pairs with this difference are:", maxPairs)

}</lang>

Output:
The maximum difference between adjacent pairs of the list is: 7
The pairs with this difference are: [[1 8] [2 9] [10 3]]

Haskell

<lang haskell>import Data.List (maximumBy) import Data.Ord (comparing)

maxDeltas :: [Float] -> [(Float, (Float, Float))] maxDeltas xs = filter ((delta ==) . fst) pairs

 where
   pairs =
     zipWith
       (\a b -> (abs (a - b), (a, b)))
       xs
       (tail xs)
   delta = fst $ maximumBy (comparing fst) pairs

main :: IO () main =

 mapM_ print $
   maxDeltas [1, 8, 2, -3, 0, 1, 1, -2.3, 0, 5.5, 8, 6, 2, 9, 11, 10, 3]</lang>
Output:
(7.0,(1.0,8.0))
(7.0,(2.0,9.0))
(7.0,(10.0,3.0))

Julia

<lang julia> function maxadjacentdiffs(list)

   pairs, maxδ = Pair{eltype(list)}[], abs(zero(eltype(list)))
   for i in eachindex(list[begin:end-1])
       x, y = list[i], list[i + 1]
       if (δ = abs(x - y)) == maxδ
           push!(pairs, x => y)
       elseif δ > maxδ
           maxδ, pairs = δ, [x => y]
       end
   end
   return maxδ, pairs

end

diff, pairs = maxadjacentdiffs([1,8,2,-3,0,1,1,-2.3,0,5.5,8,6,2,9,11,10,3])

foreach(p -> println(p[1], ", ", p[2], " ==> ", diff), pairs)

</lang>

Output:
1.0, 8.0 ==> 7.0
2.0, 9.0 ==> 7.0
10.0, 3.0 ==> 7.0

Nim

<lang Nim>import strformat, strutils

type Pair = (float, float)

func `$`(p: Pair): string = &"({p[0]:g}, {p[1]:g})"

func maxdiff(list: openArray[float]): tuple[diff: float; list: seq[Pair]] =

 assert list.len >= 2
 result = (diff: -1.0, list: @[])
 var prev = list[0]
 for n in list[1..^1]:
   let d = abs(n - prev)
   if d > result.diff:
     result.diff = d
     result.list = @[(prev, n)]
   elif d == result.diff:
     result.list.add (prev, n)
   prev = n

let list = [float 1, 8, 2, -3, 0, 1, 1, -2.3, 0, 5.5, 8, 6, 2, 9, 11, 10, 3] let (diff, pairs) = list.maxdiff()

echo &"The maximum difference between adjacent pairs of the list is: {diff:g}" echo "The pairs with this difference are: ", pairs.join(" ")</lang>

Output:
The maximum difference between adjacent pairs of the list is: 7
The pairs with this difference are: (1, 8) (2, 9) (10, 3)

Phix

procedure maxdiff(sequence s)
    sequence d = sq_abs(sq_sub(s[1..-2],s[2..-1]))
    atom m = max(d)
    sequence p = find_all(m,d)
    for i=1 to length(p) do
        integer pi = p[i], pj = pi+1
        p[i] = sprintf("s[%d..%d]=%V",{pi,pj,s[pi..pj]})
    end for
    printf(1,"max difference is %g, occurring at %s\n",{m,join(p,", ")})
end procedure
maxdiff({1,8,2,-3,0,1,1,-2.3,0,5.5,8,6,2,9,11,10,3})
Output:
max difference is 7, occurring at s[1..2]={1,8}, s[13..14]={2,9}, s[16..17]={10,3}

Python

<lang python>Maximum difference between adjacent numbers in list


  1. maxDeltas [Float] -> [(Float, (Float, Float))]

def maxDeltas(ns):

   Each of the maximally differing successive pairs
      in ns, each preceded by the value of the difference.
   
   pairs = [
       (abs(a - b), (a, b)) for a, b
       in zip(ns, ns[1:])
   ]
   delta = max(pairs, key=lambda ab: ab[0])[0]
   return [
       ab for ab in pairs
       if delta == ab[0]
   ]


  1. ------------------------- TEST -------------------------
  2. main :: IO ()

def main():

   Each of the maximally differing pairs in a list
   maxPairs = maxDeltas([
       1, 8, 2, -3, 0, 1, 1, -2.3, 0,
       5.5, 8, 6, 2, 9, 11, 10, 3
   ])
   for ab in maxPairs:
       print(ab)


  1. MAIN ---

if __name__ == '__main__':

   main()</lang>
Output:
(7, (1, 8))
(7, (2, 9))
(7, (10, 3))

Raku

<lang perl6>sub max-diff (*@list) {

  return 0 if +@list < 2;
  my $max = @list.rotor(2 => -1).max({ (.[0] - .[1]).abs }).map( (* - *).abs )[0];
  "$max @ elements { @list.rotor(2 => -1).grep( { (.[0] - .[1]).abs == $max } ).gist }"

}


sub min-diff (*@list) {

  return 0 if +@list < 2;
  my $min = @list.rotor(2 => -1).min({ (.[0] - .[1]).abs }).map( (* - *).abs )[0];
  "$min @ elements { @list.rotor(2 => -1).grep( { (.[0] - .[1]).abs == $min } ).gist }"

}


sub avg-diff (*@list) { (+@list > 1) ?? (@list.sum / +@list) !! 0 }


  1. TESTING

for (

     [ 1,8,2,-3,0,1,1,-2.3,0,5.5,8,6,2,9,11,10,3 ]
    ,[(rand × 1e6) xx 6]
    ,[ e, i, τ, π, ∞ ]
    ,[ 1.9+3.7i, 2.07-13.2i, 0.2+-2.2i, 4.6+0i ]
    ,[ 6 ]
    ,[]
    ,[<One Two Three>]
   )

-> @list {

   say 'List: ', ~ @list.raku;
   for ('  Maximum', &max-diff ,'Minimumum', &min-diff, '  Average', &avg-diff)
   -> $which, &sub {
       say "$which distance between list elements: " ~ &sub(@list);
   }
   say ;

}</lang>

Output:
List: [1, 8, 2, -3, 0, 1, 1, -2.3, 0, 5.5, 8, 6, 2, 9, 11, 10, 3]
  Maximum distance between list elements: 7 @ elements ((1 8) (2 9) (10 3))
Minimumum distance between list elements: 0 @ elements ((1 1))
  Average distance between list elements: 3.658824

List: [480470.3324944039e0, 719954.3173377671e0, 648221.5674277907e0, 340053.78585537826e0, 540629.6741075241e0, 4336.700602958543e0]
  Maximum distance between list elements: 536292.9735045655 @ elements ((540629.6741075241 4336.700602958543))
Minimumum distance between list elements: 71732.74990997638 @ elements ((719954.3173377671 648221.5674277907))
  Average distance between list elements: 455611.06297097047

List: [2.718281828459045e0, <0+1i>, 6.283185307179586e0, 3.141592653589793e0, Inf]
  Maximum distance between list elements: Inf @ elements ((3.141592653589793 Inf))
Minimumum distance between list elements: 2.896386731590008 @ elements ((2.718281828459045 0+1i))
  Average distance between list elements: Inf+0.2i

List: [<1.9+3.7i>, <2.07-13.2i>, <0.2-2.2i>, <4.6+0i>]
  Maximum distance between list elements: 16.900855007957436 @ elements ((1.9+3.7i 2.07-13.2i))
Minimumum distance between list elements: 4.919349550499537 @ elements ((0.2-2.2i 4.6+0i))
  Average distance between list elements: 2.1925-2.925i

List: [6]
  Maximum distance between list elements: 0
Minimumum distance between list elements: 0
  Average distance between list elements: 0

List: []
  Maximum distance between list elements: 0
Minimumum distance between list elements: 0
  Average distance between list elements: 0

List: ["One", "Two", "Three"]
Cannot convert string to number: base-10 number must begin with valid digits or '.' in '⏏Two' (indicated by ⏏)
  in sub max-diff at listdiff.p6 line 3
  in block  at listdiff.p6 line 33
  in block <unit> at listdiff.p6 line 20

REXX

Some basic error checking was made   (non─numeric element,   not enough elements).

This REXX version was optimized to handle very large lists. <lang rexx>/*REXX program finds/displays the maximum difference between adjacent elements of a list*/ parse arg $ /*obtain optional arguments from the CL*/ if $= | S=="," then $= , /*Not specified? Then use the default.*/

    '1,8,2,-3,0,1,1,-2.3,0,5.5,8,6,2,9,11,10,3' /*commas are optional, blanks may be */

$= translate($, , ',') /*elide optional commas between numbers*/

  1. = words($) /*number of elements in the $ list. */
            do i=1  for words($); x= word($, i) /*examine each element, ensure a number*/
            @.i= x
            if datatype(x, 'N')  then iterate   /*Is it numeric?   Yes, then continue. */
            say '***error***  element #'i  " isn't numeric: "   x
            exit 13
            end   /*i*/

if #<2 then do; say '***error*** not enough elements were specified, minimum is two.'

                  exit 13
            end

say ' list of elements: ' space($) /*show the list of numbers in list.*/ say ' number of elements: ' # /*show " number " elements " " */ aa=; bb= /*the AA and BB list(s); # pairs. */ d= -1 /*maximum difference found (so far). */

       do j=1  for #-1;   jp= j + 1;   a= @.j   /*obtain the  "A"  element.            */
                                       b= @.jp  /*   "    "   "B"     "                */
       newD= abs(a - b)                         /*obtain difference between 2 elements.*/
       if newD<d  then iterate                  /*Is this  not  a new max difference ? */
       d= newD                                  /*assign new maximum difference,  and  */
       aa= aa a;     bb= bb b                   /*  the elements that had the max diff.*/
       end   /*j*/

say /*stick a fork in it, we're all done. */ say 'The maximum difference of the elements in the list is: ' d

       do k=1  for words(aa)
       say 'and is between the elements: '     word(aa, k)      " and "      word(bb, k)
       end   /*k*/

exit 0 /*stick a fork in it, we're all done. */</lang>

output   when using the default input:

<ore>

  list  of elements:  1 8 2 -3 0 1 1 -2.3 0 5.5 8 6 2 9 11 10 3
 number of elements:  17

The maximum difference of the elements in the list is: 7 and is between the elements: 1 and 8 and is between the elements: 2 and 9 and is between the elements: 10 and 3

Ring

<lang ring> see "working..." + nl strList = "[1,8,2,-3,0,1,1,-2.3,0,5.5,8,6,2,9,11,10,3]" see "Maximum difference between adjacent elements of list is:" + nl + nl see "Input list = " + strList + nl + nl see "Output:" + nl sList = [1,8,2,-3,0,1,1,-2.3,0,5.5,8,6,2,9,11,10,3] sortList = []

for n = 1 to len(sList)-1

   diff = fabs(sList[n]-sList[n+1])
   oldDiff = diff
   first = sList[n]
   second = sList[n+1]
   add(sortList,[oldDiff,first,second])

next

sortList = sort(sortlist,1) sortList = reverse(sortlist) flag = 1

for n=1 to len(sortList)-1

   oldDiff1 = sortlist[n][1]
   oldDiff2 = sortlist[n+1][1] 
   first1 = sortlist[n][2]
   second1 = sortlist[n][3]
   first2 = sortlist[n+1][2]
   second2 = sortlist[n+1][3]
   if n = 1 and oldDiff1 != oldDiff2
      see "" + first1 + "," + second1 + " ==> " + oldDiff1 + nl 
   ok
   if oldDiff1 = oldDiff2
      if flag = 1
         flag = 0
         see "" + first1 + "," + second1 + " ==> " + oldDiff1 + nl   
         see "" + first2 + "," + second2 + " ==> " + oldDiff2 + nl
      else
         see "" + first2 + "," + second2 + " ==> " + oldDiff2 + nl
      ok
   else
      exit
   ok

next

see "done..." + nl </lang>

Output:
working...
Maximum difference between adjacent elements of list is:

Input list = [1,8,2,-3,0,1,1,-2.3,0,5.5,8,6,2,9,11,10,3]

Output:
2,9 ==> 7
1,8 ==> 7
10,3 ==> 7
done...

Wren

<lang ecmascript>var list = [1, 8, 2, -3, 0, 1, 1, -2.3, 0, 5.5, 8,6, 2, 9, 11, 10, 3] var maxDiff = -1 var maxPairs = [] for (i in 1...list.count) {

   var diff = (list[i-1] - list[i]).abs
   if (diff > maxDiff) {
       maxDiff = diff
       maxPairs = [[list[i-1], list[i]]]
   } else if (diff == maxDiff) {
       maxPairs.add([list[i-1], list[i]])
   }

} System.print("The maximum difference between adjacent pairs of the list is: %(maxDiff)") System.print("The pairs with this difference are: %(maxPairs)")</lang>

Output:
The maximum difference between adjacent pairs of the list is: 7
The pairs with this difference are: [[1, 8], [2, 9], [10, 3]]

XPL0

<lang XPL0>real List, Dist, MaxDist; int I; [List:= [1., 8., 2., -3., 0., 1., 1., -2.3, 0., 5.5, 8., 6., 2., 9., 11., 10., 3.]; MaxDist:= 0.; for I:= 0 to 17-2 do

   [Dist:= abs(List(I) - List(I+1));
   if Dist > MaxDist then
       MaxDist:= Dist;
   ];

Format(1, 0); for I:= 0 to 17-2 do

   [Dist:= abs(List(I) - List(I+1));
   if Dist = MaxDist then
       [RlOut(0, List(I));  Text(0, ", ");  RlOut(0, List(I+1));
       Text(0, " ==> ");  RlOut(0, MaxDist);  CrLf(0);
       ];
   ];

]</lang>

Output:
1, 8 ==> 7
2, 9 ==> 7
10, 3 ==> 7