# Find the minimum and maximum integers in an array, without using builtins

## Challenge

Given an array of integers, received from stdin, function arguments, program arguments, or some other method:

Output only the minimum and maximum numbers in the array, through a return value, stdout, or other fitting methods.

## Example session

> minmax( {0, 15, 2, 3, 7, 18, -2, 9, 6, -5, 3, 8, 9, -14} )
-14 18


## Reference implementation

// C++14

void minmax(std::vector<int> v) {
int min = v[0]; int max = v[0];
for(auto it : v) {
if (*it < min)
min = *it;
if (*it > max)
max = *it;
}
std::cout << min << ' ' << max << std::endl;
}


## Rules

• You may not use a built-in function to calculate the values.
• Standard loopholes disallowed.
• Creative implementations encouraged.
• This is , shortest answer wins but will not be selected.

## Clarifications

• If the array contains 1 element you need to output it twice.
• If the minimum and maximum values are the same, you need to output them both.
• This is a do X without Y challenge, which aren't particularly interesting. – user45941 Aug 23 '16 at 21:31
• @DmitryKudriavtsev Try the sandbox next time. – user45941 Aug 23 '16 at 21:38
• Seriously, use the Sandbox. Your changes to the challenge have invalidated every single answer. – user45941 Aug 23 '16 at 21:58
• I encouraged creative methods No, you encouraged short solutions, by tagging it code golf – Luis Mendo Aug 24 '16 at 1:24
• As said Luis Mendo Yes, everyone is just posting "i sort your array using a built-in and take first and last", in different languages, not really creative :x – Walfrat Aug 24 '16 at 11:15

## Retina, 17 bytes

O#
$¶$
Ss¶.+¶


Input and output are linefeed-separated.

Try it online!

### Explanation

O#


Sort lines by numerical value.

$¶$


Duplicate the entire input to make sure that the first and last element are distinct.

Ss¶.+¶


Remove all intermediate lines, leaving only the minimum and maximum.

def m(v) puts v.sort![0];$><<v[-1];end ->v{[v.sort![0],v[-1]]}  Thanks @Jordan! • You don't need the space after def m(v). Regardless, you can save 15 bytes by using a lambda and just returning an array: ->v{[v.sort![0],v[-1]]}. – Jordan Aug 23 '16 at 21:46 # BASH 38 grep -o '[^ ]*'|sort -g|sed -n '1p;$p'


# Factor, 38 bytes

[ natural-sort [ first ] [ last ] bi ]


Sort the sequence and get its first and last elements.

# dc, 45 bytes

[dsa]dsAx[dsz]dsZx[dla>Adlz<Zs.z0<f]dsfxlzlaf


This is a fairly straightforward equivalent of the C++ reference code:

#Test data
0 15 2 3 7 18 _2 9 6 _5 3 8 9 _14

# Uses two variables: a for min, and z for max

# Functions A and Z simply store a copy to a and z respectively.  Call
# them both, to initialize the variables.
[dsa]dsAx
[dsz]dsZx

# Function f is the main work - define and call it
[
dla>A                       # copy into a if lower
dlz<Z                       # copy into z if higher
z0<f                        # recurse until end of input
]dsfx

# print the result
lzlaf


## C#, 60 bytes

n=>{System.Array.Sort(n);return new[]{n[0],n[n.Length-1]};};


A naïve method at 93 bytes:

n=>{var r=new[]{n[0],n[0]};foreach(int i in n){if(i<r[0])r[0]=i;if(i>r[1])r[1]=i;}return r;};


# Octave, 35 bytes

@(x)[x(all(t=x<=x')) x(sum(t)==1)]


This is an anoynymous function. Try it at ideone.

The code avoids using sorting. Namely, it does all pairwise "less than or equal" comparisons between elements of the input. The minimum is the element for which all comparisons are true. The maximum is that for which only one comparison is true.

# Python, 35 34 bytes

lambda s:sorted(s+s[:1])[::len(s)]


Alternative version:

lambda s:sorted(s+s)[::len(s)*2-1]


Old version, 35 bytes.

lambda s:sorted(s+[s[0]])[::len(s)]


Fairly simple: take the input list, append the first element, sort it, then take the first and (length)th element of the resulting list. As the length of the input after appending an element is length + 1, this ends up taking the first and last element of said list, which are the minimum and maximum elements.

• Though not the shortest answer in Python, this is very creative! +1 – mbomb007 Aug 24 '16 at 18:24
• The 34-byte one doesn't work in Python 3; this works in both 2 and 3. Also, it was posted after this one. – TLW Aug 25 '16 at 0:59
• @mbomb007 - fine, golfed. This is now tied for the shortest Python implementation, and as a bonus it works in both 2 and 3. – TLW Aug 25 '16 at 1:04

# zsh, 22 bytes

(){echo $1$_} ${(n)@}  defines a lambda function that prints its first arg ($1) and the last argument to the previous command ($_), and passes it $@ after sorting it so the previous command becomes the invocation of that lambda

# zsh, 21 bytes

this only works fine if there's more than 1 argument :(

<<<"${${(n)@}/ * / }"


sorts $@, makes it a string and replaces everything from the first space to the last one with a single space, then passes it as input to cat with <<< usage: $ ./minmax 23 342 21 10
10 342


# Scala, 55 bytes

val s=args.map(_.toInt).sorted


To execute:

$scala minmax.scala 1 2 3 4 5 6 7 8 9 ## Bash + coreutils, 30 bytes tr \ \\n|sort -n|sed '$p;1!d'


The sed script prints, after the input is sorted, the first and last integers.

# dc, 110 bytes

?ddsMsmzdsAsa[z1-:az0<S]dsSx[>R]s?[la;asM]sR[lM]sQ[lQxla1-dsa;al?xla0<N]dsNxlAsa[<R]s?[la;asm]sR[lm]sQlNxlmlMf


Help me, dcers! You are my only hope!

Thanks to @seshoumara for finding that bug!

I'll add an explanation later. Here it is broken up a bit:

?dd sM sm
zd sA sa
[z 1- :a z0<S]dsSx
[>R]s?
[la;asM]sR
[lM]sQ
[lQx la 1- dsa ;a l?x la0<N]dsNx
lA sa
[<R]s?
[la;a sm]sR
[lm]sQ
lNx
lm lM f

• I didn't record how to invoke this, and now I can't remember. Whatever I'm doing now, I'm doing it wrong, because this is always returning 0 as the smallest element. – Joe Aug 27 '16 at 21:52
• Pfew! It took some starring at it, but found the bug in your code. It's the first character (0) which you duplicate and initialize registers M and m. But if in the input list no number is smaller than m=0, or no number is greater than M=0, then you get an incorrect result, because you artificially added 0 to the sample numbers. The solution is to replace that first 0 with ?d, which reads the numbers and initializes M and m with the last number, thus making it a part of the sample. Then run the code like this: echo "8 _2 5"|dc -e "?ddsMsm....". – seshoumara Sep 8 '16 at 9:54
• Wow, thanks, @seshoumara! I never would have noticed that! (I'd forgotten all about this question, too :P) – Joe Sep 12 '16 at 18:51

# C++14, 66 bytes

As unnamed lambda returning via reference parameters. Accepts any random access container of integers.

[](int&a,int&b,auto&C){a=b=C[0];for(auto x:C)a=x<a?x:a,b=x>b?x:b;}


Ungolfed and usage:

#include<vector>
#include<iostream>

auto f=
[](int&a,int&b,auto&C){
a=b=C[0];
for(auto x:C)
a=x<a?x:a,
b=x>b?x:b;
}
;

int main(){
std::vector<int> v{1,2,3,4,5,6,7,8,9,0,10,121,-12,100,100,100};
int a;
int b;
f(a,b,v);
std::cout << a << ", " << b << std::endl;
}


# Pyke, 5 4 bytes

S'he


Try it here!

S    - sorted(input)
'he - ^[0], ^[-1]


## Clojure, 28 bytes

#((juxt first last)(sort %))


At least juxt is mildly interesting.

## Python, 110 Bytes

Long, but it doesn't use sort.

def m(a):
d=a[0]
if len(a)==1:return d,d
b,c=m(a[1:])
if b>=d>=c:return b,c
if d>b:return d,c
return b,d


Output is a tuple of the form (max, min). Probably the least computationally efficient way to get the max/min of an array (other than bongo sorting it :P)

# Python, 97 bytes

def k(s):
d=s[0]
if s[1:]:
a,b=k(s[1:])
return(a+d+abs(a-d))/2,(b+d-abs(b-d))/2
return d,d


Only clever part is that in python [] is falsy. Only builtin used is abs.

It uses more builtins than the 110 byte python solution, and more bytes than the 26 byte solution using sort.

# x86 opcode, 19 bytes

00: mov ebx, [esi]
02: mov edx, ebx
04: lodsd
05: cmp eax, ebx
07: cmovg ebx, eax
0A: cmp eax, edx
0C: cmovl edx, eax
0F: loop lp1
11: xchg eax, ebx
12: ret


Input: ECX(length), ESI(array)

Output: EAX(max), EDX(min)

Removing xchg eax, ebx makes 18B but output is not usual reg

# SNOBOL4 (CSNOBOL4), 87 bytes

	M =INPUT
N =M
R	I =INPUT	:F(O)
N =LT(I,N) I
M =GT(I,M) I	:(R)
O	OUTPUT =N ' ' M
END


Try it online!

# Tcl, 62 bytes

puts [lindex [set L [lsort -r [join $argv]]] 0]\ [lindex$L e]


Try it online!