19
\$\begingroup\$

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!

\$\endgroup\$
8
  • 3
    \$\begingroup\$ 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 \$\endgroup\$
    – DJMcMayhem
    Oct 5, 2018 at 21:02
  • 20
    \$\begingroup\$ 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? \$\endgroup\$
    – Shaggy
    Oct 5, 2018 at 22:08
  • 17
    \$\begingroup\$ Please add a test case where the maximum occurs more than once, like 7,3,7,2. \$\endgroup\$
    – nimi
    Oct 6, 2018 at 6:31
  • 3
    \$\begingroup\$ Can we have a test case with only one element? Also, can we include a trailing , in the input? \$\endgroup\$
    – Jo King
    Oct 6, 2018 at 7:03
  • 3
    \$\begingroup\$ If there is exactly one element in the list, that means all elements are equal and the program should output nothing, correct? It would be good to add that as a test case. \$\endgroup\$
    – DLosc
    Oct 15, 2018 at 22:25

57 Answers 57

1
2
1
\$\begingroup\$

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)
\$\endgroup\$
1
  • \$\begingroup\$ 100 bytes by using a combination of your regex (minus the ?) and a regular loop and return (instead of stream). \$\endgroup\$ Oct 8, 2018 at 14:34
1
\$\begingroup\$

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

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

APL (Dyalog Unicode), 12 bytes

(⌈/↑⍨⍬≢1↓∪)⎕

Try it online!

If there were no input requirements, it could just be ⌈/↑⍨⍬≢1↓∪ for 9 bytes.

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

Perl 6, 28 22 bytes

{.max x![==] $_}o&EVAL

Try it online!

-6 bytes thanks to @ASCII-only

\$\endgroup\$
10
  • 1
    \$\begingroup\$ Links on this one as well please :P (just save the explanation somewhere and add it back in after pasting the autogenerated submission) \$\endgroup\$
    – ASCII-only
    Mar 1, 2019 at 11:10
  • \$\begingroup\$ I need to get into the habit. Ty \$\endgroup\$
    – Ven
    Mar 1, 2019 at 11:11
  • \$\begingroup\$ Preferably with the testcases in the question (and optionally more) :P (use header to assign the function, footer to run testcases) \$\endgroup\$
    – ASCII-only
    Mar 1, 2019 at 11:15
  • \$\begingroup\$ Also, seems to be invalid. "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" \$\endgroup\$
    – ASCII-only
    Mar 1, 2019 at 11:17
  • \$\begingroup\$ something like this \$\endgroup\$
    – ASCII-only
    Mar 1, 2019 at 11:19
1
\$\begingroup\$

Python 3.8 (pre-release), 45 44 bytes

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

Try it online!

First time golfing; I'm sure this can be improved.
Also a few months late to the party on this challenge, but whatever. xD

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

Gol><>, 36 bytes

TIE!tlK1}l4,MF={=}|{?;1W~2K(?$~lM|~h

4 bytes golfed off!!! I realized I was using some redundancies in there... next I think I can really make the part for checking if the array is equal smaller!

Try it online!

# Gol><>, 40 bytes

TIE!tlK1}l4,MF={S&}|{?;1W~2K(Q$~:|~lM|~h

Haha, I had my debug stuff in my previous answer, now this has golfed off 2 bytes, but I just realized how to make it even shorter

Try it online!

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

Thunno 2, 5 bytes

G$ạ?"

Attempt This Online!

Explanation

G$ạ?"  "# Implicit input
G       # Push the maximum
 $      # Push the input again
  ạ     # Is it all equal?
   ?    # If it is:
    "  "#  Push an empty string
        # Implicit output
\$\endgroup\$
1
\$\begingroup\$

TI-BASIC, 11 9 bytes

9 Bytes

If max(Ans≠max(Ans
max(Ans

Shaved 2 more bytes - implicit Disp on the final line and optimizing the condition. We instead get a single value from the input list in Ans with max( and check if it is not equal to all the other values of the list with Ans≠max(Ans. We then check if at least one of the elements in the list was different with another max( command. Ultimately this is the same number of tokens in the condition but it saves a byte by eliminating the 2 byte ΔList( command.

11 Bytes

If sum(0≠ΔList(Ans
Disp max(Ans

Takes an input list in Ans. The ΔList( command returns a list of the differences of the elements in the provided list. In TI-BASIC logic performed on lists returns a list with the operation performed on each element in that list, so 0≠ returns a list of 1s and 0s identifying if diffs of consecutive elements were 0 and therefore the elements were equal. By summing this list we identify whether all all elements were different to the next and therefore whether they were all different (we would need to sort the list first if trying to identify the number of different elements, but since we only care about whether they're all the same there's no need to sort). That whole chunk is used as the condition for whether to display the max of the input list in Ans. 11 bytes because the ΔList( command is a 2 byte token.

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

Runic Enchantments, 39 bytes

/u'!}R:'!=?\~or:}(\
\i|'<\   }n/ ;${;?/

Try it online!

Numbers have to be separated with | to be parsed from input correctly (using , causes the list to be read as a single number as , is the group separator and C# doesn't care where it's located in the string, it ignores all of them).

No possibility of removing the three spaces in the lower line, due to the loop entrance and exit locations.

Does have a limited stack size that can be processed (9 items) due to the mana cost of the sort command (and potential bleed from large stack size and low remaining mana). A slightly larger program can handle up to 14 items.

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

Actually, 9 bytes

;M@╔l1<óX

Try it online!

Actually parses comma-separated items as lists on input, so long as the items look like Python literals, so there is no overhead for the restrictive input format.

Explanation:

;M@╔l1<óX
;M         make a copy of the input, maximal element
  @╔       remove duplicates from other copy
    l1<    is 1 less than the length of the deduplicated list?
       ó   if so, immediately exit, without printing anything
        X  else, discard the length, and implicitly print the remaining stack element (the maximal element of the input list) at exit
\$\endgroup\$
0
\$\begingroup\$

Tcl, 88 bytes

proc M t {if [set f [lindex [set S [lsort -de [split $t ,]]] 0]]!=[lindex $S e] {set f}}

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Tcl, 88 bytesproc M t {expr [set f [lindex [set S [lsort -de [split $t ,]]] 0]]!=[lindex $S e]?$f:""}Try it online! \$\endgroup\$
    – sergiol
    Oct 15, 2018 at 14:21
0
\$\begingroup\$

Bash (coreutils), 28 bytes

sort -n|uniq|tail +2|tail -1

Input is a stream, one number on each line

tail +2 strips the first line, and the output is empty if it's the only line coming out from uniq, which squashes identical lines into one after sort.

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

Rust, 128 bytes

fn f(s:&str)->Option<u32>{let v=s.split(",").map(|a|a.parse::<u32>().unwrap());let x=v.clone().max();if v.min()==x{None}else{x}}

Try it online!

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

F#, 112 bytes

let m(c:string)=
 let n=c.Split ','|>Seq.map int
 if Seq.distinct n|>Seq.length=1 then None else Seq.max n|>Some

Try it online!

I get the feeling that it could be made smaller, but I can't quite see how...

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

Ruby, 39 bytes

a=eval gets
puts a.max if a.uniq.size>1

Takes an string-form array and prints the result.

\$\endgroup\$
1
  • \$\begingroup\$ Input should be taken as a string \$\endgroup\$ Oct 8, 2018 at 6:25
0
\$\begingroup\$

Java (JDK), 238 bytes

Golfed

public static String max(String s){StringTokenizer st=new StringTokenizer(s,",");TreeSet<Integer>t=newTreeSet<>();while(st.hasMoreTokens()){t.add(Integer.parseInt(st.nextToken()));}if(t.first()=t.last())return "";return Integer.toString(t.last());}

Ungolfed

import java.util.StringTokenizer;
import java.util.TreeSet;

public class max {
    public static String max(String s) {
        StringTokenizer st = new StringTokenizer(s,",");
        TreeSet<Integer> t = new TreeSet<>();
        while (st.hasMoreTokens()) {
            t.add(Integer.parseInt(st.nextToken()));
        }
        if (t.first() == t.last()) return "";
    return Integer.toString(t.last());
    }
}

I have already seen this answer, but I still wanted to share my answer.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Hey! Few general tips for golfing in Java (especially 8+); You can use the lambda declaration to shave off almost all of the public static String max(String s) preamble, try and avoid using if expressions and use ternary operators instead, and any imports (e.g. import java.util.*) count towards your byte count, so avoid if possible! Anyway, check out this link for a whole load of tips and welcome to CodeGolf! \$\endgroup\$ Oct 8, 2018 at 8:13
  • \$\begingroup\$ @LukeStevens Thanks for the tips! I will work on fixing this answer soon! \$\endgroup\$
    – Jaden Lee
    Oct 10, 2018 at 2:31
0
\$\begingroup\$

Ruby -aplF,, 38 bytes

$_=$F.uniq.one?? p: $F.map(&:to_i).max

Try it online!

I'm generally not a fan of extensively using command line switches, but since the I/O format is very rigid - here it goes.

The input is automatically (-a) split into an array $F using comma as a separator (-F,). If it contains only one unique element, we return nil, otherwise, the max value. Finally, the output written into $_ is implicitly printed (-p). The option -l isn't really necessary - it is only there to make empty outputs discernible by line breaks.

Update: Almost forgot that we don't automatically get integers from split, just strings, which brings more boilerplate...

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

Perl 5 -n -M5.010, 54 bytes

use List::Util'/.+/';@n=split/,/;uniq(@n)>1&&say max@n

Try it online!

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

V, 22 bytes

Ó,/ò
ún
Dç^"$/d
GYVHp

Try it online!

Hexdump:

00000000: d32c 2ff2 0afa 6e0a 44e7 5e12 2224 2f64  .,/...n.D.^."$/d
00000010: 0a47 5956 4870                           .GYVHp

Explanation:

Ó,/ò                Replace commas with new lines
ún                  Sort; cursor ends up in first line
D                   Delete line (smallest number)
 ç^<C-r>"$/d        Delete all lines that contain the same number
GYVHp               Go to last line, copy, select all, paste
                    If all numbers are equal, the buffer is empty and nothing will be copied,
                    resulting in an empty output
\$\endgroup\$
0
0
\$\begingroup\$

PHP, 57 bytes

<?=count(array_unique($a=split(",",$argn)))>1?max($a):"";

requires PHP<7; replace split with explode for current PHP (+2 bytes):

<?=count(array_unique($a=explode(",",$argn)))>1?max($a):"";

Run as pipe with -nR or try them online.

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

Ruby, 32 bytes

->l{eval(l).minmax.uniq[1,1]*''}

Try it online!

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

Scala (91 79 bytes):

def f(s:String){val i=s.split(",");if(i.toSet.size>1)print(i.map(_.toInt).max)}

Try it online

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

Bash, 36 bytes

tr , \\n|sort -un|tail -n+2|tail -n1

takes input on stdin, outputs to stdout

$ echo 1,2,3 | ./f.sh
3
$ echo 1,1,1 | ./f.sh
$ echo 123,231,321,312 | ./f.sh
321
\$\endgroup\$
0
\$\begingroup\$

Java (JDK), 112 108 117 bytes

s->{return java.util.Arrays.stream(s.split(",")).mapToLong(Long::new).distinct().sorted().skip(1).max().getAsLong();}

Try it online!

Either returns a long or throws an exception, which presumably counts as not returning anything.

Edit: Fixed a bug that caused incorrect output if the maximum was the first element of the input. (+9 bytes)

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

JavaScript (Node.js), 53 bytes

s=>(s=s.split`,`.sort((a,b)=>a-b))[0]-s.pop()?s[0]:''

Try it online!

Worse than Shaggy's

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

C (gcc), 86 bytes

a;g(){scanf("%d,",&a);}f(b,c){for(b=g(),c=a;~g();c=a>c?a:c)b&=a==c;b||printf("%d",c);}

Try it online!

Read stdin and write stdout

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