loading...

Daily Challenge #117 - MinMinMax

thepracticaldev profile image dev.to staff ・1 min read

Given an unsorted array of integers, find the smallest number in the array, the largest number in the array, and the smallest number between the two array bounds that are not in the array.

For instance, given the array [-1, 4, 5, -23, 24], the smallest number is -23, the largest number is 24, and the smallest number between the array bounds is -22. You may assume the input is well-formed.

Your solution should return an array [smallest, minimumAbsent, largest]

The smallest integer should be the integer from the array with the lowest value.

The largest integer should be the integer from the array with the highest value.

The minimumAbsent is the smallest number between the largest and the smallest number that is not in the array.

minMinMax([-1, 4, 5, -23, 24]); //[-23, -22, 24]
minMinMax([1, 3, -3, -2, 8, -1]); //[-3, 0, 8]
minMinMax([2, -4, 8, -5, 9, 7]); //[-5, -3,9]


This challenge comes from kodejuice on CodeWars. Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge idea for a future post? Email yo+challenge@dev.to with your suggestions!

Discussion

pic
Editor guide
Collapse
citizen428 profile image
Michael Kohl

Ruby:

def min_min_max(arr)
  return [] if arr.size = 0
  return [arr.first, nil, arr.first] if arr.size == 1

  min, *middle, max = arr.sort
  [min, ([*min+1..max-1] - middle).first, max]
end
Collapse
dak425 profile image
Donald Feury
min, *middle, max = arr.sort

Can you explain this part? I haven't seen sort used like this before.

Collapse
citizen428 profile image
Michael Kohl

Sure. But Array#sort is secondary here, it works with any array on the right hand side of an assignment.

I wrote a post for my old blog about this, that should help clarify it:

legacyblog.citizen428.net/blog/201...

Thread Thread
dak425 profile image
Donald Feury

Holy crap I had no idea you could do that in Ruby. Thank ya for the old post that explained it very clearly.

Thread Thread
citizen428 profile image
Michael Kohl

Holy crap I had no idea you could do that in Ruby.

That's something I mention in my post from 2010 and it still hasn't changed much. I think one of the problems is that it's not a common idiom in Rails and for many people Ruby == Rails.

BTW, it's exactly this destructuring mechanism that allows you to iterate over hashes in Ruby like this:

{ a: 1, b: 2 }.each { |k, v| ... }

Hash#each actually turns the key-value-pairs into two element arrays, which then essentially become the right hand side of the assignment to the block variables:

{ a: 1, b: 2 }.each.to_a
#=> [[:a, 1], [:b, 2]]
Thread Thread
dak425 profile image
Donald Feury

That is fascinating, I had no idea. I will keep that in mind.

Collapse
craigmc08 profile image
Craig McIlwrath

Haskell solution:

import Data.List ((\\))

minminmax :: (Ord a, Enum a) => [a] -> (a, a, a)
minminmax xs = let min = minimum xs
                   max = maximum xs
                   range = [min..max] \\ xs
               in  (min, head range, max)

The \\ operator is the list difference, and the .. can be used on any enum type to build a list. This means this works for a large number of types, like:

minminmax "sonicthehedgehog" = ('c', 'f', 't')
Collapse
kespri profile image
kespri

My solution in Swift, I check if the array is not empty and bigger than two elements :

func minMinMax(array: [Int]) -> [Int] {
    guard !array.isEmpty, array.count > 2,
        let min = array.min(),
        let max = array.max(),
        let minimumAbsent = ((min...max).first{!array.contains($0)})
        else {
            return []
    }
    return [min, minimumAbsent, max]
}
Collapse
wheatup profile image
Hao

I'm sure there's less time complexity one but this boi will get its job done

const minMinMax = arr => {
    const [min, max] = [...arr].sort().splice(1, arr.length - 3);
    for (let i = min + 1; i < max; i++) {
        if (!arr.includes(i)) {
            return [min, i, max];
        }
    }
    return [min, undefined, max];
}

minMinMax([-1, 4, 5, -23, 24]); // [ -23, -22, 24 ]
Collapse
mercatante profile image
Steven Mercatante
function minMinMax(arr) {
  // Sorting `arr` lets us easily select the min and max values
  arr.sort((a, b) => a - b)
  const min = arr[0]
  const max = arr[arr.length - 1]

  // Starting at the `min` number, search between 
  // `min` and `max` until you find a value that's not in `arr`
  let minimumAbsent = null
  for (let i = min; i < max; i++) {
    if (!arr.includes(i)) {
      minimumAbsent = i
      break
    }
  }

  return [min, minimumAbsent, max]
}

minMinMax([-1, 4, 5, -23, 24]); //[-23, -22, 24]
// minMinMax([1, 3, -3, -2, 8, -1]); //[-3, 0, 8]
// minMinMax([2, -4, 8, -5, 9, 7]); //[-5, -3, 9]

Runnable example:

Collapse
peter279k profile image
peter279k

Here is the PHP code snippets:

function minMinMax($array) {
  print_r($array);
  $ans = [];
  $ans[0] = min($array);

  $number = $ans[0];
  while (true) {
    $number += 1;

    $ans[1] = $number;
    if (in_array($ans[1], $array) === false) {
      break;
    }
  }

  $ans[2] = max($array);

  return $ans;
}
Collapse
aminnairi profile image
Amin

Elm

import List exposing (minimum, maximum, member)
import Maybe exposing (withDefault)


nextUnknownInteger : Int -> List Int -> Int
nextUnknownInteger integer integers =
    let
        nextInteger = integer + 1
    in
        if member nextInteger integers then
            nextUnknownInteger nextInteger integers
        else
            nextInteger


minMinMax : List Int -> List Int
minMinMax integers =
    let
        minimumInteger     = withDefault 0 <| minimum integers
        maximumInteger     = withDefault 0 <| maximum integers
        nextMinimumInteger = nextUnknownInteger minimumInteger integers

    in
        [minimumInteger, nextMinimumInteger, maximumInteger]

Playground

Here.

Collapse
kiliman profile image
Kiliman

TypeScript with tests

github.com/kiliman/dev-to-daily-ch...

export const minMinMax = (
  set: number[],
): [number, number | undefined, number] => {
  if (set.length < 1) {
    throw new Error('set must include at least one number')
  }
  const sorted = [...set].sort((a, b) => a - b)
  const smallest = sorted[0]
  const largest = sorted[set.length - 1]
  let minimumAbsent = smallest + 1
  for (let i = 1; i < sorted.length; i++) {
    if (minimumAbsent !== sorted[i]) break
    minimumAbsent++
  }

  return [
    smallest,
    minimumAbsent > largest ? undefined : minimumAbsent,
    largest,
  ]
}

Test

import { minMinMax } from '.'

it('should throw an error if less than one element', () => {
  expect(() => minMinMax([])).toThrow()
})

it('should return smallest, minimumAbsent, largest from array of numbers', () => {
  expect(minMinMax([-1, 4, 5, -23, 24])).toStrictEqual([-23, -22, 24])
  expect(minMinMax([1, 3, -3, -2, 8, -1])).toStrictEqual([-3, 0, 8])
  expect(minMinMax([2, -4, 8, -5, 9, 7])).toStrictEqual([-5, -3, 9])
})

it('should return undefined for minimumAbsent if not present between smallest and largest', () => {
  expect(minMinMax([-3, -2, -1, 0, 1, 2, 3])).toStrictEqual([-3, undefined, 3])
})

it('should support a single number', () => {
  expect(minMinMax([1])).toStrictEqual([1, undefined, 1])
})

it('should support two numbers', () => {
  expect(minMinMax([1, 2])).toStrictEqual([1, undefined, 2])
  expect(minMinMax([1, 3])).toStrictEqual([1, 2, 3])
})
Collapse
j_medland profile image
John Medland

Here is a solution with LabVIEW. Not tried LabVIEW? The community edition beta is now open!🎉🎉

Coding Challange 117 - LabVIEW Snippet

Collapse
vitablack13 profile image
Vitablack

Explanatory post. Thanks so much for the details. I also want to share information. If you need a professional resume, write to these guys resumeedge.com/