Maximum difference between adjacent elements of list: Difference between revisions
m (added a word to the task's preamble ("which").) |
m (→{{header|REXX}}: elided a duplicated comment.) |
||
Line 453: | Line 453: | ||
aa= aa a; bb= bb b /* the elements that had the max diff.*/ |
aa= aa a; bb= bb b /* the elements that had the max diff.*/ |
||
end /*j*/ |
end /*j*/ |
||
say |
say |
||
say 'The maximum difference of the elements in the list is: ' d |
say 'The maximum difference of the elements in the list is: ' d |
||
do k=1 for words(aa) |
do k=1 for words(aa) |
Revision as of 23:05, 18 July 2021
- Task
Find maximum difference between adjacent elements of list.
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 (which 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
<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
- 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] ]
- ------------------------- TEST -------------------------
- 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)
- 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 }
- 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*/
- = 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 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