Intro

A friend posed this question today in a slightly different way - "Can a single [Python] command determine the largest of some integers AND that they aren't equal?".

While we didn't find a way to do this within reasonable definitions of "a single command", I thought it might be a fun problem to golf.

 Challenge

"Return the largest of a list of integers if-and-only-if they are not all equal."

More specifically:

Given a string containing only a comma-separated list of integers:

  • If they are all equal, return/output nothing
  • Else, return/output the largest

Rules

  • The input must be a string containing only a comma-separated list of integers
  • The output must be either nothing (no output of any kind), or else the largest element from the input, represented as it is in the input

Entries may be a full program or just a function, provided you provide some way to test them!

Assumptions

  • Assume input list elements may be more than one digit but no larger than ( 232 − 1 )
  • Assume the input list has no more than a million elements
  • Assume the input will not include negative values
  • Assume the input will never be empty

For the avoidance of doubt, the explanation of the challenge given just after "More specifically" shall supersede the statement of the challenge above it ("Return the largest...").

 Examples

(1) All equal:

Input: 1,1
Output:

(2) Dissimilar:

Input: 1,2
Output: 2

(3) Zero!:

Input: 0,0,0,0,0,0,0,1,0,0
Output: 1

(4) Random:

Input: 7,3,8,4,8,3,9,4,6,1,3,7,5
Output: 9

(5) Larger numbers, larger list:

Input: 627,3894,863,5195,7789,5269,8887,3262,1448,3192
Output: 8887

Additional examples:

(6) All equal, larger list:

Input: 7,7,7,7,7,7,7,7,7
Output:

(7) All equal, larger list, larger numbers:

Input: 61976,61976,61976,61976,61976,61976,61976,61976,61976,61976,61976,61976,61976,61976,61976,61976,61976,61976,61976,61976,61976,61976,61976
Output:

(8) Not equal, larger list, larger numbers:

Input: 96185,482754,96185,96185,96185,96185,96185,96185,7,96185,96185,96185,96185,96185,96185,96185,96185,96185,96185,96185,96185,96185,96185,96185,96185,961185,96185,96185,96185
Output: 961185

Scoring

This is code-golf, so the code with the shortest number of bytes wins!

  • 3
    Is it OK to throw an error when the list contains all equal values? And can we output a null value (such as None in python) rather than outputting nothing? Also, why must the input be a string rather than a list? And what do you mean by the largest element from the input, represented as it is in the input – DJMcMayhem Oct 5 at 21:02
  • 15
    I'd suggest loosening the input requirements to allow for an array/list of integers, too. Are we guaranteed that the list will contain at least 2 elements? Can we output a consistent, non-numeric value instead of nothing if all integers are equal? – Shaggy Oct 5 at 22:08
  • 15
    Please add a test case where the maximum occurs more than once, like 7,3,7,2. – nimi Oct 6 at 6:31
  • 3
    Can we have a test case with only one element? Also, can we include a trailing , in the input? – Jo King Oct 6 at 7:03
  • 2
    Info: This challenge was sandboxed. /// For OP: Although the sandbox is pretty inactive, (I think) it is only a minor problem. The problem is that some problems with the challenge are not apparent if one only reads the challenge, and can only be discovered when one actually solves it. – user202729 Oct 6 at 11:00

46 Answers 46

R, 50 37 bytes

-33 bytes thanks to digEmAll! -13 bytes thanks to rturnbull!

x=scan(se=",");if(any(diff(x)))max(x)

Try it online!

MathGolf, 5 bytes

è▀s╞╙

Try it online!

Explanation

è      Read whole input as int array
 ▀     Get unique elements
  s    Sort list
   ╞   Discard from left of array
    ╙  Get maximum of list

This works because both the max operator and the discard from left operator don't do anything for empty lists. Well, the max operator removes the list and pushes nothing for empty lists.

It could be 4 bytes if input could be taken as a list.

  • Input must be a comma separated string. – Shaggy Oct 6 at 11:11
  • @Shaggy I missed that. Right now MathGolf doesn't have a "split on character" operator, so it'll take some work to get it right. I'll see what I can do. – maxb Oct 6 at 11:46

Jelly, 4 bytes

ḟṀE?

A full program accepting the input as a command line argument (unquoted) which prints the required output

(Note that it deals with: empty input like , single item input like 7 and multiple item input like 7,8,7 like the spec seems to currently require.)

Try it online!

How?

ḟṀE? - Full program: if one argument is present it is evaluated using Python
     -                 so 7,8,7 -> [7,8,7], while 7 -> 7
ḟṀE? - Main Link: list or integer OR no argument (in which case an implicit argument of 0)
   ? - if...
  E  - ...condition: all equal? (for any integer E yields 1 since the argument is
     -                           treated as a list like [integer])
ḟ    - ...then: filter discard (since it's undefined the right argument is implicitly 
     -                          equal to the left; both are treated as lists, so this
     -                          yields an empty list)
 Ṁ   - ...else: maximum (again an integer is treated as a list)
     - implicit print (Jelly's representation of an empty list is an empty string
     -                 furthermore no newline is printed in either case)

Perl 6, 26 23 22 bytes

-1 byte thanks to nwellnhof

{.max if .Set>1}o&EVAL

Try it online!

Returns an empty slip if everything is equal.

Explanation

                o&EVAL  # Eval the string to a list of integers
{              }         # Pass to code block
 .max            # Return the max
      if .Set>1  # If the list converted to a set has more than one element
  • 1
    The EVAL trick is neat and you can even save a byte with o&EVAL. – nwellnhof Oct 6 at 12:25

CJam, 16 13 bytes

q',/:iL|$1>W>

Try it online!

Python 2, 37 bytes

outputs to stderr (debug on tio).

a=input();m=max(a);m>min(a)>exit(`m`)

Try it online!

Python 2, 42 41 bytes

a=input();print('',max(a))[len(set(a))>1]

Try it online!

  • Welcome to PPCG :) I don't know Python but it looks like this requires input as list. Unfortunately (and unnecessarily, my opinion) the spec is (currently) very explicit that input must be a string. – Shaggy Oct 6 at 0:25
  • @Shaggy, this program works if the input is of the form element, element, .... i.e, it doesn't have to be enclosed in brackets. – Arnav Borborah Oct 6 at 1:27
  • 1
    A list does work, but is not required because in Python 2, input by default evals whatever string is passed from stdin. – Arnav Borborah Oct 6 at 1:33
  • 1
    40 bytes. I don't know if a one element list can have a trailing , though, since your solution errors if the input is just a single number – Jo King Oct 6 at 6:58
  • 2
    @JoKing Is there a reason you could not change the != to a > as the input will never be empty? – nedla2004 Oct 6 at 18:28

Haskell, 77 75 61 bytes

f.read.('[':).(++"]")    
f a=[0|any(/=a!!0+0)a]>>show(maximum a)

Try it online!

('[':).(++"]") takes a string (e.g. "1,2,1,3") and encloses it in bracket chars ("[1,2,1,3]"). Then read turns the string into a list of integers ([1,2,1,3]).

The function f uses this tip for a shorter conditional if one of the outcomes is the empty list. any(/=a!!0+0)a checks whether the list a contains any element that is not equal to its first element a!!0. (The +0 is needed such that read knows it has to look for a list of numbers.) If all elements are equal this test results in False and the empty string is returned. Otherwise show(maximum a), that is the maximum of the list converted to a string, is returned.

  • @nimi Thanks for pointing out! – Laikoni Oct 6 at 18:48

Red, 81 bytes

x: split input","forall x[x/1: load x/1]sort x: unique x if 1 <>length? x[last x]

Like the R solution, a huge chunk of the code is handling the input string "1,1,2,44,1". If we can have that as a block, eg: x: [1 1 2 44 1], then we can do it in 41 bytes:

sort x: unique x if 1 <>length? x[last x]
  • 4
    Welcome to PPCG! We typically ask for a link to an interpreter to verify a solution, and Dennis, one of our mods, has set up Try it online! for just such a purpose! It will even format your answer for you! Hope you enjoy your time spent here! – Giuseppe Oct 6 at 0:40
  • sort x: unique load replace/all input","" "if 1 <>length? x[last x] for 67 bytes. Unfortunately input doesn't work in TIO. If you make it a func, it works just fine in TIO: 73 bytes – Galen Ivanov Oct 6 at 6:49

APL (Dyalog Unicode), 12 bytes

Full program. Prompts for string from stdin.

{1≠≢∪⍵:⌈/⍵}⎕

Try it online!

 prompt for and evaluate expression (commas concatenate the numbers into a list)

{} apply the following anonymous lambda ( is the argument; the list of numbers):

1≠ [if] 1 is different from…

 the tally of…

 the unique numbers in…

 the list

: then

⌈/ return the max across (lit. max reduction)…

 the list

 [else: do nothing]

  • 1≠≢∪ here it seems find only if its argument is a list not a repetition of the same number so it is not 1 1 1 or 22 . So 1≠≢∪1 1 2 3 3 return true even if 3 is not unique and if that is true would return ⌈/⍵ the max 3 (even if it should return no output). Where is my error? Or possible ':' has a different meaning – RosLuP Oct 10 at 9:29
  • @RosLuP Even if there are repetitions, and even repetitions of the max number, we still have to print the max. Only if the list has exactly one unique number do we print nothing. Look at the last example case in the OP. – Adám Oct 10 at 9:33
  • Yes I wrongly understood the problem... thanks – RosLuP Oct 10 at 9:38
  • would this work? ⌈/~⌊/ – ngn Oct 10 at 21:27
  • @ngn No, it outputs a newline if all elements are equal. – Adám Oct 10 at 21:43

APL (Dyalog Classic), 6 bytes

⍪⌈/~⌊/

Try it online!

a train computing the maximum (⌈/) without (~) the minium (⌊/) turned into a matrix ()

if the input contains only one distinct element, ⌈/~⌊/ will be empty and will return a 0×1 matrix which renders as nothing

otherwise, ⌈/~⌊/ will be a 1-element vector and its will be a 1x1 matrix (visually indistinguishable from a scalar) that contains the maximum

Neim, 4 bytes

𝐐𝐎Ξ𝐠

Explanation:

  Ξ   If
𝐐    all elements are equal
  𝐎  not
      then
   𝐠  get greatest element

Try it online!

  • 2
    Currently, the input must be a comma-delimited string of integers but I've asked if we can take an array instead. – Shaggy Oct 5 at 22:10

Octave, 28 bytes

Returns the maximum (a number, which is an 1x1 matrix) or an empty (1x0) matrix.

@(a)max(a)(1+all(a(1)==a):1)

Try it online!

  • 2
    Input is a string of comma separated numbers – Jo King Oct 5 at 22:49

Japt, 16 bytes

This would be 9 if not for the unnecessarily strict input format, 7 if throwing an error counts as outputting nothing.

Assumes the string contains at least 2 integers.

q, mn
â ÊÉ?Urw:P

Try it

Common Lisp, 102 bytes

(lambda(x &aux(c(read-from-string(concatenate'string"#.`("x")"))))(or(apply'= c)(princ(apply'max c))))

Try it online!

The size is mainly due to inputting the data; with input as a regular list, the length reduces to 46 bytes:

(lambda(x)(or(apply'= x)(princ(apply'max x))))

XPath 3.1, 54 bytes

with the input string as the context item:

let$t:=tokenize(.,',')!xs:int(.)return max($t)[$t!=$t]

Could be reduced by one character if you allow the context to bind a shorter prefix than "xs" to the XML Schema namespace.

Explanation: takes the input string, tokenizes on "," separator, applies xs:int() to each token to convert to an integer, computes the max of the sequence, outputs the max provided the predicate $t!=$t is true. If A and B are sequences, then A!=B is true iff there is a pair of items (a from A, b from B) such that a!=b.

If the input can be supplied as a sequence of integers $s rather than a comma-separated string then the solution reduces to

max($s)[$s!=$s]

(15 bytes - which might well be the shortest solution in a language that isn't purpose-designed for brevity)

NOTE: this doesn't satisfy the requirement "represented as it is in the input" - if there's an integer with leading zeroes or a plus sign in the input, these will be lost. I suspect that's true of many other solutions as well.

K4, 38 35 bytes

{$[1=#:t:?:(7h$","\:x)-48;;*:t@>t]}

Test Cases:

q)k){$[1=#:t:?:(7h$","\:x)-48;;*:t@>t]}"1,2,4,4"
,4
q)k){$[1=#:t:?:(7h$","\:x)-48;;*:t@>t]}"4,4,4,4"
q)
q)k){$[1=#:t:?:(7h$","\:x)-48;;*:t@>t]}"7,3,8,4,8,3,9,4,6,1,3,7,5"
,9
q)k){$[1=#:t:?:(7h$","\:x)-48;;*:t@>t]}"7,7,7,7,7,7,7,7,7,7,7,7,7"
q)

I'm not very fluent in any of the k variants available on TiO, so no online example available, I'll try to come up with one though

Explanation

If you're wondering why certain operations are performed before others, K4 does not have operator precedence, it instead interprets from right to left (though you can use parentheses for precedence). Expressions seperated by semicolons.

   $[expr;`True;`False] is the conditional format

{$[1=#:t:?:(7h$","\:x)-48;;*:t@>t]}
               ","\:x                 //split string on commas
            7h$                       //cast strings to long
                      -48             //they'll be from ascii format, so compensate
         ?:                           //get distinct list      
       t:                             //set list to variable t        
     #:                               //get count of t
   1=                                 //check if count t = 1
                         ;;           //return nothing if true
                             t@>t  //if false, sort t descending
                           *:         //return first value

Can probably be golfed down more, not a fan of having to use that makeshift max function at the end.

EDIT: If the commas in output are a problem, it can be fixed with two more bytes:

q)k){$[1=#:t:?:(7h$","\:x)-48;;*:,/t@>t]}"1,2,4,4"
4
                                 ,/                 //joins the single element lists into one

Taking the total to 40 37, but the comma before the number simply means that it's a single element list as opposed to an atom.

PHP (<=5.6) 64 74 bytes

 echo array_count_values($a=split(',',$argn))[$m=max($a)]==count($a)?'':$m;

Run as pipe with -nR or test it online

split was removed in PHP7, but as I had to add 10 to fix a few issues, it was worth using instead of explode which is roughly equivalent in this case.

  • Also this doesn't work when there are more than one element with the max value I missread the If they are all equal, return/output nothing to be If they are equal, return/output nothing meaning if there are more then one to output empty. Adding ==count($a) fixes it. Because array_count_values counts the number of times it appears in the array, if that equals the total amount of elements in the array then output '' otherwise output the max – ArtisticPhoenix Oct 7 at 4:51
  • 1
    @JoKing - You shouldn't be taking input via a pre-declared variable - fixed using $argn it takes it from stdin (this has been used in multiple golf answers) I can give examples of not only mine but other users. – ArtisticPhoenix Oct 7 at 4:57

JavaScript (Node.js), 49/53 bytes

My original version using .every(), 53 bytes

Does a function returning '' count as no output? Sure this can be improved upon...

s=>(a=s.split`,`).every(e=>a[0]==e)?'':Math.max(...a)

Try it online!


Improved version using Set() by Shaggy, 49 bytes

s=>new Set(a=s.split`,`).size>1?Math.max(...a):``

Try it online!

05AB1E, 9 8 bytes

',¡ZsËiõ

-1 byte thanks to @Cowabunghole.

Try it online or verify all test cases.

Explanation:

',¡        '# Split the (implicit) input by ","
   Z        # Push the maximum (without popping the list)
    s       # Swap so the list is at the top of the stack again
     Ëi     # If all elements are equal:
       õ    #  Push an empty string ""
            # (Implicitly output the top of the stack to STDOUT as result)
  • 1
    Pretty similar solution, but you can avoid the else by doing ',¡ZsËiõ, saving 1 byte – Cowabunghole Oct 12 at 14:24
  • @Cowabunghole Smart, thanks! – Kevin Cruijssen Oct 12 at 17:04

Python 2, 44 bytes

k=eval(input())
if~-len(set(k)):print max(k)

Try it online!

  • I'm guessing eval in Python converts a comma-delimited string to a list? – Shaggy Oct 6 at 0:28
  • 1
    Yes; more exactly a tuple (immutable list). If the input were not a string (i.e., omit quotes in TIO input section), then one could just use k=input() and get the same result. – Chas Brown Oct 6 at 0:30

Ohm v2, 9 bytes

Ul1E?Oq¿↑

Try it online! Explanation:

Ul1E?Oq¿↑
U         Uniquify input
 l        Get length
  1E      Push whether length is equak to 1
    ?Oq   If so immediately quit
       ¿↑ Else print maximum
  • 2
    The input should be a string of comma separated numbers – Jo King Oct 5 at 22:50

Charcoal, 15 bytes

≔I⪪S,θ¿›⌈θ⌊θI⌈θ

Try it online! Link is to verbose version of code. Explanation:

≔I⪪S,θ

Split the input on commas and cast each value to integer.

¿›⌈θ⌊θ

Test whether the maximum value is greater than the minimum value.

I⌈θ

If so then cast the maximum value to string and print.

Mathematica, 43 bytes

If[!Equal@@#,Max@#]&@@#~ImportString~"CSV"&

Pure function. Takes a comma-separated string as input and returns either a number or Null. I believe this is valid, as Null is not graphically displayed:

C (gcc), 91 bytes

M(s)char*s;{long m=atol(s),o,l=0;for(;s=strchr(s,44);o<0?m-=o:0)l|=o=m-atol(++s);s=l?m:-1;}

Try it online!

Degolf

M(s)char*s;{
    long m=atol(s),o,l=0; // Read the first integer from string
    for(;s=strchr(s,44); // Advance pointer to next ','
           o<0?m-=o:0) // End of loop: if difference <0, deduct from max, increasing it to new max.
        l|=o=m-atol(++s); // Read next number, and subtract it from current max. 
                          // Bitwise-OR the difference into the l-variable
    s=l?m:-1; // End of function: if l is non-zero, there were at least two different values.
              // Return -1 if l is zero, otherwise the max value.
}
  • Suggest M(char*s) instead of M(s)char*s; and index() instead of strchr() – ceilingcat Oct 7 at 17:16

Pyth, 7 bytes

Itl{QeS

Try it online!
All test cases (slightly different code for better output formatting)

As Pyth is based on Python, user input is always interpreted as a string, which then may be passed through eval(). All Pyth programs automatically run Q=eval(input()) as their first instruction.

Explanation:
Itl{QeS  | Full code
Itl{QeSQ | with implicit variables filled
---------+-------------------------------
I        | If
 t       | one less than
  l      | the length of
   {Q    | the deduplicated input
         | is truthy (!=0),
         | print
     e   | the last element of
      SQ | the sorted input

Java (JDK), 101 bytes

d->{long m=0,c=-1,b;for(var s:d.split(",")){b=new Long(s);c=c<0|c==b?b:0;m=b>m?b:m;}return c>0?"":m;}

Try it online!

Explained

d->{                            // Function taking a String input
    long m=0,c=-1,b;            // Initialise variables
    for(var s:d.split(",")){    // Split by comma and loop over elements
        b=new Long(s);          // Parse String to Long
        c=c<0                   // If c<0 (i.e. this is the first element)
            |c==b               // ...or c is equal to the current element
            ?b                  // Set c to the current element (all elements are the same so far
            :0;                 // Otherwise set c to zero to denote that list is not all same element  
        m=b>m?b:m;              // Set m to max of b and m
    }
    return c>0?""               // If c is not zero then all elements are the same, return nothing
                 :m;            // Else return max element
}

Bonus solution!

Despite my best efforts I couldn't get this solution using regex and Streams to less than 105 bytes, but I really liked its elegance so had to give it an honourary mention;

d->d.matches("(.+?)(,\\1)+")?"":java.util.Arrays.stream(d.split(",")).map(Long::new).reduce(0L,Long::max)
  • 100 bytes by using a combination of your regex (minus the ?) and a regular loop and return (instead of stream). – Kevin Cruijssen Oct 8 at 14:34

MATL, 15 9 bytes

U&=?}1MX>

Try it online!
Multiple testcases

Just trying to keep my MATL chops from getting too rusty!

Edit: rusty after all; saved 6 bytes, thanks to @LuisMendo.

Explanation

U     % str2num - automatically parses comma-separated strings
&=?   % Are all the values equal? 
}     % if not
1M    % Get the numeric matrix again on the stack
X>    % And find its maximum value.

Japt -hF, 8 bytes

q, ün Åc

Try it

-3 bytes if the input could be taken as an array.

Pip, 13 bytes

a^:',MXaRMMNa

Try it online!

Uses the approach from ngn's APL solution:

     MNa  Minimum of the list
  aRM     Remove it from the list
MX        Take the max of the remaining elements

The first 5 bytes a^:', split the input string on commas.

Alternate 13-byte solutions:

I!$=Ya^',PMXy
a^:',$=a?uMXa

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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