# Chunk + Enumerate a list of digits

I have a list of decimal digits:

4, 4, 4, 7, 7, 9, 9, 9, 9, 2, 2, 2, 4, 4

The list of decimal digits are known as items. We can form "chunks" from these items by grouping together identical and adjacent numbers. I want to assign each chunk a unique number, starting from 1, and increasing by 1 in the order the chunks appear in the original list. So, the output for the given example would look like this:

1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5

## Input format

A list of digits. (0-9) You may use your language built-ins to read this list however you want. Encoding: ASCII

# Output format

A series of decimal numbers, separated by a delimiter. Your program must always use the same delimiter. The delimiter must be longer than 0 bits. Encoding: ASCII

Standard loopholes apply.

• Any particular reason for the strict input and output format? Aug 13, 2019 at 21:26
• @UnrelatedString Hmm, I shall loosen them. Aug 13, 2019 at 21:27
• The IO is still rather strict. Can't you just say "input and output is as a list" and let the site defaults take care of it for you?
– Jo King
Aug 14, 2019 at 3:35
• Can we assume the list is non-empty?
– Jo King
Aug 14, 2019 at 4:14
• A list by definition has delimiters already. That's why it's a list. I also don't understand what you mean by You may use your language built-ins to read this list however you want.. Does that mean we have to include a string to list converter in our submission? And are we allowed to output as a list?
– Jo King
Aug 15, 2019 at 0:47

# Python 3.8 (pre-release), 41 bytes

lambda l,n=0:[n:=n+(l!=(l:=x))for x in l]


Try it online!

Praise the magic walrus := of assignment expressions.

# Python 2, 42 bytes

n=0
for x in input():n+=x!=id;id=x;print n


Try it online!

• Hmm, how long would this be in Pyth? Aug 14, 2019 at 0:05
• Huh, I avoided id because it's 2 bytes long... Aug 14, 2019 at 7:54
• Oof nice idea of id Aug 14, 2019 at 12:23
• @noɥʇʎԀʎzɐɹƆ 8 bytes for a straightforward translation: Try it online! Dec 14, 2019 at 1:16

# Python 2, 44 bytes

l=input()
n=0
for i in l:n+=i!=l;l=i;print n


Try it online!

# APL (dzaima/APL), 7 bytesSBCS

Anonymous tacit prefix function. Prints space-separated.

+\1,2≠/


Try it online!

2≠/ pair-wise inequality

1, prepend 1

+\ cumulative sum

# Jelly, 6 5 bytes

ŒɠµJx


Try it online!

Saved one byte thanks to UnrelatedString!

Inputs and outputs as array's (with opening/closing brackets)

## How it works

ŒɠµJx - Main link, takes one argument:                       [7, 7, 5, 5, 5, 1]
Œɠ    - Get the lengths of consecutive elements:             [2, 3, 1]
µ   - Call these lengths A
J  - range(length(A))                                     [1, 2, 3]
x - Repeat each element by the corresponding value in A: [1, 1, 2, 2, 2, 3]

• 5 bytes Aug 13, 2019 at 21:30
• @UnrelatedString all these new-fangled atoms! Aug 13, 2019 at 21:34

# Wolfram Language (Mathematica), 29 bytes

Join@@(i=1;0#+i++&/@Split@#)&


Try it online!

# 05AB1E, 5 bytes

¥Ā.¥>


Try it online!

• Minor 5-bytes alternative: ¥Ā could also be üÊ. Aug 14, 2019 at 6:55
• 4 bytes Aug 14, 2019 at 12:03

f(a:t)=1:map(+sum[1|a/=t!!0])(f t)
f e=e


Try it online!

# Pyth, 13 11 bytes

s.e*]hkhbr8


Try it online!

         r8  # Run-length encode (implicit argument is the input) (-> [[frequency, char], ...]
.e          # Enumerated map (current element is b, index is k) over rQ8
*]hk      # [ k+1 ] *
hb    #           b[0]
s            # Reduce list on + ([a]+[b] = [a,b])


-2 bytes thanks to Mr. Xcoder

• hMsM._+0nVt for -2 bytes. Aug 14, 2019 at 7:56
• Or if you want to keep your approach, rQ8 is the same as r8 and .n can be s for -2 as well Aug 14, 2019 at 7:57
• Ah nice, the docs didn't mention what functions take an implicit Q Aug 14, 2019 at 8:39

# Scala, 75 bytes

s=>s.scanLeft(("",0))((x,y)=>(y,x._2+(if(x._1!=y)1 else 0))).tail.map(_._2)


Try it online!

If input and output must be comma separated String (and not List) then 102 bytes.

s=>s.split(", ").scanLeft(("",0))((x,y)=>(y,x._2+(if(x._1!=y)1 else 0))).tail.map(_._2).mkString(", ")


# Jelly, 5 bytes

nƝÄŻ‘


Try it online!

I initially aimed for a 4-byter (the same program but without the Ż) but then quickly realized that a 1 had to be prepended every time due to an oversight... Even though there is another 5-byter in Jelly, I'll actually keep this because it uses a different method.

For each pair of neighbouring items of the input list $$\L\$$, test if $$\L_i\ne L_{i+1}, \forall 1\le i<|L|\$$ and save these results in a list. Then take the cumulative sum of this list and increment them by 1 to match the chunk indexing system. TL;DR. Whenever we encounter different neighbouring items, we increment the chunk index by 1.

while(''<$d=$argv[++$x])echo$i+=$argv[$x-1]!=$d,' ';  Try it online! Input via command line, output to STDOUT. Thx to @Night2 for the pesky '0' == 0 comparison bugfix! • @Night2 good catch! Updated and fixed. Thx! Aug 15, 2019 at 17:42 # Julia 1.0, 56 bytes l->foldl(l,init=(0,0))do(p,i),c println(i+=p!=c) c,i end  Try it online! # Desmos, 65 bytes L=join(1,1-0^{(l[2...]-l)^2}) f(l)=∑_{n=1}^{[1...L.length]}L[n]  Try It On Desmos! Try It On Desmos! - Prettified # Factor, 45 bytes [ 0 f rot [ tuck = rot dup 1 + ? tuck ] map ]  Try it online! # Ly, 29 bytes 1sp&nry[pluy,[',o!]p=!l+spy]p  Try it online! This one keeps a counter with the chunk number in the backup cell. That's incremented anytime the current codepoint doesn't match the next one on the list. The only other trick is the code to conditionally add the , delimiter if there's at least one more codepoint on the stack. 1sp - init the chunk number to 1, pop from stack &nr - read in list of digits as codepoints y[p y]p - loop as long as the stack isn't empty lu - load/print the chunk counter y,[ !]p - if/then, true if there's 2+ digits left ',o - print a comma delimiter =! - push "1" if the top 2 entries are not equal l+sp - increment chunk counter is digits differ  # Japt v2.0a0, 9 bytes £T±A¦(A=X  Try it # Add++, 23 bytes D,f,@*,BGd€bL$bLRz€¦XBF


Try it online!

## How it works

D,f,@*,     - Define a function, f, that takes one argument:  [7 7 5 5 5 1]
BG   - Group neighbouring elements together:           [[[7 7] [5 5 5] [1]]]
d    - Duplicate:                                      [[[7 7] [5 5 5] [1]] [[7 7] [5 5 5] [1]]]
€bL  - Get the length of each:                         [[[7 7] [5 5 5] [1]] [2 3 1]]
$bLR - Length, then range of length: [[2 3 1] [1 2 3]] z - Zip together: [[2 1] [3 2] [1 3]] €¦X - Reduce each by repetition: [[1 1] [2 2 2] [3]] BF - Flatten: [1 1 2 2 2 3] - Due to the * in the function definition, return the whole stack: [1 1 2 2 2 3]  # Japt, 8 7 bytes ä¦Ug)åÄ  Try it # Retina 0.8.2, 34 bytes \b\d+\b(?<=(\b(\3|(\d+))\D*)*)$#3


Try it online! Explanation:

\b\d+\b


Match each number in turn.

(?<=(...)*)


Start looking backwards for as many matches as possible. (The next entries will be in right-to-left order as that's how lookbehind works.)

\D*


Skip the separators.

(\3|(\d+))


Try to match the same number as last time, but failing that, just match any number, but remember that we had to match a new number.

\b


Ensure the whole number is matched.

\$#3


Count the number of new numbers.

# Stax, 10 bytes

▓ª2ªmD?Ä╧╖


Run and debug it

The output uses space as a delimiter. The input follows the precise specifications using commas as separators, and now enclosing braces.