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 …
3y ago
[APL (Dyalog Unicode)], 11 byt …
3y ago
[Jelly], 4 bytes ¹Ƥċ" …
3y ago
Japt, 14 11 8 bytes £¯Y …
3y ago
[APL (Dyalog Unicode)], 11 7 b …
3y ago
[Ruby], 36 bytes ```ruby - …
3y ago
[JavaScript (Node.js)], 34 29 …
2y ago
[Husk], 4 bytes Sz#ḣ …
3y ago
Scala 3, 50 44 bytes ```scala …
3y ago
[Jelly], 7 bytes =þ`ÄŒD …
3y ago
Haskell + hgl, 10 bytes ``` …
1y 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#.]=&><\ …
2y ago
J, 24 char ```([: +/ [: ( …
2y ago
Ruby, 31 bytes ```ruby ->a …
2y ago
19 answers
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
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
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
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
Husk, 4 bytes
Sz#ḣ
Explanation
Sz#ḣ
Sz zip the input
ḣ with its prefixes
# using the count function
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
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.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
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
Haskell + hgl, 10 bytes
mpn$ce~<gj
Explanation
-
mpn
map across all non-empty prefixes of the input ... -
ce
count the number of elements in each prefix equal to ... -
gj
the 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
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