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 …
5y ago
[APL (Dyalog Unicode)], 11 byt …
5y ago
[Jelly], 4 bytes ¹Ƥċ" …
5y ago
Japt, 14 11 8 bytes £¯Y …
5y ago
[APL (Dyalog Unicode)], 11 7 b …
5y ago
[Python 3.8 (pre-release)], 69 …
4y ago
J, 24 char ```([: +/ [: ( …
4y ago
[Ruby], 36 bytes ```ruby - …
5y ago
[JavaScript (Node.js)], 34 29 …
4y ago
[Husk], 4 bytes Sz#ḣ …
5y ago
Scala 3, 50 44 bytes ```scala …
5y ago
[Jelly], 7 bytes =þ`ÄŒD …
5y ago
[Perl], 26 bytes su …
6mo ago
Uiua, 3 bytes (SBCS) Builti …
6mo ago
[Lean 4], 111 97 bytes ```l …
1y ago
Python 3, 50 bytes We can s …
1y ago
Haskell + hgl, 10 bytes ``` …
3y ago
Python 3, 70 bytes ```pytho …
4y ago
Factor, 122 bytes ``` USIN …
4y ago
Vyxal, 4 bytes ``` KƛtO ``` …
4y ago
[Python 3], 74 bytes …
4y ago
J, 9 bytes ```J 1#.]=&><\ …
4y ago
Ruby, 31 bytes ```ruby ->a …
4y ago
23 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.
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
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
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.
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 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
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
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
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
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
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, 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
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
Lean 4, 111 97 bytes
def d(l: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. Nope, got it down to sub-100 :)
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 3d 28 28 ce bb 78 3d 3e 28 6c 2e 72 65 76 |):=((..x=>(l.rev|
00000020 65 72 73 65 2e 64 72 6f 70 20 78 29 2e 63 6f 75 |erse.drop x).cou|
00000030 6e 74 20 6c 2e 72 65 76 65 72 73 65 5b 78 5d 29 |nt l.reverse[x])|
00000040 3c 24 3e 28 4c 69 73 74 2e 72 61 6e 67 65 20 6c |<$>(List.range l|
00000050 2e 6c 65 6e 67 74 68 29 29 2e 72 65 76 65 72 73 |.length)).revers|
00000060 65 |e|
0 comment threads
Haskell + hgl, 10 bytes
mpn$ce~<gj
Explanation
-
mpnmap across all non-empty prefixes of the input ... -
cecount the number of elements in each prefix equal to ... -
gjthe last element of that prefix.
Reflection
I'm happy with this. It doesn't take any extra steps, and the glue is cheap.
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