10
\$\begingroup\$

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.

\$\endgroup\$
  • 8
    \$\begingroup\$ Any particular reason for the strict input and output format? \$\endgroup\$ – Unrelated String Aug 13 at 21:26
  • 2
    \$\begingroup\$ @UnrelatedString Hmm, I shall loosen them. \$\endgroup\$ – noɥʇʎԀʎzɐɹƆ Aug 13 at 21:27
  • 8
    \$\begingroup\$ 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? \$\endgroup\$ – Jo King Aug 14 at 3:35
  • 2
    \$\begingroup\$ Can we assume the list is non-empty? \$\endgroup\$ – Jo King Aug 14 at 4:14
  • 1
    \$\begingroup\$ 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? \$\endgroup\$ – Jo King Aug 15 at 0:47

33 Answers 33

6
\$\begingroup\$

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!

\$\endgroup\$
  • \$\begingroup\$ Hmm, how long would this be in Pyth? \$\endgroup\$ – noɥʇʎԀʎzɐɹƆ Aug 14 at 0:05
  • \$\begingroup\$ Huh, I avoided id because it's 2 bytes long... \$\endgroup\$ – Erik the Outgolfer Aug 14 at 7:54
  • \$\begingroup\$ Oof nice idea of id \$\endgroup\$ – U10-Forward Aug 14 at 12:23
5
\$\begingroup\$

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

\$\endgroup\$
5
\$\begingroup\$

Python 2, 44 bytes

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

Try it online!

\$\endgroup\$
3
\$\begingroup\$

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

Wolfram Language (Mathematica), 29 bytes

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

Try it online!

\$\endgroup\$
2
\$\begingroup\$

05AB1E, 5 bytes

¥Ā.¥>

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Minor 5-bytes alternative: ¥Ā could also be üÊ. \$\endgroup\$ – Kevin Cruijssen Aug 14 at 6:55
  • 1
    \$\begingroup\$ 4 bytes \$\endgroup\$ – Grimy Aug 14 at 12:03
2
\$\begingroup\$

Haskell, 40 bytes

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

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Perl 6, 21 bytes

{+<<[\+] $,|$_ Zne$_}

Try it online!

Anonymous code block that takes a list and returns a list. This works by comparing whether each pair of adjacent elements are not equal, than taking the cumulative sum of the list.

\$\endgroup\$
2
\$\begingroup\$

05AB1E, 4 bytes

γdƶ˜

Try it online!

γ       # group adjacent equal digits together
 d      # replace all digits with 1
  ƶ     # multiply each group by its 1-based index
   ˜    # flatten
\$\endgroup\$
  • \$\begingroup\$ I keep forgetting that 05ab1e has that ƶ... +1 \$\endgroup\$ – Mr. Xcoder Aug 14 at 12:05
  • 1
    \$\begingroup\$ Here an alternative 4-byter: ηεγg \$\endgroup\$ – Kevin Cruijssen Aug 15 at 16:01
2
\$\begingroup\$

MATL, 8 bytes

Y'wn:wY"

Try it online!

Explanation:

    Y'      % run-length encoding
    w       % swap elements in stack
    n       % number of elements in array / size along each dimension
    :       % range; vector of equally spaced values
    w       % swap elements in stack
    Y"      % replicate elements of array
            % (implicit) convert to string and display
\$\endgroup\$
2
\$\begingroup\$

Jelly, 4 bytes

ŒgƤẈ

Try it online!

How?

ŒgƤẈ - Link: list of integers  e.g. [7,7,2,7,7]
  Ƥ  - for prefixes:     [7]   [7,7]   [7,7,2]      [7,7,2,7]        [7,7,2,7,7]
Œg   -   group runs      [[7]] [[7,7]] [[7,7],[2]]  [[7,7],[2],[7]]  [[7,7],[2],[7,7]]
   Ẉ - length of each    [1,   1,      2,           3,               3]
\$\endgroup\$
1
\$\begingroup\$

Octave / MATLAB, 25 bytes

@(x)cumsum([1 ~~diff(x)])

Try it online!

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

Haskell, 46 43 bytes

scanl(+)1.map fromEnum.(zipWith(/=)=<<tail)

Try it online!

Anonymous pointfree function that takes a list and returns a list

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

J, 12 bytes

1+/\@,2~:/\]

Try it online!

Similar to Adám's APL answer

      2~:/\]  - pair-wise inequality
1    ,        - prepend 1
    @         - and   
+/\           - find the cumulative sum
\$\endgroup\$
1
\$\begingroup\$

Perl 5, 27 bytes

s/\d/$i+=$&!=$p;$p=$&;$i/ge

Try it online!

The command line option -p makes perl read the input line from STDIN into the "default variable" $_. It then search-replaces all digits in $_ with the counter $i. And $i is increased for each digit which is different than the previous digit, which it also is at the first digit so the counter starts at 1. The previous digit is stored in $p.

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

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

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

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(", ")
\$\endgroup\$
1
\$\begingroup\$

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.

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

R, 33 bytes

function(x)cumsum(c(1,!!diff(x)))

Try it online!

Uses the same cumulative sum method as Luis Mendo and others.

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

JavaScript (ES6), 30 bytes

Takes input as an array of integers.

a=>a.map(p=n=>i+=p!=(p=n),i=0)

Try it online!

Commented

a =>                // a[] = input array
  a.map(p =         // initialize p to a non-numeric value
  n =>              // for each value n in a[]:
    i +=            //   increment i if:
      p != (p = n), //     p is not equal to n; and update p to n
    i = 0           //   start with i = 0 (chunk counter)
  )                 // end of map()
\$\endgroup\$
1
\$\begingroup\$

PHP, 52 bytes

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!

\$\endgroup\$
  • \$\begingroup\$ @Night2 good catch! Updated and fixed. Thx! \$\endgroup\$ – 640KB Aug 15 at 17:42
0
\$\begingroup\$

Japt v2.0a0, 9 bytes

£T±A¦(A=X

Try it

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

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

Japt, 8 7 bytes

ä¦Ug)åÄ

Try it

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

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.

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

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.

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

C (gcc), 62 61 bytes

This is one of the few entries I've done where a complete program is shorter than a function submission!

On the first pass, I don't care about the previous value, so I get to rely on the fact that argv is a pointer to somewhere and is extremely unlikely to be between [0..9]!

s;main(i,j){for(;~scanf("%d,",&i);j=i)printf("%d ",s+=j!=i);}

Try it online!

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

Scala, 114 bytes

s.split(", ").zipWithIndex.scan(s.head,0){(a,b)=>if(a._1==b._1)a else b._1->(a._2+1)}.tail.unzip._2.mkString(", ")

Try it online!

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

C (gcc), 62 bytes

f(_,l)int*_;{printf("%d ",l=--l?f(_,l)+(_[l]!=_[l-1]):1);_=l;}

Try it online!

A function that takes the list and its length as arguments.


C (gcc), 60 bytes

f(_,l)int*_;{_=printf("%*d",--l?f(_,l)+(_[l]!=_[l-1]):2,0);}

Try it online!

Outputs in unary, delimited by 0s

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

x86-16, 12 bytes

Unassembled listing:

        NUM_LOOP: 
AC          LODSB                   ; load [SI] into AL, advance SI 
3A C2       CMP  AL, DL             ; is this char same as last? 
74 01       JZ   SAME               ; if so, same index 
43          INC  BX                 ; otherwise increment index 
        SAME: 
92          XCHG AX, DX             ; save current char for next compare 
8A C3       MOV  AL, BL             ; put index value in AL to store
AA          STOSB                   ; store AL into [DI], advance DI
E2 F4       LOOP NUM_LOOP           ; keep looping 

Input is byte array at SI, length in CX. Output is byte array at DI. Of course, this is if default I/O rules apply now.

Example: SI = 120H, DI = 130H

enter image description here

\$\endgroup\$

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.