31
\$\begingroup\$

The Task

The task is very simple. Given an array containing only integers and strings, output the largest number and the smallest number.

Test Cases

Input: [1, 2, 3, 4, 5, 6, 7, 8]
Output: 1, 8

Input: [5, 4, 2, 9, 1, 10, 5]
Output: 1, 10

Input: [7, 8, 10, "Hello", 5, 5]
Output: 5, 10

Numbers in strings are not considered integers:

Input: [1, 2, 3, 4, "5"]
Output: 1, 4

If there is only one integer, it is both the largest and smallest integer:

Input: [1]
Output: 1, 1

Input: ["1", "2", "3", "4", 5]
Output: 5, 5

Rules

  • You can assume that an array will always contains at least one integer.
  • All integers are positive (greater than 0)
  • The order of the output doesn't matter.
  • This is , so the submission with the least amount of bytes wins!
  • Strings can contain all printable ASCII characters (32 - 126) and are non-empty.
\$\endgroup\$
8
  • 1
    \$\begingroup\$ How are strings that contain quote marks represented in the input? \$\endgroup\$ – feersum Feb 5 '16 at 11:23
  • \$\begingroup\$ @feersum Wouldn't that depend on your language? \$\endgroup\$ – Martin Ender Feb 5 '16 at 11:25
  • \$\begingroup\$ @feersum With escape characters probably, but if the language doesn't handle that, that's okay. \$\endgroup\$ – Adnan Feb 5 '16 at 11:25
  • \$\begingroup\$ @MartinBüttner If input is taken from stdin, it should not depend on what language is used. \$\endgroup\$ – feersum Feb 5 '16 at 13:31
  • 4
    \$\begingroup\$ @feersum That's new to me. Even from STDIN [1, 2, 3] 1 2 3 and {1; 2; 3} are all valid input formats, so I don't see why it should be any different for string literals received from STDIN. \$\endgroup\$ – Martin Ender Feb 5 '16 at 13:33

40 Answers 40

1
2
1
\$\begingroup\$

Python 3, 65 bytes

Here's the obligatory example of how Python 3 is worse (for golfing) than Python 2, because it got rid of weird behaviours, like "you can compare ints and strings, and all ints are less than all strings".

def m(a):b=sorted(n for n in a if type(n)==int);return b[0],b[-1]
\$\endgroup\$
1
\$\begingroup\$

C#, 71 bytes

(object[]z)=>{var a=z.OfType<int>();return new int[]{a.Max(),a.Min()};};

Simple lambda which returns the min and max as an int array.

\$\endgroup\$
1
\$\begingroup\$

PARI/GP, 52 bytes

This is terrible -- there has to be a better way to check if something is a number than type. polcoeff(eval(x),0) is even worse, despite (ab)using the requirement that numbers are positive. iferr(O(x);1,E,0) is clever but a byte longer: E is required for some reason, and p-adic numbers like O(3) are falsy (i.e., O(3)==0) so the ;1 is needed.

v->v=[x|x<-v,type(x)=="t_INT"];[vecmin(v),vecmax(v)]

An alternate approach is just as long:

v->[f([x|x<-v,type(x)=="t_INT"])|f<-[vecmin,vecmax]]
\$\endgroup\$
1
\$\begingroup\$

Hoon, 90 84 bytes

|*
*
=+
(sort (skip ((list @) +<) (curr test 0)) lte)
[(snag 0 -) (snag 0 (flop -))]

This uses a couple fun features of Hoon:

  • I'm returning a wet gate instead of a dry one to prevent having to specify the type. This makes the caller typecheck the function instead of definition, which is perfectly fine.

  • The function argument for |= is an unnamed arm, which is placed in the subject at +<. Specifying a/* and using a as the input is longer than just leaving it unnamed and using +< directly

  • The same thing applies for =+ - it places the variable at the top of the subject at -, so I save the sorted list as an intermediate and can reference it the three times needed cheaply

  • The input specifies "All integers are positive (greater than 0)", which along with the fact the string will never be empty helps immensely. I can then slam the input through the type verifier gate (list @), which converts all entries in the list that aren't a number into 0 and then get rid of all zeros.

Example of use:

> %.  (limo ~[1 2 "hello" 9 17])
      |*
      *
      =+
      (sort (skip ((list @) +<) (curr test 0)) lte)
      [(snag 0 -) (snag 0 (flop -))]
[1 17]
\$\endgroup\$
1
\$\begingroup\$

K (ngn/k), 18 bytes

(&/;|/)@\:(`l~@:)#

Try it online!

  • (`l~@:)# filter input to only integers
  • (&/;|/)@\: apply min (&/) and max (|/), returning a list
\$\endgroup\$
1
\$\begingroup\$

C++20 (gcc) std::variant array, 139 129 127 126 125 124 bytes

#import<variant>
int f(auto a,int n,int&m,int&M){for(m=~0u/2,M=0;n--;)if(int*p=std::get_if<int>(a++))*p>m?:m=*p,*p<M?:M=*p;}

Try it online!

Explanation

This uses C++20's abbreviated function templates (cppref) which allow me to just put auto as a parameter instead of using the full name or a template<class T> declaration. It is wonderful.

The effective ungolfed signature is this if it wasn't a template:

void f(std::variant<int, char *> *array, int n_elements, int &min, int &max);

Note that the second type can be literally anything. In the test, I did const char * because C++ string literals are const char *.

The input is an array of std::variant<int, char *> (cppref) of n_elements elements, and the output is stored into min and max which are int references.

It then uses std::get_if<int> (cppref) to select only the ints in the array, and calculates the min and max as normal.

It also uses the x?:y extension from GCC which allows me to omit the middle of the ternary to calculate the min/max, as well as cheating a byte because GCC reluctantly allows #import in C++ as a deprecated extension from Objective-C, and trading a warning for a byte by using int as the return type without returning int

An equivalent C++17-compatible version would be this at 158 153 143 141 140 139 138 bytes:

#import<variant>
template<class T>int f(T a,int n,int&m,int&M){for(m=~0u/2,M=0;n--;)if(int*p=std::get_if<int>(a++))*p>m?:m=*p,*p<M?:M=*p;}

Ungolfed version:

#include <variant>

void f(std::variant<int, const char *> *array, int n_elements, int &min, int &max)
{
    // Set min to INT_MAX and max to 0
    // C++20 guarantees 2's complement, so this is guaranteed to work
    min = ~0u/2;
    max = 0;
    // Loop through each element
    while (n_elements--) {
        // std::get_if returns a pointer to the element if it is an int, or nullptr.
        if (int *p = std::get_if<int>(array++)) {
             // if (*p > min) {} else { min = *p; }
             *p > min ?: min = *p;
             // if (*p < max) {} else { max = *p; }
             *p < max ?: max = *p;
        }
    }
}
\$\endgroup\$
0
\$\begingroup\$

Jelly, 6 bytes

OƑƇṢ.ị

Try it online!

Yields [max, min]

How it works

OƑƇṢ.ị - Main link. Takes  a list L on the left
  Ƈ    - Filter keep:
 Ƒ     -   Invariant under:
O      -     Converting to ordinals
         This filters non-integers from the list, as O has no effect on integers
   Ṣ   - Sort
    .ị - First and last elements
\$\endgroup\$
0
\$\begingroup\$

Python 3, 64 bytes

Another Python solution: the mandatory solution using lambda was missing :)

lambda y:[f(e for e in y if isinstance(e,int))for f in(min,max)]

Try it online!

\$\endgroup\$
0
\$\begingroup\$

R, 45 bytes

function(l)range(unlist(Filter(is.double,l)))

Try it online!

Takes input as a list, as R vectors (c()) will coerce everything to the same type, in this case, character if they are there.

Filters out non-numeric values, then uses range to find the max and min values.

\$\endgroup\$
0
\$\begingroup\$

Ruby, 27 bytes

->a{a.grep(Integer).minmax}

Try it online!

Slightly different from the previous Ruby answer! The user seems to be inactive for a while, so I thought of posting it.

\$\endgroup\$
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.