14
\$\begingroup\$

Challenge description

Given a list / array of items, display all groups of consecutive repeating items.

Input / output description

Your input is a list / array of items (you can assume all of them are of the same type). You don't need to support every type your language has, but is has to support at least one (preferably int, but types like boolean, although not very interesting, are also fine). Sample outputs:

[4, 4, 2, 2, 9, 9] -> [[4, 4], [2, 2], [9, 9]]
[1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4] -> [[1, 1, 1], [2, 2], [3, 3, 3], [4, 4, 4, 4]]
[1, 1, 1, 3, 3, 1, 1, 2, 2, 2, 1, 1, 3] -> [[1, 1, 1], [3, 3], [1, 1], [2, 2, 2], [1, 1], [3]]
[9, 7, 8, 6, 5] -> [[9], [7], [8], [6], [5]]
[5, 5, 5] -> [[5, 5, 5]]
['A', 'B', 'B', 'B', 'C', 'D', 'X', 'Y', 'Y', 'Z'] -> [['A'], ['B', 'B', 'B'], ['C'], ['D'], ['X'], ['Y', 'Y'], ['Z']]
[True, True, True, False, False, True, False, False, True, True, True] -> [[True, True, True], [False, False], [True], [False, False], [True, True, True]]
[0] -> [[0]]

As for empty lists, output is undefined - it can be nothing, an empty list, or an exception - whatever suits your golfing purposes the best. You don't have to create a separate list of lists either, so this is a perfectly valid output as well:

[1, 1, 1, 2, 2, 3, 3, 3, 4, 9] ->

1 1 1
2 2
3 3 3
4
9

The important thing is to keep the groups separated in some way. This is so the shortest code in bytes wins

\$\endgroup\$
12
  • \$\begingroup\$ Maybe we output a list that has some special separator value? \$\endgroup\$ – xnor Jul 4 '16 at 9:57
  • \$\begingroup\$ @xnor: Can you provide an example? An array of ints separated by, for instance, 0s would be a bad idea since there can be 0s in the input... \$\endgroup\$ – shooqie Jul 4 '16 at 10:10
  • \$\begingroup\$ For example, [4, 4, '', 2, 2, '', 9, 9] or [4, 4, [], 2, 2, [], 9, 9]. \$\endgroup\$ – xnor Jul 4 '16 at 10:11
  • \$\begingroup\$ Actually, what types do we have to support. Can the elements themselves to be lists? I imagine some languages have built-in types that can't be printed or have weird equality-checking. \$\endgroup\$ – xnor Jul 4 '16 at 10:11
  • \$\begingroup\$ @xnor: Yeah, that's what my concern was - if your input has lists inside it, then using empty list as a separator might be confusing. That's why I included "you can assume all the items are of the same type", so that can use a different type as a separator. \$\endgroup\$ – shooqie Jul 4 '16 at 10:13

43 Answers 43

1
2
0
\$\begingroup\$

TSQL, 132 bytes

This is a little different from the other answers - sql doesn't have arrays, the obvious input for sql is a table.

Golfed:

DECLARE @ table(i int identity, v varchar(20))
INSERT @ values(1),(1),(1),(3),(3),(1),(1),(2),(2),(2),(1),(1),(3)

SELECT REPLICATE(v+' ',COUNT(*))FROM(SELECT i,i-row_number()over(partition
by v order by i)x,v FROM @)z GROUP BY x,v ORDER BY max(i)

Ungolfed:

DECLARE @ table(i int identity, v varchar(20))
INSERT @ values(1),(1),(1),(3),(3),(1),(1),(2),(2),(2),(1),(1),(3)

SELECT
  REPLICATE(v+' ',COUNT(*))
FROM 
  (
     SELECT
       i,
       i-row_number()over(partition by v order by i)x,
       v
     FROM @
  )z
GROUP BY
  x,v
ORDER BY
  max(i)

Fiddle

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

Perl 5 - 39 Bytes

print$_.($/)[$_ eq@a[++$-]]for@a=sort@a
\$\endgroup\$
0
\$\begingroup\$

Pyke, 2 bytes (non competitive)

Only supports integers

$f

Try it here!

split_at(input, delta(input))

Added split_at node, splits input when 2nd arg is truthy

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

sed, 33 23+1=24 bytes

s/([^ ]+)( \1)* */&\n/g

It needs the -r option.

Usage example:

$ echo '1 1 1 2 2 3 3 3 4 9 9' | sed -r 's/([^ ]+)( \1)* */&\n/g'
1 1 1 
2 2 
3 3 3 
4 
9 9
\$\endgroup\$
0
\$\begingroup\$

JavaScript (ES6), 56

Input: array of numbers or strings

Output: array of arrays

First time ever using exact comparisong in golfed code

a=>a.map(x=>x!==p?o.push(g=[p=x]):g.push(x),p=o=g=[])&&o
\$\endgroup\$
0
\$\begingroup\$

Clojure, 19 bytes

#(partition-by + %)

It's a built-in, but it takes a mapping function. In this case, + serves as an identity function.

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

Javascript (using external library) (178 bytes)

(s)=>_.From(s).Aggregate((t,e)=>{if(0===t.Items.length)return t.Items.push([e]),t;var s=t.Items[t.Items.length-1];return s[0]===e?(s.push(e),t):(t.Items.push([e]),t)},{Items:[]})

Disclaimer: I am using a library I wrote to implement LINQ from C# into JS. It didn't exactly help me win but oh well

Image

Image2

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

Befunge, 47 41 38 Bytes

&:&:.92pv.<
g29:&:-1_@|!-
92p25*,.^ >:

Input format:

number_of_values-1         values (separated by a space)

You may test the code here


Previous version with explanations :

&:&:.00pv.<
g00:&:-1_@|!-
v*52p00:  <
>,.     ^

The interpet's cursor follows the symbols > v < ^. If the cursor is at the end of a line and is going to the right, it will loop back to the beginning (same principle for other directions).

&: : Gets the first input put it to the stack and duplicates it (to the stack)

&:.00pv : Gets the second input, prints it and saves it into the code, at the coordinates (0,0) [erasing the first '&']. Then, go down

_ : Test if last value of the stack (the number of values) is equals to 0 and set the cursor's direction to the right if it is, to the left if it isn't

1-: : Removes 1 from the number of values

&:00g-!| : Compares the next input with the one stored at (0,0). Set the cursor's direction to up if they are equal, to down if they aren't

. : Displays a numeric value

:00p52*,. : Override the last saved value to the current value, then displays \n (ascii 10, 5*2) followed by the value

@ : Terminates the program

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

05AB1E, 1 byte

γ

Builtins ftw ¯\_(ツ)_/¯

Try it online or verify all test cases.

Here an alternative without builtins (6 bytes):

üÊ0šÅ¡

Try it online or verify all test cases.

Explanation:

γ       # Split the (implicit) input-list into chunks of equal adjacent values
        # (after which the resulting list of lists is output implicitly)

ü       # For each overlapping pair of values in the (implicit) input-list:
 Ê      #  Check that they are NOT equal (0 if equal; 1 if not)
  0š    # Prepend a 0 to this list
    Å¡  # Split the (implicit) input-list at the truthy indices
        # (after which the resulting list of lists is output implicitly)
\$\endgroup\$
0
\$\begingroup\$

Charcoal, 35 bytes

≔⁰ξ≔⁺θ θF⊖Lθ«¿¬⁼§θι§θ⊕ι«P✂θξ⊕ι↓≔⊕ιξ

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

Input as a list of characters.

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

Brachylog v2, 1 byte

Try it online!

Less built-in and far, far slower:

Brachylog v2, 4 bytes

~c=ᵐ

Try it online!

~c      The output is a partitioning of the input (with as few partitions as possible)
   ᵐ    such that each partition
  =     contains only one unique element.
\$\endgroup\$
0
\$\begingroup\$

C (gcc), 54 bytes

f(char*s){printf("%c%c",*s,*s-s[1]?10:32),*++s&&f(s);}

Try it online!

or 55 bytes iteratively

f(char*s){while(printf("%c%c",*s,*s-s[1]?10:32),*++s);}

Try it online!

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

Factor, 23 bytes

[ [ ] group-by values ]

Try it online!

[                        ! begin quotation (anonymous function)
  [ ]                    ! A quotation that returns its input
      group-by           ! group adjacent elements with a ( key -- value ) quotation
               values    ! obtain the values of an associative array
                      ]  ! end quotation

Factor actually has a combinator called monotonic-split that can do this more directly, but it's more bytes.

\$\endgroup\$
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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