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 int
s 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;
}
}
}
[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