diff --git a/numbers/numbers.go b/numbers/numbers.go index 38fd16f..a7afa6c 100644 --- a/numbers/numbers.go +++ b/numbers/numbers.go @@ -105,3 +105,23 @@ func Round(x float64) float64 { } return t } + +// MinMax returns the smallest and the largest value among the provided values. +// Returns (0, 0) if there are no values. +func MinMax(values []float64) (min, max float64) { + if len(values) == 0 { + return 0, 0 + } + min = math.MaxFloat64 + max = -1 * math.MaxFloat64 + + for _, v := range values { + if v < min { + min = v + } + if v > max { + max = v + } + } + return min, max +} diff --git a/numbers/numbers_test.go b/numbers/numbers_test.go index 495bed3..791cc72 100644 --- a/numbers/numbers_test.go +++ b/numbers/numbers_test.go @@ -147,3 +147,55 @@ func TestRound(t *testing.T) { } } } + +func TestMinMax(t *testing.T) { + tests := []struct { + desc string + values []float64 + wantMin float64 + wantMax float64 + }{ + { + desc: "no values", + }, + { + desc: "all values the same", + values: []float64{1.1, 1.1}, + wantMin: 1.1, + wantMax: 1.1, + }, + { + desc: "all values the same and negative", + values: []float64{-1.1, -1.1}, + wantMin: -1.1, + wantMax: -1.1, + }, + { + desc: "min and max among positive values", + values: []float64{1.1, 1.2, 1.3}, + wantMin: 1.1, + wantMax: 1.3, + }, + { + desc: "min and max among positive and zero values", + values: []float64{1.1, 0, 1.3}, + wantMin: 0, + wantMax: 1.3, + }, + { + desc: "min and max among negative, positive and zero values", + values: []float64{1.1, 0, 1.3, -11.3, 22.5}, + wantMin: -11.3, + wantMax: 22.5, + }, + } + + for _, tc := range tests { + t.Run(tc.desc, func(t *testing.T) { + gotMin, gotMax := MinMax(tc.values) + if gotMin != tc.wantMin || gotMax != tc.wantMax { + t.Errorf("MinMax => (%v, %v), want (%v, %v)", gotMin, gotMax, tc.wantMin, tc.wantMax) + } + }) + } +}