15
\$\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\$
16
  • 8
    \$\begingroup\$ Any particular reason for the strict input and output format? \$\endgroup\$ Aug 13, 2019 at 21:26
  • 2
    \$\begingroup\$ @UnrelatedString Hmm, I shall loosen them. \$\endgroup\$ Aug 13, 2019 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, 2019 at 3:35
  • 2
    \$\begingroup\$ Can we assume the list is non-empty? \$\endgroup\$
    – Jo King
    Aug 14, 2019 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, 2019 at 0:47

38 Answers 38

7
\$\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\$
4
  • \$\begingroup\$ Hmm, how long would this be in Pyth? \$\endgroup\$ Aug 14, 2019 at 0:05
  • \$\begingroup\$ Huh, I avoided id because it's 2 bytes long... \$\endgroup\$ Aug 14, 2019 at 7:54
  • \$\begingroup\$ Oof nice idea of id \$\endgroup\$ Aug 14, 2019 at 12:23
  • \$\begingroup\$ @noɥʇʎԀʎzɐɹƆ 8 bytes for a straightforward translation: Try it online! \$\endgroup\$
    – isaacg
    Dec 14, 2019 at 1:16
6
\$\begingroup\$

Python 2, 44 bytes

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

Try it online!

\$\endgroup\$
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\$
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
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\$
2
  • \$\begingroup\$ Minor 5-bytes alternative: ¥Ā could also be üÊ. \$\endgroup\$ Aug 14, 2019 at 6:55
  • 1
    \$\begingroup\$ 4 bytes \$\endgroup\$
    – Grimmy
    Aug 14, 2019 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\$
2
  • \$\begingroup\$ I keep forgetting that 05ab1e has that ƶ... +1 \$\endgroup\$
    – Mr. Xcoder
    Aug 14, 2019 at 12:05
  • 1
    \$\begingroup\$ Here an alternative 4-byter: ηεγg \$\endgroup\$ Aug 15, 2019 at 16:01
2
\$\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\$
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\$

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\$
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\$
0
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\$
3
  • \$\begingroup\$ hMsM._+0nVt for -2 bytes. \$\endgroup\$
    – Mr. Xcoder
    Aug 14, 2019 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, 2019 at 7:57
  • \$\begingroup\$ Ah nice, the docs didn't mention what functions take an implicit Q \$\endgroup\$
    – ar4093
    Aug 14, 2019 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
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\$
1
  • \$\begingroup\$ @Night2 good catch! Updated and fixed. Thx! \$\endgroup\$
    – 640KB
    Aug 15, 2019 at 17:42
1
\$\begingroup\$

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!

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

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

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

Factor, 45 bytes

[ 0 f rot [ tuck = rot dup 1 + ? tuck ] map ]

Try it online!

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

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

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

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.