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

Jelly, 3 bytes

Ṣ.ị


Try it online!

Sort the array, and then takes the 0.5-th element.

Jelly uses 1-indexing, and floating points indexing means take its floor and its ceil.

So the 0.5-th element would give you the 0th element and the 1st element.

The 0th element is the last element.

• Pretty Clever I'm wait for it.... Jelly! – Rohan Jhunjhunwala Aug 23 '16 at 22:45
• Oh, so that would make finding the median trivial. – Adám Aug 24 '16 at 7:54
• @KonradRudolph This. – Leaky Nun Aug 24 '16 at 10:31
• Don't you want the first and last elements, rather than the first two elements? Or have I misunderstood your explanation? – Toby Speight Aug 24 '16 at 10:44
• @TobySpeight In 1-based indexing the 0th element is the last element. – Leaky Nun Aug 24 '16 at 11:46

Python, 6149373634 31 bytes

lambda s:s.sort()or[s[0],s[-1]]


-12 bytes thanks to RootTwo

Another -12 bytes thanks to chepner

-2 bytes thanks to johnLate

-3 bytes thanks to johnLate

• I changed the heading to Python because it works in Python 3 also. – Leaky Nun Aug 23 '16 at 21:44
• You can golf off a dozen bytes: use [::(len(s)-1)or 1] for the first subscript. And the second term can be shortened to s[:len(s)<2]. – RootTwo Aug 24 '16 at 6:45
• At the cost of sorting the list twice, you can shave off another 12 bytes: lambda s:sorted(s)[:1]+sorted(s)[-1:]. – chepner Aug 25 '16 at 3:37
• save 6 bytes by lambda s:sorted(s)[::len(s)-1] – Aaron Sep 12 '16 at 17:50
• The current version (lambda s:sorted(s)[::len(s)-1]) does not work for arrays with one element (ValueError: slice step cannot be zero). A possible fix would be lambda s:sorted(s*2)[::len(s*2)-1] (34 bytes). – johnLate Sep 12 '16 at 19:42

Brain-Flak220 218 bytes

(({}))([]){({}[()]<(([])<{({}[()]<([([({}<(({})<>)<>>)<><({}<>)>]{}<(())>)](<>)){({}())<>}{}({}<><{}{}>){{}<>(<({}<({}<>)<>>)<>({}<>)>)}{}({}<>)<>>)}{}<>{}>[()]){({}[()]<({}<>)<>>)}{}<>>)}{}({}<((())){{}{}([][()])}{}>)


Try It Online!

Explanation

First it doubles the top value (in cast the list is only one long)

(({}))


Then it uses my bubble sort algorithm:

([]){({}[()]<(([])<{({}[()]<([([({}<(({})<>)<>>)<><({}<>)>]{}<(())>)](<>)){({}())<>}{}({}<><{}{}>){{}<>(<({}<({}<>)<>>)<>({}<>)>)}{}({}<>)<>>)}{}<>{}>[()]){({}[()]<({}<>)<>>)}{}<>>)}{}


Then it picks up the top value of the stack (i.e. the min)

({}<...>)


Then it pops until the height of the stack is one:

((())){{}{}([][()])}{}


JavaScript (ES6), 34 bytes

a=>[a.sort((x,y)=>x-y)[0],a.pop()]


sort sorts in-place, so I can just refer to the [0] index for the lowest value and pop the highest value from the array, however it does a string sort by default so I have to pass a comparator.

• I don't think you need the (x,y)=>x-y part, unless using sort() with the default algorithm counts as a builtin. – Scott Aug 24 '16 at 17:48
• @Scott But I don't want a lexical sort... – Neil Aug 24 '16 at 20:00
• Right... I didn't test it with numbers > 10 or < 0. I didn't know sort() internally treats everything as strings - sorry! – Scott Aug 24 '16 at 20:05

Mathematica, 18 bytes

Sort[#][[{1,-1}]]&


Sorts the array and extracts the first and last values.

R, 31 bytes

l=sort(scan());l[c(1,sum(l|1))]


Not that original, but hey !

ARM Machine Code, 26 bytes

Hex dump (little endian):

6810 4601 f852 cb04 4560 bfc8 4660 4561 bfb8 4661 3b01 d8f5 4770


This is a function, with no system call or library dependence. The encoding is Thumb-2, a variable (2 or 4 byte) encoding for 32-bit ARM. As one might imagine, there's no easy way to just sort and pick the first and last elements here. Overall there's nothing really that fancy going on here, it's more or less the same as the reference implementation.

Ungolfed assembly (GNU syntax):

.syntax unified
.text
.global minmax
.thumb_func
minmax:
@Input: @r0 and r1 are dummy parameters (they don't do anything)
@r2 - Pointer to list of integers (int*)
@r3 - Number of integers to sort (size_t)
@Output:
@Minimum of the list in r0 (int)
@Maximum in r1 (int)
ldr r0,[r2] @min=r2[0]
mov r1,r0 @max=min
loop:
@ip is intra-procedure call register, a.k.a. r12
ldr ip,[r2],#4 @ip=*r2++
cmp r0,ip
it gt @if (r0>ip)
movgt r0,ip @r0=ip
cmp r1,ip
it lt @if (r1<ip)
movlt r1,ip @r1=ip
subs r3,r3,#1
bhi loop @while (--r3>0)
bx lr @Return


Tested on the Raspberry Pi 3; here's the testing script (C99, input through argv):

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
//First 2 arguments are dummies.
uint64_t minmax(int,int,int* array,size_t size);

int main(int argc,char** argv) {
int i;
int array[argc-1];
for (i=1;i<argc;i++) {
array[i-1]=atoi(argv[i]);
}
uint64_t result = minmax(0,0,array,argc-1);
printf("Minimum is %d, maximum is %d.\n",(unsigned)result,(unsigned)(result>>32));
}


f x=(foldl1x)<$>[min,max]  In Haskell, min and max give minimum and maximum of two arguments, not of a list. I couldn't tell whether this is disallowed (it seems that instead only minimum and maximum would be disallowed) so please let me know if they are and I'll promptly delete this answer. • @nimi FGITW effect, sadly... – ThreeFx Aug 25 '16 at 5:26 Octave, 20 bytes @(n)sort(n)([1,end])  This sorts the input vector and outputs the first and last value. Actually, 5 bytes S;F@N  Try it online! Explanation: S;F@N S sort ; dupe F first element @N and last element  05AB1E, 6 4 bytes {Âø¬  Explanation { # sort list Â # bifurcate ø # zip ¬ # head  Try it online MATL, 4 bytes S5L)  Try it online! Explanation S % Implicitly input the array. Sort 5L % Push [1 0]. When used as a (modular, 1-based) index, this means "first and last" ) % Apply as an indexing vector into the sorted array. Implicitly display  Python, 29 bytes lambda s:s[s.sort():1]+s[-1:]  Test it on Ideone. C, 8381 79 bytes m,M;f(a,s)int*a;{for(m=M=*a;s--;++a)*a<m?m=*a:*a>M?M=*a:0;pr‌​intf("%i %i",m,M);}  • the declaration can turn into ...f(a,s)int*a{... per this – cat Dec 6 '16 at 15:50 • You can combine the ternary expressions to get another 2 bytes off: m,M;f(a,s)int*a;{for(m=M=*a;s--;++a)*a<m?m=*a:*a>M?M=*a:0;printf("%i %i",m,M);} – gastropner Dec 18 '17 at 22:02 • In gcc you can replace *a>M?M=*a:0 with *a<M?:M=*a – ceilingcat Jan 4 '18 at 18:52 Brachylog, 9 bytes oOtT,Oh:T  Try it online! V, 12 bytes :sor ò2Gjkd  Try it online! Credit to DJMcMayhem for this. • \o/ Yay, I'm no longer the only person to have ever used this language! – James Aug 23 '16 at 22:07 • If the input is a single number, that number still has to be output twice – Luis Mendo Aug 24 '16 at 2:15 • @LuisMendo hm, will work on that. – Rɪᴋᴇʀ Aug 24 '16 at 4:00 CJam, 10 9 bytes q~$_(p;W>


Try it online.

I'm really not good at CJam.

q~          e# eval input
$e# sort _ e# duplicate ( e# pop first p e# print ; e# remove array W> e# get last element  • The usual way to get the first element of a list is 0= (but that unfortunately that doesn't save any bytes). Two other 9-byte solutions: 0W]q~$f=p or the unnamed block {$2*_,(%}. – Martin Ender Aug 24 '16 at 7:36 • 8 bytes: q~$(p)p;. You can use ) to get the last element like you use ( to get the first. – Business Cat Aug 24 '16 at 13:30
• @BusinessCat That's what I originally had, but it fails for single-element input. – PurkkaKoodari Aug 24 '16 at 13:30
• @Pietu1998: Oh, you're right. I didn't notice that. – Business Cat Aug 24 '16 at 13:31

Perl 6 13 bytes

*.sort[0,*-1]


Test:

my &min-max = *.sort[0,*-1];

say min-max 1;
# (1 1)
say min-max (0, 15, 2, 3, 7, 18, -2, 9, 6, -5, 3, 8, 9, -14)
# (-14 18)

• Darn, you beat me there! – bb94 Aug 25 '16 at 1:23

Python 2, 34 bytes

x=sorted(input());print x[0],x[-1]


PHP, 44 bytes

function a($a){sort($a);echo $a[0].end($a);}


POSIX Awk, 44 bytes

awk '{for(;NF-1;NF--)if($1>$NF)$1=$NF}1' RS=


Java, 115 bytes

String f(int[]i){int t=i[0],a=t,b=t;for(int c=0;c<i.length;c++){a=i[c]<a?i[c]:a;b=i[c]>b?i[c]:b;}return""+a+" "+b;}


Ungolfed:

String f(int[] i) {
int t=i[0], a=t, b=t; // assigns a and b to i[0]
for (int c=0; c < i.length; c++) { // loop through the array
a=(i[c]<a) ? i[c] : a;
b=(i[c]>b) ? i[c] : b; // assignment with ternary operator
}
return ""+a+" "+b; // returns a string
}


My first ever code "golf" solution.

JavaScript (ES6), 46 bytes

I wanted to try an answer without sorting:

a=>a.map(i=>i<n?n=i:i>x?x=i:0,n=x=a[0])&&[n,x]


Bonus recursive version, 53 bytes:

f=([i,...a],n=i,x=i)=>i+.5?f(a,i<n?i:n,i>x?i:x):[n,x]

• Thanks. Mine also doesn't use sort. – aross Sep 26 '16 at 14:30

JavaScript (ES6), 68 58 bytes (without sorting)

Oh my first try in Golf: without explicit sort (and without min max).
Thanks to @ETHproductions for golfing tips!!

a=>(b=[],a.map(n=>b[n]=0),[b.indexOf(0),b.lastIndexOf(0)])


Does not work with negative integers.

Tried @Luis Mendo 's approach but got it 2 bytes longer... Cost for supporting negative numbers lol?

a=>[a.find(n=>a.every(e=>e>=n)),a.find(n=>a.every(e=>e<=n))]


Could get shorter if order of output is not important:

a=>a.filter(n=>a.every(e=>e>=n)||a.every(e=>e<=n))

• Currying doesn't work in this case; the function is called internally as f(a,b), and curried functions need to be called as f(a)(b). (Try testing it out in a browser console.) – ETHproductions Sep 24 '16 at 3:12
• @ETHproductions You are correct. I should have provided an already sorted list as input when I was testing... Sorry for the misleading info. Other than a browser console, what ways are good ways to test ES6 code? – Sunny Pun Sep 24 '16 at 15:47
• I sometimes use this page to test my JS code, although this only supports what your browser does in terms of ES6 features. There are online places where you can run ES6 in any browser, but all the ones I found are very strict with the code (not accepting undeclared variables and the like). – ETHproductions Sep 24 '16 at 16:12
• Some golfing tips: you can get rid of the let and return and wrap everything in parentheses, like so: a=>(b=[],a.map(n=>b[n]=0),[b.indexOf(0),b.lastIndexOf(0)]) – ETHproductions Sep 24 '16 at 16:13
• @ETHproductions Thanks a lot! What does the , mean in the parentheses? (I don't know what is happening there) – Sunny Pun Sep 24 '16 at 16:18

Processing, 59 52 bytes

void m(int[]x){x=sort(x);print(x[0],x[x.length-1]);}


Processing doesn't actually let me read from stdin that I've been able to find, and I don't know if its internal Java compiler supports lambdas (and its been so long since I've had to write serious Java that I don't remember how).

• You can save bytes by removing spaces after int[] – user41805 Dec 4 '16 at 18:33

PHP, 66 65 bytes

Note: this doesn't use any sort builtin. Also, PHP 7 required for the null coalesce operator.

for(;n|$x=$argv[++$i];$x>$h&&$h=$x)$l=min($l??$x,$x);echo"$l,$h";  The max part is straightforward. The min part is a bit more elaborate. since in PHP null is less than 123, null needs to be handled. For this I'm using the null coalesce operator. If $l is null, use the current number ($x) instead, then take the smaller of the 2 numbers. Run like this: php -d error_reporting=30709 -r 'for(;n|$x=$argv[++$i];$x>$h&&$h=$x)$l=min($l??$x,$x);echo"$l,$h";' -- 0 15 2 3 7 18 -2 9 6 -5 3 8 9 -14;echo


37 bytes (with sort)

Being allowed to sort makes it trivial (windows-1252 encoding):

php -d error_reporting=30709 -r '$a=$argv;echo$a[sort($a)],~ß,end(\$a);' -- 0 15 2 3 7 18 -2 9 6 -5 3 8 9 -14;echo


Sort returns 1 when successful, and the list of arguments will start with - which will be sorted as the first item, so we need item 1 to yield min. Therefore we happen to be able to use the return value of sort as the index, saving 2 bytes.

Tweaks

• Use n|"0" to make "0" truthy to continue the loop, instead of 0 ."0". Saved a byte

APL (Dyalog), 1110 5 bytes

-5 thanks to Erik the Outgolfer.

According to the original poster, using a function that picks the largest of exactly two elements (in contrast to the largest of a whole array) [is] allowed. Therefore, the obvious solution is:

⌊/,⌈/


⌊/ minimum-reduction

, followed by

⌈/ maximum-reduction

More in the spirit of the challenge:

(⊃,⊢/)⍋⊃¨⊂


(

⊃ first

, followed by

⊢/ the last (lit. right-reduction)

) of

⍋ the indices of the elements in ascending order

⊃¨ each picks from

⊂ the entire argument

TryAPL online!

Julia 0.6, 19 bytes

x->sort(x)[[1,end]]


Try it online!

C++ (g++), 148 133 131 122 119 bytes

#import<map>
#import<vector>
[](std::vector<int>v){int a=v[0],b=a;for(int i:v)i<a?a=i:i<b?:b=i;printf("%d %d\n",a,b);};


Try it online!

(\l->(head l,last l)).Data.List.sort

Would love to use &&& here but imports are so costly...
• You can't just use Data.List.sort from what I know, you'd need to import it. You could specify Haskell and put LambdaBot in brackets which imports Control.Arrow as well, this would make it valid and save you 20 bytes (no need for Data.List at all). – ბიმო Dec 30 '17 at 0:27