Cumulative Counts
Challenge
Given an array of numbers return the cumulative count of each item.
This is the number of times an item has occurred so far.
Examples
[1,1,2,2,2,1,1,1,3,3] -> [1,2,1,2,3,3,4,5,1,2]
[3,7,5,4,9,2,3,2,6,6] -> [1,1,1,1,1,1,2,2,1,2]
Brownie points for beating my 7 byte APL answer.
BQN, 5 bytes ``` 1+⊒ ``` T …
4y ago
[APL (Dyalog Unicode)], 11 byt …
4y ago
[Jelly], 4 bytes ¹Ƥċ" …
4y ago
Japt, 14 11 8 bytes £¯Y …
4y ago
[APL (Dyalog Unicode)], 11 7 b …
4y ago
[Ruby], 36 bytes ```ruby - …
3y ago
[JavaScript (Node.js)], 34 29 …
2y ago
[Husk], 4 bytes Sz#ḣ …
4y ago
Scala 3, 50 44 bytes ```scala …
3y ago
[Jelly], 7 bytes =þ`ÄŒD …
4y ago
[Lean 4], 111 bytes ```lean …
4d ago
Python 3, 50 bytes We can s …
4d ago
Haskell + hgl, 10 bytes ``` …
2y ago
Python 3, 70 bytes ```pytho …
2y ago
Factor, 122 bytes ``` USIN …
2y ago
Vyxal, 4 bytes ``` KƛtO ``` …
2y ago
[Python 3], 74 bytes …
2y ago
[Python 3.8 (pre-release)], 69 …
2y ago
J, 9 bytes ```J 1#.]=&><\ …
3y ago
J, 24 char ```([: +/ [: ( …
3y ago
Ruby, 31 bytes ```ruby ->a …
2y ago
21 answers
You are accessing this answer with a direct link, so it's being shown above all other answers regardless of its score. You can return to the normal view.
Lean 4, 111 bytes
def c(l:List Nat):List Nat:=((λx=>((l.reverse).drop x).count (l.reverse)[x]!)<$>(List.range l.length)).reverse
Given how verbose Lean syntax is, and how you can't really assign variables to keywords in a way that it saves bytes the vast majority of the time, if at all, I doubt there's a way to save any more bytes from here. I think 111 might actually be the limit.
And the only reason that I have to reverse the list is because while Lean does have a function to drop elements, it only does so from the left, which we really don't want here.
Hexdump since this contains unprintable characters:
00000000 64 65 66 20 64 28 6c 3a 4c 69 73 74 20 4e 61 74 |def d(l:List Nat|
00000010 29 3a 4c 69 73 74 20 4e 61 74 3a 3d 28 28 ce bb |):List Nat:=((..|
00000020 78 3d 3e 28 28 6c 2e 72 65 76 65 72 73 65 29 2e |x=>((l.reverse).|
00000030 64 72 6f 70 20 78 29 2e 63 6f 75 6e 74 20 28 6c |drop x).count (l|
00000040 2e 72 65 76 65 72 73 65 29 5b 78 5d 21 29 3c 24 |.reverse)[x]!)<$|
00000050 3e 28 4c 69 73 74 2e 72 61 6e 67 65 20 6c 2e 6c |>(List.range l.l|
00000060 65 6e 67 74 68 29 29 2e 72 65 76 65 72 73 65 |ength)).reverse|
0 comment threads
BQN, 5 bytes
1+⊒
3 characters, but, as there's no SBCS codepage for BQN, it must be counted as UTF-8.
Two of the three characters are just adding one to the built-in that almost solves the challenge too.
0 comment threads
Jelly, 4 bytes
¹Ƥċ"
" For each element of the input,
ċ how many times does it occur in
¹Ƥ " the corresponding prefix of the input?
0 comment threads
APL (Dyalog Unicode), 11 bytes (SBCS)
1 1∘⍉+\∘.=⍨
This was a fun APL exercise. Working on figuring out how to get it down to 7 bytes.
APL (Dyalog Unicode), 11 7 bytes (SBCS)
Razetime and rak1507 came up with 7 byte equivalents of my original dfn (this one's rak1507's). See their solutions below.
+/¨⊢=,\
+/¨⊢=,\
,\ ⍝ Prefixes of the list
= ⍝ Compare every prefix
⊢ ⍝ to the corresponding element in the original list
+/ ⍝ Sum each to get a count of how many elements in each prefix match
JavaScript (Node.js), 34 29 26 bytes
-5 bytes thanks to Shaggy's suggestion on a similar challenge
-3 bytes again thanks to Shaggy!
a=>a.map(d=v=>d[v]=-~d[v])
1 comment thread
Husk, 4 bytes
Sz#ḣ
Explanation
Sz#ḣ
Sz zip the input
ḣ with its prefixes
# using the count function
0 comment threads
Ruby, 36 bytes
->a{i=-1;a.map{a[0..i+=1].count _1}}
The code in the TIO link is 2 bytes longer because _n
block parameter names are not supported on TIO's Ruby instance yet. It will work the same, however. The code is:
->a{i=-1;a.map{a[0..i+=1].count a[i]}}
0 comment threads
Scala 3, 50 44 bytes
? => ?.indices zip?map(?take _+1 count _.==)
This is an annoying, stupid approach. The more elegant one using inits
was much longer (x=>x.inits.toSeq.reverse.tail zip x map(_ count _.==)
).
? => //The input
?.indices //The indices
zip ? //Zip them with the elements of the input
.map( //For every index i and the corresponding element x,
? take _+1 //Take the first i+1 elements of the input
count //Count how many of them
_.==) //Are equal to the element x
0 comment threads
Python 3.8 (pre-release), 69 bytes
def f(x,y={},z=[]):
for i in x:y[i]=y.get(i,0)+1;z+=[y[i]]
return z
Bonus: theoretical answer if python allowed named assignment with subscript (54 bytes)
lambda x,y={}:[y[i]:=y[i]+1if i in y else 1for i in x]
0 comment threads
Factor, 122 bytes
USING: kernel sequences sequences.windowed ;
IN: c
: c ( s -- s ) dup length [ dup last [ = ] curry count ] rolling-map ;
0 comment threads
Ruby, 31 bytes
->a{a.map{$*[_1]=1.+$*[_1]||0}}
$*
is a global variable, so calling this lambda multiple times (in a single process) would give wrong result. A 32 bytes version that does not rely on a global state:
->a,*c{a.map{c[_1]=1.+c[_1]||0}}
If array consists of positive integers from a known range (lets say 0...1e3
, then 30 bytes version is:
->a{b=[0]*1e3;a.map{b[_1]+=1}}
0 comment threads
Python 3, 70 bytes
def f(a):
d={};r=[]
for x in a:d[x]=d.get(x,0)+1;r+=[d[x]]
return r
0 comment threads
Vyxal, 4 bytes
KƛtO
Explained
KƛtO
Kƛ # For each prefix of the input
tO # How many times does the tail occur in the prefix?
0 comment threads
Python 3, 50 bytes
We can simply omit the lambda name since we don't refer to it anywhere in the lambda definition.
lambda l:[l[:i+1].count(j)for i,j in enumerate(l)]
Example usage in the terminal:
>>>(lambda l:[l[:i+1].count(j)for i,j in enumerate(l)])([1,1,2,2,2,1,1,1,3,3])
[1, 2, 1, 2, 3, 3, 4, 5, 1, 2]
>>>(lambda l:[l[:i+1].count(j)for i,j in enumerate(l)])([3,7,5,4,9,2,3,2,6,6])
[1, 1, 1, 1, 1, 1, 2, 2, 1, 2]
I tested this on version 3.8.5 but this should work on earlier as well as newer versions of Python 3.
0 comment threads
J, 24 char
([: +/ [: (* +/\ )"1 ~. ="0 1 ])
Sample Runs
([:+/[:(*+/\)"1~.="0 1]) 1 1 2 2 2 1 1 1 3 3
1 2 1 2 3 3 4 5 1 2
([:+/[:(*+/\)"1~.="0 1]) 3 7 5 4 9 2 3 2 6 6
1 1 1 1 1 1 2 2 1 2
0 comment threads
Python 3, 74 bytes
def f(a):
d={x:0 for x in a};r=[]
for x in a:d[x]+=1;r+=[d[x]]
return r
0 comment threads