32
\$\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
    Commented Feb 5, 2016 at 11:23
  • \$\begingroup\$ @feersum Wouldn't that depend on your language? \$\endgroup\$ Commented Feb 5, 2016 at 11:25
  • \$\begingroup\$ @feersum With escape characters probably, but if the language doesn't handle that, that's okay. \$\endgroup\$
    – Adnan
    Commented Feb 5, 2016 at 11:25
  • 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\$ Commented Feb 5, 2016 at 13:33
  • 1
    \$\begingroup\$ @CodyGray Keep in mind this is an older challenge, and so what we currently consider to be “good” challenges may not apply. Ultimately, this is “filter out strings, then take the min and max”, but in 2016, such a challenge was considered good. Nowadays, we may not agree, but it’s problematic to apply the standards held in 2021 to challenges posted in 2016 \$\endgroup\$ Commented Jan 1, 2021 at 18:51

50 Answers 50

1
2
1
\$\begingroup\$

Jolf, 20 bytes

I can probably golf this... I need to implement type-checking shorter solutions.

γ fxd='nF~tH0ͺZkγZKγ
 _fx                 filter the input
    d='nF~tH0        checking for number type
γ                    call that "γ"
             ͺ       pair
              ZkγZKγ  the min and max of the array
\$\endgroup\$
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\$

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\$

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
\$\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\$
1
\$\begingroup\$

Vyxal, 6 bytes

0+∩₍gG  # main program
0+      # add 0 to each element of input if number, else append 0
  ∩     # take the set intersection
   ₍    # apply the following two operations on top of stack and wrap
    gG  # min and max
        # implicit output

It may be possible to take this down a byte if there is a command that only affects strings but not numbers. I couldn't find one after some basic searching, but its possible a single command exists that does that.

Try it Online!

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

K (ngn/k), 19 bytes

(&/;|/)@\:(`i=@:')#

Try it online!

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

Factor, 27 bytes

[ [ real? ] filter minmax ]

Try it online!

Integers are objects, reals, and integers in Factor, so we can save a few bytes by using the shortest class predicate word to filter out the strings.

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

Zsh (builtins only), 35 bytes

A=(${(n)@//[A-z]});<<<$A[1]\ $A[-1]

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ NB, Zsh takes all inputs as strings and can't distinguish between "1" and 1 \$\endgroup\$
    – roblogic
    Commented Mar 3, 2023 at 21:35
1
\$\begingroup\$

Japt, 11 bytes

'm¬iÔm!rUfâ

Try it

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

Thunno D E, \$3 \log_{256}(96) \approx\$ 2.47 bytes

zni

Attempt This Online! Output as [max, min]

Verify some more test cases: 1 2 3 4 5

Explanation:

     # Example input: 1, 2, 3, 4, "5"
     # The E flag tells the interpreter not to evaluate the input strings,
     # so they end up as "1", "2", "3", "4", '"5"'
     # The D flag duplicates the input. The zn command will automatically pop the top item.
     # We want to keep all the items on the stack, so we need the D flag
zn   # Push [max, min]. As the top item is not a list, it applies it to the stack,
     # converting each to a float. It can't convert '"5"', so it just ignores it.
  i  # Convert each to an integer (as the zn command converted to float)
\$\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\$

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\$

Brachylog, 7 bytes

ℕˢ⟨⌋≡⌉⟩

Try it online!

Explanation

 ˢ      Select the elements of the input list which...
ℕ       ...are integers >= 0
  ⟨   ⟩  Make a list containing...
   ⌋     ...the minimum element...
     ⌉   ...and the maximum element...
    ≡   ...and return it unchanged
\$\endgroup\$
0
\$\begingroup\$

Japt, 11 bytes

kȶsÃÍg[TJ]

Try it

kȶsÃÍg[TJ]     :Implicit input of array
k               :Remove elements that return true
 È              :When passed through the following function as X
  ¶             :  Is strictly equal to
   s            :  X converted to a string
    Ã           :End remove
     Í          :Sort
      g         :Get elements at 0-based indices
       [TJ]     :  0 and -1 (last)
\$\endgroup\$
0
\$\begingroup\$

Python 3, 54 bytes

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

lambda y:[f(e for e in y if e*0==0)for f in (min,max)]

Try it online!

-10 bytes thanks to aeh5040

\$\endgroup\$
1
  • \$\begingroup\$ replace isinstance(e,int) with e*0==0 to save 11 \$\endgroup\$
    – aeh5040
    Commented Aug 7, 2021 at 20:40
0
\$\begingroup\$

Arturo, 38 37 bytes

$[a][filter'a=>string?@[min a max a]]

Try it

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

JavaScript, 53 bytes

Based on edc65's this answer. We can save 1 byte if check !x[0] instead of x===+x

a=>[Math.max(...a=a.filter(x=>!x[0])),Math.min(...a)]

f=a=>[Math.max(...a=a.filter(x=>!x[0])),Math.min(...a)]

;[
    [1, 2, 3, 4, 5, 6, 7, 8],    // [8, 1]
    [5, 4, 2, 9, 1, 10, 5],      // [10, 1]
    [7, 8, 10, "Hello", 5, 5],   // [10, 5]
    [1, 2, 3, 4, "5"],           // [4, 1]
    [1],                         // [1, 1]
    ["1", "2", "3", "4", 5],     // [5, 5]
].map(a => console.log(JSON.stringify(f(a))))

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

Uiua, 17 bytes

∩⊔⊃/↥/↧▽¬∵'type⊔.

Try it!

∩⊔⊃/↥/↧▽¬∵'type⊔.
                .  # duplicate
         ∵'type⊔   # mask of types (0 for int, 1 for string)
        ¬          # not
       ▽           # keep
  ⊃/↥/↧            # min and max
∩⊔                 # unbox both (need this for one-int arrays)
\$\endgroup\$
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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