title: The max() is not enough

text:
# Question
Title: The max() is not enough
## 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!

# Answer
# , ~~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!
> 8 votes

# Answer
# 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

```
> 5 votes

# Answer
# 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.
> 5 votes

# Answer
# 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)

```
> 5 votes

# Answer
# 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\]
> 4 votes

# Answer
# 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
> 4 votes

# Answer
# CJam, ~~16~~ 13 bytes

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

```

Try it online!
> 3 votes

# Answer
# 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!
> 3 votes

# Answer
# Python 2, ~~42~~ 41 bytes

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

```

Try it online!
> 3 votes

# Answer
# 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.
> 3 votes

# Answer
# 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]

```
> 3 votes

# Answer
# Python 2, 37 bytes

outputs to stderr (debug on tio).

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

```

Try it online!
> 3 votes

# Answer
# Neim, 4 bytes

```
Ξ

```

Explanation:

```
  Ξ   If
    all elements are equal
    not
      then
     get greatest element

```

Try it online!
> 2 votes

# Answer
# 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.
> 2 votes

# Answer
# 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 votes

# Answer
# 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
> 2 votes

# Answer
## 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.
> 2 votes

# Answer
# 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))))

```
> 2 votes

# Answer
# 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)

```
> 2 votes

# Answer
# Japt `-hF`, 8 bytes

```
q, ün Åc

```

Try it

`-3` bytes if the input could be taken as an array.
> 2 votes

# Answer
# PowerShell, ~~45~~ 49 bytes

*+4 bytes thanks Veskah*

```
($l=$args-split','|sort{+$_}-u)[-1]|?{$l.count-1}

```

Try it online!

Less golfed:

```
$list=$args-split','|sort{+$_}-unuqie
$max=$list[-1]
$max|?{$list.count-1}

```
> 2 votes

# Answer
# Vyxal, 5 bytes

```
≈[¤|G

```

Try it Online!

```
≈[    # If all same
  ¤   # ""
   |G # Else max

```
> 2 votes

# Answer
# Jelly, 3 bytes

```
ṀḟṂ

```

Try it online!

TIO link uses function I/O for the sake of having a test harness, but it works just fine with a plain comma-separated list. I'd prefer to let a challenge like this stay dead, but if it's been bumped anyways...

```
Ṁ      The maximum,
 ḟ     unless it's equal to
  Ṃ    the minimum.

```
> 2 votes

# Answer
# Python 2, 44 bytes

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

```

Try it online!
> 1 votes

# Answer
# 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

```
> 1 votes

# Answer
# 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

```
> 1 votes

# Answer
# Charcoal, 15 bytes

```
≔Ｉ⪪Ｓ,θ¿›⌈θ⌊θＩ⌈θ

```

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

```
≔Ｉ⪪Ｓ,θ

```

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

```
¿›⌈θ⌊θ

```

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

```
Ｉ⌈θ

```

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

# Answer
# 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:
> 1 votes

# Answer
# 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.
}

```
> 1 votes

# Answer
# 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.
> 1 votes

# Answer
# 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)

```
> 1 votes

# Answer
# 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.

```
> 1 votes

# Answer
# 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

```
> 1 votes

# Answer
# Perl 6, ~~28~~ 22 bytes

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

```

Try it online!

-6 bytes thanks to @ASCII-only
> 1 votes

# Answer
# APL (Dyalog Unicode), 12 bytes

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

```

Try it online!

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

# Answer
# 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
> 1 votes

# Answer
# 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!
> 1 votes

# Answer
# 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

```
> 1 votes

# Answer
# 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.
> 1 votes

# Answer
# 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.
> 0 votes

# Answer
# 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

```
> 0 votes

# Answer
# 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!
> 0 votes

# Answer
# Ruby, 39 bytes

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

```

Takes an string-form array and prints the result.
> 0 votes

# Answer
# 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`.
> 0 votes

# Answer
# 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!
> 0 votes

# Answer
## 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...
> 0 votes

# Answer
# **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.
> 0 votes

# Answer
# 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...
> 0 votes

# Answer
# , 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

```
> 0 votes

# Answer
# Perl 5 -n -M5.010, 54 bytes

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

```

Try it online!
> 0 votes

# Answer
# 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.
> 0 votes

# Answer
# Ruby, 32 bytes

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

```

Try it online!
> 0 votes

# Answer
# 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
> 0 votes

# Answer
# 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)
> 0 votes

# Answer
## 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

```
> 0 votes

# Answer
# 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
> 0 votes

# Answer
# 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
> 0 votes

---
Tags: code-golf
---


title: Parse basic arithmetic into an AST

text:
# Question
Title: Parse basic arithmetic into an AST
# Introduction

An abstract syntax tree (AST) is a tree of tokens that shows their connection to each other and syntactical meaning. They are commonly used in compilers and static analysis tools, as parsing a language into an AST helps remove any ambiguity and can be helpful for optimizations. Many ASTs are large and complex, but in this thread, your task is to create a basic parser to convert an arithmetic expression into a basic AST.

# Challenge

The main part of this challenge is resolving the order of operations. In this challenge, assume PEMDAS so that multiplication is before division and addition is before subtraction. Also, assume left associativity. Every node in the tree should either be an operator or a number. Operators with other operators as children resolve their children first, so nodes at the bottom of the tree resolve first. Number nodes should have no children. Your solution may assume the input is valid, all numbers are positive, and that the input contains no parentheses (unless you'd like to add support for fun).

The input will be a string with only the characters `0123456789+-*/` (and optionally `()`). Your program/function may return nested objects/dictionaries, nested arrays/lists, or even a built-in data structure; as long as your output can be interpreted as a tree you're OK (note: if you are going to abuse this rule by using weird formats, then explain how it represents a tree).

### Test cases

`1+2+3*5-7` -\> `['-', ['+', ['+', 1, 2], ['*', 3, 5]], 7]`, where the first element of the array is the operator, and the second and third are the children.

`13*7+9-4+1` -\> `{op: '-', left: {op: '+', left: {op: '*', left: 13, right: 7}, right: 9}, right: {op: '+', left: 4, right: 1}}`

`8/2*6+4-1` -\> `['-', ['+', ['/', 8, ['*', 2, 6]], 4], 1]`

This is , so the shortest code wins!

# Answer
# Vyxal ~~44~~ 23 bytes

```
λ`+-:*`(n~ḟ0>[:∇ẇWfvx|_

```

Thanks to @emanresuA for full refactoring, I began to understand better how lambda works.

```
    λ        # Open lambda
    `+-:*`(  # Open loop over operators
    n~ḟ0> [  # If there is such operator
    :∇ẇWf   # Split and wrap into list
    vx       # Recursive call lambda as map
    |_       # If there is no continue
             # ]); Closing If, loop and lambda
                 expected but not required

```
> 4 votes

# Answer
# Python, ~~69~~ 68 bytes

```
f=lambda x:[*([i,*map(f,x.split(i,1))]for i in'-+/*'if i in x),x][0]

```

Attempt This Online!
> 7 votes

# Answer
# JavaScript (Node.js), 82 bytes

```
f=(x,i=5,b,j=x.split(b=' */+-'[--i]))=>i?j[1]?[f(j.pop()),b,f(j.join(b))]:f(x,i):x

```

Try it online!

Seem not that golfed but anyway

Output is reversed
> 5 votes

# Answer
# sed, 96 bytes

```
s/^/x_/
:a
s/([^*/+-]*)\*([^*/+-]*)/['_',\1,\2]/
ta
y#/+-_SAD#*/+SADM#
/xM/!ba
s///
y#MDAS#*/+-#

```

Attempt This Online!
> 5 votes

# Answer
# Wolfram Language 99 bytes

Wolfram Language have built-in tools for working with AST, for example

```
FullForm@MakeExpression@"1-(4/2)+3*(5+7)"

```

produce

```
HoldComplete[Plus[1,Times[-1,Times[4,Power[2,-1]]],Times[3,Plus[5,7]]]]

```

and

```
TreeForm@MakeExpression@"1-(4/2)+3*(5+7)"

```

produce

But firstly it looks like cheating. Secondly, it's a bit difficult to obtain the required form from WL output.
Maybe someone can do it, it will be interesting.
Here is a solution based on more common functions.

```
If[StringLength@#1 == 1,#1,#0/@StringSplit[#1, x__ ~~ # ~~ y__ :> {#,x,y}&/@ {"-", "+", "/", "*"}, 2][[2]]]&

```
> 5 votes

# Answer
# Charcoal, 63 bytes

```
≔⟦Ｓ⟧θ⊞υθＦ-+/*ＦΦυ№§κ⁰ι«≔Ｅ⮌⪪⊟κι⟦λ⟧ζＦζ⊞υλＷ⊖Ｌζ⊞ζ⟦ι⊟ζ⊟ζ⟧Ｆ⊟ζ⊞κλ»⁻⭆¹θ'

```

Try it online! Link is to verbose version of code. Outputs values in one-element sublists and operators in three-element sublists. Explanation:

```
≔⟦Ｓ⟧θ

```

Wrap the input string in a list.

```
⊞υθ

```

Push it to the list of lists to be processed.

```
Ｆ-+/*

```

Loop over the operators in ascending order of precedence.

```
ＦΦυ№§κ⁰ι«

```

Loop over the terms that contain this operator.

```
≔Ｅ⮌⪪⊟κι⟦λ⟧ζ

```

Remove the term from its list, split it on the operator, and wrap all of the resulting terms in lists.

```
Ｆζ⊞υλ

```

Push all of those lists to the list of lists to be processed.

```
Ｗ⊖Ｌζ⊞ζ⟦ι⊟ζ⊟ζ⟧

```

Build up consecutive terms into a nested structure.

```
Ｆ⊟ζ⊞κλ

```

Re-insert the top-level terms back into the original list.

```
»⁻⭆¹θ'

```

Pretty-print the final list.
> 3 votes

# Answer
# Retina, 53 bytes

```
+0`(\w+)\*(\w+)
aUb$1b$2c
4}T`V*/+-`_o
T`abcV`[,]*/+-

```

Try it online! Link includes test cases. Explanation: Port of @Jiří's sed answer.

```
(\w+)\*(\w+)
aUb$1b$2c

```

Replace (parameter)`*`(parameter) with `[*,`(parameter)`,`(parameter)`]`, except encoding `*` with `U`, `[` with `a`, `,` with `b` and `]` with `c` as they are all letters and will therefore be treated as part of the same parameter in subsequent replacements (both with the current operator and with subsequent operators of lower precedence).

```
0`

```

Only perform one replacement at a time.

```
+`

```

Repeat the above replacement until no more changes can be made.

```
T`V*/+-`_o

```

Step the operators and their encodings in sequence so that `-` becomes `+` etc. allowing each operator in turn to be encoded as a `U`, but those then in turn get stepped to previous vowels.

```
4}`

```

Repeat the whole of the above four times, once for each operator.

```
T`abcV`[,]*/+-

```

Translate all of the letter placeholders back to the characters they represent.
> 2 votes

# Answer
# Haskell \+ hgl, 61 bytes

```
z#y=Fe<Rv<sQ[y<*χ z,z#y,p3 z]++y

```

```
gk$bkw$rF(#)(p<rv<dg_)"-+/*"

```

## Explanation

This takes input as a string and outputs as a `Free List String`. In haskell a list can only contain one type of thing. A free list of strings is basically a list that is allowed to contain strings or other free lists of strings. That makes it the perfect sort of structure for this challenge.

A good deal of the machinery here is devoted to making things left associative. *Right* associativity would be quite easy, but if we naively modify the algorithm to be left associative it creates recursion without a base case. So what we do instead is that we actually just do right associativity but parse the entire thing backwards. Of course this means we have to do a bunch of extra reversing things, but that's how it goes.

For reference here's a right associative version:

```
z#y=Fe<sQ[pp[z],y<*χ z,z#y]++y

```

```
gk$rF(#)(p<dg_)"-+/*"

```

It's 9 bytes shorter.

The actual code is quite extensible. We do a fold over a list of operations, and adding new operations is as simple as adding their symbol in the right spot (later entries have higher precedence).

## Reflection

This is pretty alright, there could be some improvements.

* `m p` should get a shorthand. I keep thinking it already exists, but I can't find it, so I should make it.
* I wasn't able to use `(*:*)`, but if it had a prefix version I could.
* Although I use `p3`, I did at one point have a chain of 4 `p`s, so I guess `p4` has a potential use.
* `bkw` doesn't save any bytes here over just using `Rv`. It's a nice little function and I was excited to use it here, but it seems of limited use. Probably not deserving of a 2 byte name though.
> 2 votes

# Answer
# Go, 79 bytes

```
import(."go/parser";."go/ast")
func f(s string)Expr{e,_:=ParseExpr(s)
return e}

```

Attempt This Online!

Returns an `ast.Expr` from `go/ast` in Go's standard library, which represents a Go expression.
> 1 votes

---
Tags: code-golf, string, arithmetic, parsing
---


title: Have you heard of tralindromes?

text:
# Question
Title: Have you heard of tralindromes?
I haven't. :P So I decided to define one:

A **tralindrome** is a string which contains three equal-length sections X, Y, Z such that

* all characters in the string are included in at least one of the three sections,
* X starts at the first character, Y starts at or right after the last character of X, and Z starts at or right after the last character of Y:
```
abcdefgh  or  abcdefgh
XXX           XXX
  YYY            YYY
     ZZZ           ZZZ

```
* and X is equal to the reverse of Y, and Y is equal to the reverse of Z.

Some examples of tralindromes:

```
a       (a / a / a)
bb      (b / b / b) - note that there are two possible choices for Y
ccc     (c / c / c)
coco    (co / oc / co)
mamma   (ma / am / ma)
uhhuh   (uh / hu / uh)
xyyxxy  (xy / yx / xy)
banaban    (ban / nab / ban)
dottodot   (dot / tod / dot)
dadadadada (dada / adad / dada)

```

non-tralindromes:

```
xy
coc
faff
xyzzy
mummy
random
hotshot
tralindrome
dadadadadada
aabaabaaaabaa
abccbacbaabcabc

```

Given a nonempty string that entirely consists of lowercase letters, determine if it is a tralindrome.

For output, you can choose to

* output truthy/falsy using your language's convention (swapping is allowed), or
* use two distinct, fixed values to represent true (affirmative) or false (negative) respectively.

Shortest code in bytes wins.

# Answer
> 16 votes
# Regex (Perl / PCRE2 / Boost / Python`regex`), ~~59~~ ~~47~~ ~~46~~ ~~38~~ ~~37~~ ~~33~~ 32 bytes

```
^((.+)((.)(?3)\4|(?=\2$).?))?.?$

```

Try it online! \- Perl v5.28.2 / Attempt This Online! \- Perl v5.36+
Try it online! \- PCRE2 v10.33 / Attempt This Online! \- PCRE2 v10.40+
Try it online! \- Boost
Attempt This Online! \- Python `import regex`

This has been a special-case rollercoaster. The original versions needed `|^.$` to match one-character strings – and then two 38 byte versions suddenly didn't need that anymore, and just naturally matched one-character strings. And then at 37 the `|^.$` was back... it stuck around during the drop to 33 bytes.

Now at 32 bytes, it's still there, but hiding. It's subsumed into the rest of the expression, at the cost of also matching an empty string (which is allowed by the challenge's rules).

The following explanation is for the 33 byte version, because it's easier to format the comments. The transformation is `^pattern.?$|^.$``^(pattern)?.?$`, with all of `pattern`'s capture group indices incremented by 1.

```
^                 # Anchor start
(.+)              # Match the longest prefix that we conjecture (but later prove)
                  # recurs as a suffix, and capture it in \1.
# Match the palindromic subsection at the end, using recursion
(                 # Define recursive subroutine (?2)
    (.)           # \3 = one character from the left side
    (?2)          # Call self recursively
    \3            # Match the same character on the right side
|           # or...
    (?=\1$)       # End the recursion. Assert that the remaining suffix exactly
                  # matches the prefix we captured.
    .?            # Optionally skip one character, which will happen if the
                  # palindromic portion is odd in length.
)
.?                # Optionally skip one character at the end. This will have been
                  # verified already by the "(?=\1$)" above, so we don't need to
                  # do so again.
$                 # Assert we've reached the end of the string.
|^.$              # Match a one-character string as a special case, since the
                  # above algorithm only works on multi-character tralindromes.

```

A previous 38 byte version was PCRE2-only due to use of non-atomic lookahead, but that has turned out to be unnecessary.

# Regex (Ruby), ~~53~~ ~~52~~ ~~44~~ ~~43~~ ~~39~~ 38 bytes

```
^((.+)((.)\g<3>\k<4+0>|(?=\2$).?))?.?$

```

Try it online!

This is the ~~47~~ ~~46~~ ~~38~~ ~~37~~ ~~33~~ 32 byte regex ported to Ruby's subroutine call syntax. `\k<4+0>` retrieves `\4` from the current level of recursion, whereas what `\4` would retrieve may have been overwritten at a deeper level of recursion.

# Regex (.NET), 35 bytes

```
^(.?(.)*.?)(?<-2>\2)*(?(2)^)\1$|^.$

```

Try it online!

From Neil's Retina answer; please see his post for the explanation. Beats my .NET regex by ~~20~~ ~~12~~ ~~11~~ ~~7~~ 6 bytes.

I have ported it to my style here, optimizing for the best speed at its length. Moving the special-case test to the end should make it theoretically faster to match any valid multi-character tralindrome, at the cost of being slower to match a one-character string.

Ported to PCRE2, this is 55 bytes, demonstrating that what's optimal in one regex engine isn't necessarily so in others:

```
^(?*((.?).*(?=(.*))(.?)))\2((.)(?5)\6|(?=\3$)\4)\1$|^.$

```

Attempt This Online! \- PCRE2 v10.40+

# Regex (.NET), ~~64~~ ~~63~~ ~~55~~ ~~47~~ ~~46~~ ~~42~~ 41 bytes

```
^((.+)(.)*(?=\2$).?(?<-3>\3)*(?(3)^))?.?$

```

Try it online!

At ~~55~~ ~~47~~ ~~46~~ ~~42~~ 41 bytes, this is now a port of the ~~38~~ ~~37~~ ~~33~~ 32 byte Perl/PCRE2/Boost regex.

`((.)(?3)\4|pattern3.?)` becomes `(.)*pattern3.?(?<-3>\3)*(?(3)^)`, using .NET's balancing groups instead of recursion to match the palindromic subsection:

`(.)*` \- capture the left half of the palindrome, pushing it onto the `\3` stack one character at a time.

`.?` \- optionally skip one character, in the case that the palindrome is odd in length.

`(?<-3>\3)*` \- pop every character off the `\3` stack, matching them in reverse order.

`(?(3)^)` \- assert that if the `\3` stack isn't empty, then something impossible (that we're at the start of the string) is true – i.e. assert that the `\3` stack is empty.

# Regex (Perl / PCRE / .NET), ~~61~~ ~~57~~ 51 bytes

```
^(.+)((.?)(?=.*?(\3(?(4)\4|.?)$)))+(?=\1$).?\4$|^.$

```

Try it online! \- Perl v5.28.2 / Attempt This Online! \- Perl v5.36+
**Try it online! \- PCRE1**
Try it online! \- PCRE2 v10.33 / Attempt This Online! \- PCRE2 v10.40+
Try it online! \- .NET

This is a port of the ~~46~~ ~~38~~ 33 byte Perl/PCRE2/Boost version, to regex engines that don't have recursion (or do have it, but not in a non-atomic form, in the case of PCRE1). To match the palindromic subsection, group-building (with a nested backreference) is used instead of recursion.

# Regex (Java / Perl / PCRE / .NET), ~~66~~ 56 bytes

```
^(.+?)((.?)(?=.*?(\3(\4|(?!\6).?)$))())+(?=\1$).?\4$|^.$

```

**Try it online! \- Java 12.0.2 / Attempt This Online! \- Java 18.0.1+**
Try it online! \- Perl v5.28.2 / Attempt This Online! \- Perl v5.36+
Try it online! \- PCRE1
Try it online! \- PCRE2 v10.33 / Attempt This Online! \- PCRE2 v10.40+
Try it online! \- .NET

This is a port of the ~~61~~ 51 byte Perl/PCRE/.NET version, to regex engines that don't have conditionals but do have nested backreferences.

Java seems to have some bugs in its regex engine, especially in the vein of giving up on backtracking when there are too many possibilities (and there don't even have to be all that many). To work around this, `(.+?)` is used instead of `(.+)`. If Java's regex engine were really behaving well, this wouldn't be necessary.

Some other variants don't play nice in Java. For example, a port of the previous 57 byte Perl/PCRE/.NET version is **62 bytes**:

```
^(.*)(?=(.)).?((.)(?=.*(\4(\5()|(?!\7))$)))*(?=\1\2$).?\5$|^.$

```

But fails in Java: Try it online! (12.0.2) / Attempt This Online! (18.0.1+)
This warrants further research.

# Regex (Perl / PCRE / Python`regex` / .NET), ~~61~~ 59 bytes

```
^(.+)((.?)(?=.*?(?=(\3(?(5)\5|.?)$))(\4)))+(?=\1$).?\4$|^.$

```

Try it online! \- Perl v5.28.2 / Attempt This Online! \- Perl v5.36+
Try it online! \- PCRE1
Try it online! \- PCRE2 v10.33 / Attempt This Online! \- PCRE2 v10.40+
**Attempt This Online! \- Python `import regex`**
Try it online! \- .NET

This is a port of the 51 byte Perl/PCRE/.NET regex to engines that lack nested backreferences. To emulate them, `\4` and `\5` are copied back and forth to each other.

Ruby does not work with this regex at all. It just hangs.

# Regex (Java / Perl / PCRE / Python`regex` / .NET), 64 bytes

```
^(.+?)((.?)(?=.*?(?=(\3(\6|(?!\7).?)$))(\4))())+(?=\1$).?\4$|^.$

```

Try it online! \- Java 12.0.2 / Attempt This Online! \- Java 18.0.1+
Try it online! \- Perl v5.28.2 / Attempt This Online! \- Perl v5.36+
Try it online! \- PCRE1
Try it online! \- PCRE2 v10.33 / Attempt This Online! \- PCRE2 v10.40+
Try it online! \- Python `import regex` / Attempt This Online!
Try it online! \- .NET

This combines both the 56 Java and 59 byte Python ports, to support five different regex engines.

## \\$\large\textit{Anonymous functions}\\$

# Perl, ~~49~~ ~~45~~ 44 bytes

```
sub{pop=~/^((.+)((.)(?3)\4|(?=\2$).?))?.?$/}

```

Try it online!

# Ruby, ~~53~~ ~~49~~ 48 bytes

```
->s{s=~/^((.+)((.)\g<3>\k<4+0>|(?=\2$).?))?.?$/}

```

Try it online!

# PowerShell, 48 bytes

```
$args-match'^(.?(.)*.?)(?<-2>\2)*(?(2)^)\1$|^.$'

```

Try it online!

# Julia v1.2+, ~~54~~ ~~50~~ 49 bytes

```
s->endswith(s,r"^((.+)((.)(?3)\4|(?=\2$).?))?.?")

```

Attempt This Online!

# , ~~58~~ ~~53~~ 52 bytes

```
\(L)grepl('^((.+)((.)(?3)\\4|(?=\\2$).?))?.?$',L,,1)

```

Attempt This Online!

# PHP, ~~64~~ ~~60~~ 59 bytes

```
fn($s)=>preg_match('/^((.+)((.)(?3)\4|(?=\2$).?))?.?$/',$s)

```

Try it online!

# Python (with `regex`), 71 bytes

```
lambda s:regex.match(r'((.+)((.)(?3)\4|(?=\2$).?))?.?$',s);import regex

```

Attempt This Online!

# Python (with `regex`), 72 bytes

```
lambda s:__import__('regex').match(r'((.+)((.)(?3)\4|(?=\2$).?))?.?$',s)

```

Attempt This Online!

(If it must be a pure lambda.)

# Java, ~~85~~ 75 bytes

```
s->s.matches("((.+?)((.?)(?=.*?(\\4(\\5|(?!\\7).?)$))())+(?=\\2$).?\\5)|.")

```

Try it online!

## \\$\large\textit{Full programs}\\$

# Perl `-p`, ~~42~~ ~~38~~ 37 bytes

```
$_=/^((.+)((.)(?3)\4|(?=\2$).?))?.?$/

```

Try it online!

# Ruby `-n`, ~~47~~ ~~43~~ 42 bytes

```
p~/^((.+)((.)\g<3>\k<4+0>|(?=\2$).?))?.?$/

```

Try it online!

Prints `nil` for false and `0` for true, which are respectively falsey and truthy in Ruby. If printing `0` or `1` is desired, replace `p~` with `p !!` (+2 bytes).

# PHP `-F`, ~~63~~ ~~59~~ 58 bytes

```
<?=preg_match('/^((.+)((.)(?3)\4|(?=\2$).?))?.?$/',$argn);

```

Try it online! \- bare-bones test harness
Try it online! \- fancier test harness

# Answer
> 13 votes
# Curry (PAKCS), 38 bytes

-14 bytes thanks to @Bubbler.

```
g a=a?tail a
f(a++g(reverse a)++g a)=1

```

Try it online!

---

# Curry (PAKCS), 52 bytes

```
f([_]?(a++reverse(g a)++a))=1
g(a?(a++[_]))=a?tail a

```

Try it online!

Returns `1` for truth, and nothing otherwise.

## How?

Returns `1` when the input is either:

* a single character, or
* in the form `a ++ reverse b ++ a`, where `b` is one of the following:
    + `a`,
    + removing the first character from `a`,
    + removing the last character from `a`,
    + removing the first and the last characters from `a`.

# Answer
> 9 votes
# Python, 72 bytes

```
lambda s:1>s.find(s[(l:=len(s))//-3:])<=s.find(s[-~-l//3-1::-1])<=l%3//2
```

Attempt This Online!

### Previous Python, 74 bytes

```
lambda s:s.find(u:=s[(l:=len(s))//-3:])<1>=s[l//3:l-l//3].find(u[::-1])>=0
```

Attempt This Online!

### Previous Python, 88 bytes

```
lambda s:{s[~(n:=len(s)//-3)::-1]}&{s[:n-1:-1]}&{s[n-~n:~n-n],s[-n:n],s[~n:n],s[-n:-~n]}
```

Attempt This Online!

Returns the middle copy of the "template" as a singleton set (which is truthy in Python) or the empty set (falsy in Python).

### Previous Python, 90 bytes (-1 @Steffan)

```
lambda s:s[~(n:=len(s)//-3)::-1]in(s[n:]==s[:-n])*[s[n-~n:~n-n],s[-n:n],s[~n:n],s[-n:-~n]]
```

Attempt This Online!

Sort of similar to @alephalpha's logic now.

### Previous wrong Python, 85 bytes

```
lambda s:s[~(n:=len(s)//-3)::-1]in(s[n:]==s[:-n])*(s[2*n:n],s[-n:-2*n],s[n-~n:-n+~n])
```

Attempt This Online!

Fails on aabaabaaaabaa (false positive).

# Answer
> 9 votes
# JavaScript (Node.js), 60 bytes

```
s=>[...s,l=r=''].some(t=>s.match(`^${l+=t}?${r=t+r}?${l}$`))

```

Try it online!

# Answer
> 9 votes
# Python 3.8 (pre-release), 61 bytes

```
lambda s:s[1:~(m:=-len(s)//3)]in s[m-1:~m:-1]in s[:-m]==s[m:]

```

Try it online!

* If the full string S has length \\$L\\$, then the length \\$l\\$ of each of the three sections is \\$\lceil\frac{L}{3}\rceil \\$; \\$m = \lfloor\frac{-L}{3}\rfloor = -\lceil\frac{L}{3}\rceil = -l\\$.
* The sections X and Z are extracted as `s[:-m]` and `s[m:]`; they must be equal.
* The remainder of the string, reversed, which is `s[m-1:~m:-1]`, must be X with the first and last characters each possibly removed. This is equivalent to it being a substring of X and a superstring of (X with the first and last characters removed).
(There is a subtlety to why this equivalence is true.
The generalisation to removing up to \\$k\\$ characters from each end is false: for X=`dedent` and \\$k=2\\$, `ded` is a substring of X and a superstring of the central part `de`, but cannot be obtained from X by removing up to 2 characters from each end.
However, the original equivalence (which is the \\$k=1\\$ case) is true. If the length is reduced by 2, that is the same as the central part's length, so it can only be a superstring of the central part if it is equal. If the length is reduced by 1 or 0, then for it to be a substring of X, it can only be X with one end possibly removed.)
* Chaining of comparisons is used to check all those conditions together concisely.
* The \\$L=1\\$ case is a bit different, but it works out because negative-length slices produce empty strings in Python.

# Answer
> 8 votes
# , 31 bytes

```
<e.[:;&.>@,(<{@;g@|.,g=.<@;}.)\

```

Try it online!

Inspired by alephalpha's Curry answer, and Bubbler's edit.

It's a bit ugly mechanically, but I like the simplicity of the idea.

For each prefix, we create the Cartesian product of:

1. \[prefix\]
2. \[prefix reversed, tail of prefix reversed\]
3. \[prefix, tail of prefix\]

And then check if the input is equal to any of the elements of any of the Cartesian products.

# Answer
> 6 votes
# lin, 69 bytes

```
.+.#a $`.a len `t1+ `t \; `|
.+ `rev \`_`.' ,.a"^%s?%s?%1$s$".@ sf ?t

```

Try it here! Switched to an approach inspired by @tsh because previous approach - although interesting - sucked at handling the edge cases.

For testing purposes:

```
"mamma" ; outln
.+.#a $`.a len `t1+ `t \; `|
.+ `rev \`_`.' ,.a"^%s?%s?%1$s$".@ sf ?t

```

## Explanation

Prettified code:

```
.+.#a $` .a len `t 1+ `t \; `|
.+ `rev \`_`.' , .a "^%s?%s?%1$s$".@ sf ?t

```
* `.+.#a` store input as *a*
* `$` .a len `t 1+ `t` generate prefixes
* `\; `|` check if any are true...
    + `.+ `rev` duplicate prefix, reverse
    + `\`_`.'` convert to string
    + `,` pair
    + `"^%s?%s?%1$s$".@ sf` turn into regex (templated as *x*, *y*, *x*)
    + `.a ... ?t` check if regex matches

# Answer
> 6 votes
# Retina 0.8.2, 35 bytes

```
^.$|^(.?(.)*.?)(?<-2>\2)*(?(2)^)\1$

```

Try it online! Link includes test cases. Explanation: Port of @alephalpha's Curry explanation.

```
^.$|

```

Match a single character, or...

```
^(.?(.)*.?)

```

... a leading substring, capturing a substring of that which optionally skips the first and/or last characters, ...

```
(?<-2>\2)*(?(2)^)

```

... the inner substring in reverse, ...

```
\1$

```

... and the leading substring again.

# Answer
> 5 votes
# Brachylog, ~~20~~ 19 bytes

```
~cṪ{|~k}ʰ{|~b}ᵗ↺↔ʰ=

```

Try it online!

### Explanation

```
~cṪ                   Deconcatenate the input into 3 strings
   {|~k}ʰ             Do nothing, or add an unknown trailing char to the first string
         {|~b}ᵗ       Do nothing, or add an unknown leading char to the last string
               ↺↔ʰ    Reverse the middle string
                   =  The 3 strings must be equal

```

# Answer
> 5 votes
# 05AB1E, 15 bytes

```
ηεºyû‚yy¦‚δ«}Qà

```

Try it online or verify all test cases.

**Explanation:**

```
η         # Get the prefixes of the (implicit) input-string
 ε        # Map over each prefix:
     ‚    #  Push a pair of:
  º       #   The mirrored version of the prefix
   yû     #   And the palindromized version of the prefix
          #    e.g. "abc" → ["abccba","abcba"]
     ‚    #  Push another pair of:
  y       #   The prefix
   y¦     #   And the prefix minus its first character
          #    e.g. "abc" → ["abc","bc"]
      δ   #  Apply double-vectorized over the two pairs:
       «  #   Append
          #    → [["abccbaabc","abccbabc"],["abcbaabc","abcbabc"]]
 }        # Close the map
  Q       # Check if any inner-most string is equal to the (implicit) input
   à      # Check if any is truthy by taking the flattened maximum
          # (which is output implicitly as result)

```

# Answer
> 4 votes
# Charcoal, 32 bytes

```
⊙θ⊙Ｅ⊕κ⮌✂θμ⊕κ¹Φ²∧⁼…θ⁺μξλΦ²⁼λ✂θ⁺κρ

```

Try it online! Link is to verbose version of code. Outputs a Charcoal boolean, i.e. `-` for a tralindrome, nothing if not. Explanation: Brute-force search for a substring whose reverse equals its possibly overlapping prefix and suffix.

```
 θ                                  Input string
⊙                                   Any index satisfies
     κ                              Current index
    ⊕                               Incremented
   Ｅ                                Map over implicit range
        θ                           Input string
       ✂    ¹                       Sliced from
         μ                          Inner index to
           κ                        Outer index
          ⊕                         Incremented
      ⮌                             Reversed
  ⊙                                 Any reversed substring satisfies
              ²                     Literal integer `2`
             Φ                      Filter over implicit range
                  θ                 Input string
                 …                  Truncated to length
                    μ               Inner index
                   ⁺                Plus
                     ξ              Optional overlap
                ⁼                   Equals
                      λ             Reversed substring
               ∧                    Logical And
                        ²           Literal integer `2`
                       Φ            Filter over implicit range
                          λ         Reversed substring
                         ⁼          Equals
                            θ       Input string
                           ✂        Sliced from
                              κ     Outer index
                             ⁺      Plus
                               ρ    Optional overlap
                                    Implicitly print

```

The final optional overlap is added rather than subtracted because the outer index is actually that of the last character in the substring (which is why it is incremented when the substring is actually extracted). `Filter` is used instead of `Any` in the inner loops because it accepts an implicit range and `Any` does not.

# Answer
> 4 votes
# , ~~96~~ 86 bytes

```
\(x,l=sum(x|1),t=l%%3>0,`!`=\(y)any(y-x[1:h]))!tail(x,h<-l%/%3+t)|!x[q<-h:1+h]&!x[q-t]
```

Attempt This Online!

Pretty naive implementation, with some optimizations to make the code shorter (and unreadable).

Takes input as a vector of character codes. Outputs `FALSE` for tralindromes and `TRUE` otherwise.

### Explanation outline:

1. Let `l` be the length of input vector `x`.
2. Compute `h` \- the length of the tralindrome parts. It's \\$\lfloor\frac{l}{3}\rfloor+t\\$, where `t` is 0 for `l` divisible by 3 and 1 otherwise.
3. Prepare a helper function `!`, which compares its input with first `h` elements of `x` (denote them with `X` as in the question).
4. Then last `h` characters must be equal to `X`.
5. And one of the following must be equal to `X`:
    1. characters from `h+1` to `2*h`, reversed
    2. characters from `h+1-t` to `2*h-t`, reversed.

# Answer
> 3 votes
# Python3, 305 bytes:

```
lambda s:any(all({*s}-{*k}for k in j)^1and K(s,j)and j[0]==j[1][::-1]==j[2]for i in R(1,L(s)+1)for j in C(s,i))
R=range
L=len
K=lambda s,l:not(l or s)or l and s[:(T:=L(l[0]))]==l[0]and any(K(s[T-i:],l[1:])for i in[0,1])
C=lambda s,n,l=[]:L(l)==3and[l]or[j for x in R(L(s)-n+1)for j in C(s,n,l+[s[x:x+n]])]

```

Try it online!

# Answer
> 0 votes
# Nekomata \+ `-e`, 11 bytes

```
p::↔ᵃᶜt$,,=

```

Attempt This Online!

A port of my Curry answer (based on @Bubbler's comment).

```
p::↔ᵃᶜt$,,=
p               Find a prefix of the input
 ::             Triplicate it
   ↔            Reverse the third copy
    ᵃᶜt         Optionally drop the first character of the second and third copies
       $        Swap the second and third copies
        ,,      Join three copies together
          =     Check if the result is equal to the input

```

---
Tags: code-golf, string, decision-problem, palindrome
---


title: Cut along the lines

text:
# Question
Title: Cut along the lines
In this challenge you will take as input a non-empty list of binary values (these can be booleans or integers on the range 0-1), you should output all the ways to partition the list into non-empty sections such that no two adjacent equal values in the initial list are separated into different sections.

For example if the input is `[1,1,0,0,1]` then `[1,1],[0,0,1]` is a valid partition but `[1,1,0],[0,1]` is not since the adjacent `0`s are divided.

This is so the goal is to minimize the size of your source code as measured in bytes.

## Test cases

```
[1,0] ->
  [ [[1,0]]
  , [[1],[0]]
  ]
[1,1,1,1] ->
  [ [[1,1,1,1]]
  ]
[1,1,0,0,1] ->
  [ [[1,1,0,0,1]]
  , [[1,1],[0,0,1]]
  , [[1,1,0,0],[1]]
  , [[1,1],[0,0],[1]]
  ]

```

# Answer
> 8 votes
# K (ngn/k), 22 bytes

```
{(&'+1,!2-1_=':x)_\:x}

```

Try it online!

`1_=':x` For pairs of adjacent values: are they equal?
`2-` 2 minus that. Gives 2s for the lines between sections and 1s in sections.
`!` odometer. Returns a matrix with all binary patterns bounded by the vector.
`+1,` prepend a 1 and transpose to have the binary patterns with leading 1s in the rows.
`&'` Get indices of 1s for each row.
`(...)_\:x` For each of those integer vectors, split the input at those indices.

# Answer
> 6 votes
# Factor \+ `math.combinatorics math.unicode`, 81 bytes

```
[ dup 2 clump [ Σ 1 = ] arg-where 1 v+n all-subsets [ split-indices ] with map ]

```

Attempt This Online!

* `dup 2 clump [ Σ 1 = ] arg-where 1 v+n` get the indices of rising and falling edges
* `all-subsets` take all the subsets of that
* `[ split-indices ] with map` split the input according to each of these

# Answer
> 5 votes
# Jelly, 8 bytes

```
ITŒP‘œṖ€

```

A monadic Link that accepts a list of ones and zeros and yields a list of the valid partitions.

**Try it online!**

### How?

```
ITŒP‘œṖ€ - Link: list, B  e.g. [0, 0, 1, 1, 0, 1]
I        - deltas (of B)       [  0, 1, 0,-1, 1]
 T       - truthy indices      [     2,    4, 5]
  ŒP     - powerset            [[],[2],[4],[5],[2,4],[2,5],[4,5],[2,4,5]]
    ‘    - increment           [[],[3],[5],[6],[3,5],[3,6],[5,6],[3,5,6]]
       € - for each:
     œṖ  -   partition (B) at  [[[0,0,1,1,0,1]],[[0,0],[1,1,0,1]],[[0,0,1,1],[0,1]],[[0,0,1,1,0],[1]],[[0,0],[1,1],[0,1]],[[0,0],[1,1,0],[1]],[[0,0,1,1],[0],[1]],[[0,0],[1,1],[0],[1]]]

```

# Answer
> 5 votes
# Curry (PAKCS), 40 bytes

```
f(a++b:c:d)|b/=c=(a++[b]):f(c:d)
f a=[a]

```

Try it online!

# Answer
> 5 votes
# Vyxal, 6 bytes

```
ĠøṖvvf

```

Try it Online!

Port of @UnrelatedString's Brachylog answer.

# Answer
> 5 votes
# 05AB1E, 6 (or 4?) bytes

```
γ.œ€€˜

```

Try it online or verify all test cases.

If we can use strings as I/O, this could be 4 bytes instead by replacing `€€˜` with `J`:
Try it online or verify all test cases.

**Explanation:**

```
γ       # Split the (implicit) input-list into groups of equal adjacent values
 .œ     # Get all partitions of these groups
   €    # For each partition:
    €   #  For each part of groups within a partition:
     ˜  #   Flatten the part of groups to a single list
        # (or alternatively:)
   J    # Join each list/part of groups within each partition together
        # (after which the result is output implicitly)

```

# Answer
> 4 votes
# Brachylog, 5 bytes

```
ḅ~ccᵐ

```

Try it online!

Takes a list through the input variable and generates a list of lists of lists through the output variable.

```
ḅ        Partition into runs of consecutive equal elements.
 ~c      Take an arbitrary partition of the list of runs,
   cᵐ    and concatenate each slice.

```

# Answer
> 3 votes
# Brachylog, 20 bytes

```
Ė!|ḅa₀cPl;?b₍↰;Pgᵗ↔c

```

A predicate that takes a list of 0's and 1's as input and outputs each possible partition one after another.

Try it online!

### Explanation

This seems way too long.

```
Ė!|ḅa₀cPl;?b₍↰;Pgᵗ↔c
Ė!                    Either the input is an empty list (in which case return empty list)
  |                   Or, take the input and...
   ḅ                  Partition into blocks of equal elements
    a₀                Get a prefix of that list of blocks
      c               Flatten it
       P              Call that list P
        l             Take its length
         ;?b₍         The original input with that many elements removed from the front
             ↰        Recurse (returns a list of lists)
              ;P      Pair with P
                gᵗ    wrapped in a list
                  ↔   Reverse the order of the pair
                   c  Flatten once

```

# Answer
> 3 votes
# Prolog (SWI), 65 bytes

```
Q+[E|F]:-append(A,[B,C|D],Q),B\=C,append(A,[B],E),[C|D]+F.
Q+[Q].

```

Try it online!

Similar to @alephalpha's Curry answer. Outputs as a list of choicepoints.

# Answer
> 3 votes
# , 27 bytes

```
<;.1~1,.[:(#:[:i.*/)2-2=/\]

```

Try it online!

*-1 bytes thanks to the "2 minus" trick stolen from ovs's answer*

Say we have, eg, `1,1,0,0,1` -- then we have 2 "change points" and 4 possible combos. This is *essentially* just the problem of listing:

```
0 0
0 1
1 0
1 1

```

except we want that that list to be embedded in the `X`s of this list:

```
0 X 0 X

```

The key insight is that this is 0..3 converted using the *mixed base* number `1 2 1 2`. After that we just cut the original input using our 4 lists, with a 1 prepended to each.

# Answer
> 3 votes
# Jelly, 7 bytes

```
Ir0Œpk€

```

Try it online!

Inspired by Jonathan Allan's solution.

```
I          Get the forward differences of the list.
     k     Partition the list after each truthy position
      €    of each element of
   Œp      the Cartesian product of
 r0        the ranges from each difference to 0 inclusive.

```

# Jelly, 7 bytes

```
ŒgŒṖẎ€€

```

Try it online!

Port of my Brachylog solution.

```
Œg         Partition into runs of consecutive equal elements.
  ŒṖ       Generate every partition of the runs,
    Ẏ€€    and concatenate the runs in each slice.

```

# Answer
> 2 votes
# Perl 5, 80 bytes

```
sub{@p=pop=~/0+|1+/g;$s="@p";map$s=~s, ,$r=$_%2?$&:'';$_/=2;$r,ger,0..2**@p/2-1}

```

Try it online!

# Answer
> 2 votes
# Retina 0.8.2, 28 bytes

```
(.),(?!\1)
$1#
+%1`#
;$'¶$`,

```

Try it online! Link includes test cases. Outputs semicolon-delimited lists. Explanation:

```
(.),(?!\1)
$1#

```

Find all acceptable cutting points.

```
+

```

Loop until each cutting point has been processed.

```
%

```

Loop over each partially cut list.

```
1`

```

Only process the first remaining cutting point on each pass.

```
#
;$'¶$`,

```

Create two lists, one cut at that point, one not cut at that point.

# Answer
> 2 votes
# Haskell, 94 bytes

```
import Data.List
f l=nub[w|w<-subsequences[id=<<x|x<-tails=<<(inits.group)l,x>[]],(w>>=id)==l]

```

Try it online!

Corrected as x specifications.

Thanks to @Wheat Wizard for saving some bytes using *id=\<\<x* instead of concat.

# Answer
> 2 votes
# Knight (v2), 125 bytes

```
;=lL=p+=a@P;W=l-lT|?Gp lT Gp-lT1=a+a,l;=n^2LaW+1=n-nT;=x!=b+=o@p;=kLa;W+=k-kT1&%/n^2k 2;=o+o,GbF=d+~x=x[Ga kT=bSbFd@;D+o,bO''

```

Try it online!

Input as a binary string. Outputs each partition on a separate line.

This probably is not even the golfiest strategy lol, but whatever. The general strategy is to construct a list `a` that contains the possible indexes that can be cut at (the easy part), then enumerate over all possible combinations of cuts using `a` (the annoying as f\*** part).

# Answer
> 1 votes
# Charcoal, 45 bytes

```
⊞υ⟦Ａ⟧ＦυＦ…ι¹Ｆ²Ｆ⁺¹⌕Ａ⪫κω⁺Ｉλ¬λ⊞υ⁺⟦…κμ✂κμ⟧ΦιξＥυ⭆¹ι

```

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

```
⊞υ⟦Ａ⟧

```

Start with the original list, which is always a valid partition.

```
Ｆυ

```

Loop over the partitions found so far.

```
Ｆ…ι¹

```

Loop over the lists in the current partition, but stop after the first. (This is a sneaky way of getting the first list into a variable.)

```
Ｆ²

```

Loop over the possible first bits of a cutting point.

```
Ｆ⁺¹⌕Ａ⪫κω⁺Ｉλ¬λ

```

Loop over all of the possible cutting points that start with that bit. The cutting point is in between the bits, thus the extra `1` added to the positions. (`Incremented` works on empty lists in the newer version of Charcoal on ATO which would save a byte.)

```
⊞υ⁺⟦…κμ✂κμ⟧Φιξ

```

Cut the first list of the partition at that point and push the resulting partition to the list of partitions where it will be reevaluated for cutting.

```
Ｅυ⭆¹ι

```

Pretty-print all of the found partitions.

# Answer
> 1 votes
# Pyth, 11 10 bytes

```
mmrk9d./r8

```

Try it online!

### Explanation

```
        r8    length encode the implicitly evaluated input
      ./      get all partitions
mmrk9d        map length decoding to each partition element

```

# Answer
> 1 votes
# Python, 230 bytes

```
from itertools import*
import re
def f(M):L=re.split(r'((.)\2*)',''.join(map(str,M)))[1::3];l=len(L);I=[*range(1,l)];return[[M]]+[[[int(c)for c in''.join(L[i:j])]for i,j in pairwise([0,*P,l])]for s in I for P in combinations(I,s)]

```

Attempt This Online!

Python 3.10+ required for `pairwise`.

for `[1,1,0,0,1]` returns:

```
[[[1, 1, 0, 0, 1]],
 [[1, 1], [0, 0, 1]],
 [[1, 1, 0, 0], [1]],
 [[1, 1], [0, 0], [1]]]

```

ungolfed:

```
from itertools import *
import re
def f(M):
  # produce ['11', '00', '1'] by splitting on regex which checks 2 consecutive duplicates
  L = re.split(r'((.)\2*)',''.join(map(str,M)))[1::3]
  l = len(L)
  indexes = [*range(1,l)]
  return [[M]]+[
    # wrap list for each consequtive pair of index combos and convert back from string
    [[int(c) for c in ''.join(L[i:j])]
      for i,j in pairwise([0,*partition_indexes,l])]
    for partition_size in indexes
    for partition_indexes in combinations(indexes,partition_size)
  ]

```

# Answer
> 1 votes
# Nekomata, 4 bytes

```
ĉJᵐj

```

Attempt This Online!

A port of @Unrelated String's Brachylog answer.

```
ĉ       Partition into runs of consecutive equal elements.
 J      Take an arbitrary partition of the list of runs,
  ᵐj    and concatenate each slice.

```

# Answer
> 0 votes
# JavaScript (V8), 71 bytes

```
f=([x,...y],z='')=>x?f(y,z+x)|f(y,[z,x]):/^,|1,1|0,0/.test(z)||print(z)

```

Try it online!

Seems they look same

# JavaScript (V8), 72 bytes

```
f=([x,...y],z='')=>x?f(y,z+x)|f(y,z+[,x]):/^,|1,1|0,0/.test(z)||print(z)

```

Try it online!

---
Tags: code-golf, binary, set-partitions
---