Enumerate each series of identical numbers in-place

27

1

Given a list of strictly positive integers, go through each distinct number and replace all occurrences of it with successive indices (zero or one based) of a new series.

Examples

[][]/[]

[42][0]/[1]

[7,7,7][0,1,2]/[1,2,3]

[10,20,30][0,0,0]/[1,1,1]

[5,12,10,12,12,10][0,0,0,1,2,1]/[1,1,1,2,3,2]

[2,7,1,8,2,8,1,8,2,8][0,0,0,0,1,1,1,2,2,3]/[1,1,1,1,2,2,2,3,3,4]

[3,1,4,1,5,9,2,6,5,3,5,9][0,0,0,1,0,0,0,0,1,1,2,1]/[1,1,1,2,1,1,1,1,2,2,3,2]

Adám

Posted 2019-01-08T09:27:59.477

Reputation: 37 779

2So basically the number of times it has appeared the sequence so far? – Jo King – 2019-01-08T09:41:02.817

1@JoKing Yes, that's another way to state it, but "so far" implies zero-based, and "until and including this" implies one-based. I wanted to keep the choice. – Adám – 2019-01-08T09:42:11.927

Answers

23

JavaScript (ES6), 26 bytes

1-indexed.

a=>a.map(o=x=>o[x]=-~o[x])

Try it online!

Commented

a =>                // a[] = input array
  a.map(o =         // assign the callback function of map() to the variable o, so that
                    // we have an object that can be used to store the counters
    x =>            // for each value x in a[]:
      o[x] = -~o[x] //   increment o[x] and yield the result
                    //   the '-~' syntax allows to go from undefined to 1
  )                 // end of map()

Arnauld

Posted 2019-01-08T09:27:59.477

Reputation: 111 334

1I have no idea how that works, but it sure looks elegant. – Adám – 2019-01-08T09:33:18.417

I've not seen -~ before - that is an absolute gem. – DaveMongoose – 2019-01-08T16:12:01.367

Alternatively, it's possible to use a to store the values, but it's required to -/~ the index so no byte is saved. – user202729 – 2019-01-09T04:25:07.593

@DaveMongoose Tips for golfing in JavaScript

– user202729 – 2019-01-09T04:25:16.830

Too bad this isn't C++, otherwise something like a=>a.map(x=>++(a[-x]|=0)) would save a byte. – user202729 – 2019-01-09T04:29:15.087

1@DaveMongoose -~ is actually a commonly used alternative to +1 (since it has different precedence) in many languages – ASCII-only – 2019-01-09T08:45:58.293

@ASCII-only Thanks for the info. I also like how the bitwise negation bulldozes through undefined – DaveMongoose – 2019-01-09T10:26:32.517

10

R, 27 bytes

function(x)ave(x,x,FUN=seq)

Try it online!

Explanation :

ave(x,x,FUN=seq) splits vector x into sub-vectors using values of x as grouping keys. Then seq function is called for each group and each result is re-arranged back in the original group position.

Better see an example :

x <- c(5,7,5,5,7,6)
ave(x, x, FUN=seq) # returns 1,1,2,3,2


 ┌───┬───┬───┬───┬───┐
 │ 5 │ 7 │ 5 │ 5 │ 7 │
 └───┴───┴───┴───┴───┘            
   |   |   |    |  |     
   ▼   |   ▼    ▼  |
 GROUP A : seq(c(5,5,5)) = c(1,2,3)
   |   |   |    |  |     
   ▼   |   ▼    ▼  |
 ┌───┐ | ┌───┬───┐ |
 │ 1 │ | │ 2 │ 3 │ |
 └───┘ | └───┴───┘ |
       ▼           ▼
 GROUP B : seq(c(7,7)) = c(1,2)
       |           |
       ▼           ▼
     ┌───┐       ┌───┐
     │ 1 │       │ 2 │
     └───┘       └───┘ 

   |   |   |   |   |
   ▼   ▼   ▼   ▼   ▼ 
 ┌───┬───┬───┬───┬───┐
 │ 1 │ 1 │ 2 │ 3 │ 2 │
 └───┴───┴───┴───┴───┘  

Note :

seq(y) function returns a sequence 1:length(y) in case y has length(y) > 1, but returns a sequence from 1:y[1] if y contains only one element.
This is fortunately not a problem because in that case R - complaining with a lot of warnings - selects only the first value which is incidentally what we want :)

digEmAll

Posted 2019-01-08T09:27:59.477

Reputation: 4 599

2Brilliant! I'll add a bounty for this. Never seen ave before. – Giuseppe – 2019-01-13T19:55:43.700

I'm honored, thanks a lot ! :) – digEmAll – 2019-01-14T06:36:56.663

6

MATL, 4 bytes

&=Rs

This solution is 1-based

Try it out at MATL Online!

Explanation

Uses [1,2,3,2] as an example

    # Implicitly grab the input array of length N
    #
    #   [1,2,3,2]
    #
&=  # Create an N x N boolean matrix by performing an element-wise comparison
    # between the original array and its transpose:
    #
    #     1 2 3 2
    #     -------
    # 1 | 1 0 0 0
    # 2 | 0 1 0 1
    # 3 | 0 0 1 0
    # 2 | 0 1 0 1
    #
R   # Take the upper-triangular portion of this matrix (sets below-diagonal to 0)
    #
    #   [1 0 0 0
    #    0 1 0 1
    #    0 0 1 0
    #    0 0 0 1]
    #
s   # Compute the sum down the columns
    #
    #   [1,1,1,2]
    #
    # Implicitly display the result

Suever

Posted 2019-01-08T09:27:59.477

Reputation: 10 257

2

ah, I knew there was an old problem that made me think of something similar, it's Unique is Cheap, and the MATL solution there is one character different!

– Giuseppe – 2019-01-08T15:33:19.903

5

J, 7 bytes

1#.]=]\

Try it online!

1-indexed.

Explanation:

]\ all the prefixes (filled with zeros, but there won't be any 0s in the input):
   ]\ 5 12 10 12 12 10
5  0  0  0  0  0
5 12  0  0  0  0
5 12 10  0  0  0
5 12 10 12  0  0
5 12 10 12 12  0
5 12 10 12 12 10

]= is each number from the input equal to the prefix:
   (]=]\) 5 12 10 12 12 10
1 0 0 0 0 0
0 1 0 0 0 0
0 0 1 0 0 0
0 1 0 1 0 0
0 1 0 1 1 0
0 0 1 0 0 1

1#. sum each row:
   (1#.]=]\) 5 12 10 12 12 10
1 1 1 2 3 2

K (oK), 11 10 bytes

-1 byte thanks to ngn!

{+/'x=,\x}

Try it online!

Galen Ivanov

Posted 2019-01-08T09:27:59.477

Reputation: 13 815

1Heh, you're happy that I made the data strictly positive… – Adám – 2019-01-08T15:06:43.417

@Adám Yes, otherwise I'd need to box the prefixes :) – Galen Ivanov – 2019-01-08T15:16:37.863

1in k: =' -> = – ngn – 2019-01-31T13:17:17.010

5

APL (Dyalog Unicode), 7 bytes

Many, many thanks to H.PWiz, Adám and dzaima for all their help in debugging and correcting this.

+/¨⊢=,\

Try it online!

Explanation

The 10-byte non-tacit version will be easier to explain first

{+/¨⍵=,\⍵}

{         } A user-defined function, a dfn
      ,\⍵  The list of prefixes of our input list ⍵
           (⍵ more generally means the right argument of a dfn)
           \ is 'scan' which both gives us our prefixes 
           and applies ,/ over each prefix, which keeps each prefix as-is
    ⍵=     Checks each element of ⍵ against its corresponding prefix
           This checks each prefix for occurrences of the last element of that prefix
           This gives us several lists of 0s and 1s
 +/¨       This sums over each list of 0s and 1s to give us the enumeration we are looking for

The tacit version does three things

  • First, it removes the instance of used in ,\⍵ as ,\ on the right by itself can implicitly figure out that it's supposed to operate on the right argument.
  • Second, for ⍵=, we replace the with , which stands for right argument
  • Third, now that we have no explicit arguments (in this case, ), we can remove the braces {} as tacit functions do not use them

Sherlock9

Posted 2019-01-08T09:27:59.477

Reputation: 11 664

5

AWK, 14

  • 1 byte saved thanks to @NahuelFouilleul
{print++a[$1]}

Try it online!

The above does one-based indexing. If you prefer zero-based indexing, its an extra byte:

{print a[$1]++}

Try it online!

Digital Trauma

Posted 2019-01-08T09:27:59.477

Reputation: 64 644

1note that second can save one byte {print++a[$1]} without space seems to be working – Nahuel Fouilleul – 2019-01-11T08:20:23.703

@NahuelFouilleul Thanks! – Digital Trauma – 2019-01-11T18:48:24.440

4

Python 2, 48 bytes

lambda a:[a[:i].count(v)for i,v in enumerate(a)]

Try it online!

TFeld

Posted 2019-01-08T09:27:59.477

Reputation: 19 246

4

05AB1E, 4 bytes

ηε¤¢

Try it online! or as a Test Suite

Explanation

ηε     # apply to each prefix of the input list
  ¤¢   # count occurrences of the last element

Emigna

Posted 2019-01-08T09:27:59.477

Reputation: 50 798

3

C# (Visual C# Interactive Compiler), 44 bytes

x=>x.Select((y,i)=>x.Take(i).Count(z=>z==y))

Try it online!

dana

Posted 2019-01-08T09:27:59.477

Reputation: 2 541

22 bytes – LiefdeWen – 2019-01-08T13:17:46.790

You have the inversed of the challenge right now.. [7,7,7] should output [0,1,2], and not [0,0,0]. – Kevin Cruijssen – 2019-01-08T15:42:28.147

1@KevinCruijssen - Thanks :) Looks like I misread things, it should be fixed now. – dana – 2019-01-08T15:59:24.430

2

Perl 6, 15 bytes

*>>.&{%.{$_}++}

Try it online!

You can move the ++ to before the % for a one based index.

Explanation:

*>>.&{        }  # Map the input to
      %          # An anonymous hash
       .{$_}     # The current element indexed
            ++   # Incremented

Jo King

Posted 2019-01-08T09:27:59.477

Reputation: 38 234

2

Python 2, 47 43 bytes

f=lambda a:a and f(a[:-1])+[a.count(a[-1])]

Try it online!

A recursive 'one-based' solution.

Chas Brown

Posted 2019-01-08T09:27:59.477

Reputation: 8 959

2

Jelly, 4 bytes

ċṪ$Ƥ

Try it online!

For each prefix of the input list, it counts the number of occurrences of its last element in itself.

Mr. Xcoder

Posted 2019-01-08T09:27:59.477

Reputation: 39 774

Alternatively the old-school ;\ċ" is also 4. – Jonathan Allan – 2019-01-08T14:39:34.193

2

R, 41 bytes

function(x)diag(diffinv(outer(x,x,"==")))

Try it online!

Oddly, returning a zero-based index is shorter in R.

Giuseppe

Posted 2019-01-08T09:27:59.477

Reputation: 21 077

Once again Giuseppe, your superior knowledge of R has beaten me. I had a decently ingenious method at 60 bytes, but alas, it wasn't enough! – Sumner18 – 2019-01-08T17:21:14.050

@Sumner18 post it anyway! I always learn a lot from other peoples' approaches, and getting feedback is the fastest way to learn! – Giuseppe – 2019-01-08T17:23:35.400

thanks for the encouragement! I've posted mine now and am always open to suggestions for improvement! – Sumner18 – 2019-01-08T17:45:51.553

2

Ruby, 35 bytes

->a{f=Hash.new 0;a.map{|v|f[v]+=1}}

It's pretty mundane, unfortunately - build a hash that stores the total for each entry encountered so far.

Some other, fun options that unfortunately weren't quite short enough:

->a{a.dup.map{a.count a.pop}.reverse}   # 37
->a{i=-1;a.map{|v|a[0..i+=1].count v}}  # 38

DaveMongoose

Posted 2019-01-08T09:27:59.477

Reputation: 231

2

R, 62 43 bytes

x=z=scan();for(i in x)z[y]=1:sum(y<-x==i);z

-19 bytes thanks to Giuseppe, by removing which, and table, and only slight changes to the implementation

Original

x=z=scan();for(i in names(r<-table(x)))z[which(x==i)]=1:r[i];z

I can't compete with Giuseppe's knowledge, so my submission is somewhat longer than his, but using my basic knowledge, I felt that this solution was rather ingenious.

r<-table(x) counts the number of times each number appears and stores it in r, for future reference

names() gets the values of each unique entry in the table, and we iterate over these names with a for loop.

The remaining portion checks which entries are equal to the iterations and stores a sequence of values (from 1 to the number of entries of the iteration)

Try it online!

Sumner18

Posted 2019-01-08T09:27:59.477

Reputation: 1 334

you can remove the which() to save 7 bytes. – Giuseppe – 2019-01-08T18:09:56.763

Your use of 1:r[i] gave me the idea to just remove table() entirely: x=z=scan();for(i in x)z[y]=1:sum(y<-x==i);z is 43 bytes! This is a nice approach! – Giuseppe – 2019-01-08T18:16:50.297

Looks like neither of us can compete with digEmAll's R knowledge!

– Giuseppe – 2019-01-14T23:25:12.677

I saw that and was absolutely flabbergasted! – Sumner18 – 2019-01-15T13:51:31.957

2

Haskell, 44 bytes

([]#)
x#(y:z)=sum[1|a<-x,a==y]:(y:x)#z
_#e=e

Try it online!

Explanation

Traverses the list from left to right keeping the list x of visited elements, initially []:

For every encounter of a y count all equal elements in the list x.

ბიმო

Posted 2019-01-08T09:27:59.477

Reputation: 15 345

1

A bit longer but maybe nevertheless interesting: (#(0*));(x:r)#g=g x:r# \y->0^abs(y-x)+g y;e#g=e Try it online!

– Laikoni – 2019-01-10T18:57:41.810

@Laikoni: How did you even come up with that, you should totally post it! – ბიმო – 2019-01-10T19:15:22.200

1

Done: https://codegolf.stackexchange.com/a/178629/56433

– Laikoni – 2019-01-10T19:50:12.903

2

Haskell, 47 46 bytes

(#(*0))
(x:r)#g=g x:r# \y->0^(y-x)^2+g y
e#g=e

Try it online!

A different approach than BMO's answer which turned out a bit longer. (And kindly borrows their nice test suit.)

The idea is to iterate over the input list and keep track of the number of times each element has occurred by updating a function g. Ungolfed:

f (const 0)
f g (x:r) = g x : f (\ y -> if x==y then 1 + g y else g y) r
f g []    = []

Two interesting golfing opportunities arose. First for the initial value of g, a constant function which disregards its argument and returns 0:

const 0  -- the idiomatic way
(\_->0)  -- can be shorter if parenthesis are not needed
min 0    -- only works as inputs are guaranteed to be non-negative
(0*)     -- obvious in hindsight but took me a while to think of

And secondly an expression over variables x and y which yields 1 if x equals y and 0 otherwise:

if x==y then 1else 0  -- yes you don't need a space after the 1
fromEnum$x==y         -- works because Bool is an instance of Enum
sum[1|x==y]           -- uses that the sum of an empty list is zero
0^abs(x-y)            -- uses that 0^0=1 and 0^x=0 for any positive x
0^(x-y)^2             -- Thanks to  Christian Sievers!

There still might be shorter ways. Anyone got an idea?

Laikoni

Posted 2019-01-08T09:27:59.477

Reputation: 23 676

1You can use 0^(x-y)^2. – Christian Sievers – 2019-01-10T23:02:47.537

1

Java (JDK), 76 bytes

a->{for(int l=a.length,i,c;l-->0;a[l]=c)for(c=i=0;i<l;)c+=a[l]==a[i++]?1:0;}

Try it online!

Credits

Olivier Grégoire

Posted 2019-01-08T09:27:59.477

Reputation: 10 647

1-2 bytes by changing for(c=0,i=l;i-->0;)c+=a[l]==a[i]?1:0; to for(c=i=0;i<l;)c+=a[l]==a[i++]?1:0;. – Kevin Cruijssen – 2019-01-08T15:53:11.697

1

bash, 37 24 bytes

f()(for x;{ r+=$[a[x]++]\ ;};echo $r)

TIO

if valid, there is also this variation, as suggested by DigitalTrauma

for x;{ echo $[a[x]++];}

TIO

Nahuel Fouilleul

Posted 2019-01-08T09:27:59.477

Reputation: 5 582

1

Pass the list as command line args - https://tio.run/##S0oszvj/Py2/SKHCuporNTkjX0ElOjG6IlZbO5ar9v///8b/Df@bALHpf8v/Rv/NgLQxiA0A - only 24 bytes.

– Digital Trauma – 2019-01-08T20:17:32.633

@DigitalTrauma, thanks however i don't know if it broke the rules. also as it was asked to replace list and maybe should be something like https://tio.run/##NUtLCoMwFNz3FFPJIkEKJtrWEgIuvUPIIpWKBVGILoSQs9skUB7z5sPM227TeY6UefSKMjmvg51xW@AU4RLj6nDgu4D4q9OdCdLD6cMoonudhClLI4MM577tlMHDKko6FpewEp9hWlEQb9O0kAiXWEtAIzI902XFK4gKdZXNHVykJP0kcihil6ON3P4553V0TcQdr5g9ItdJnz8

– Nahuel Fouilleul – 2019-01-09T08:28:19.633

2@NahuelFouilleul It's fine, full programs are allowed too, and that's a valid method of inputting/outputting a list (IMO) – ASCII-only – 2019-01-09T08:44:40.560

1

Ruby, 34 bytes

->a{r=[];a.map{|x|(r<<x).count x}}

Try it online!

G B

Posted 2019-01-08T09:27:59.477

Reputation: 11 099

I can't believe I tried ->a{i=-1;a.map{|v|a[0..i+=1].count v}} and didn't think of just building a new array, lol. Nice work. – DaveMongoose – 2019-01-09T10:23:07.993

1

Perl 5, 11 bytes

$_=$h{$_}++

TIO

explanations following comment

  • $_ perl's special variable containing current line when looping over input (-p or -n switches)
  • $h{$_}++ autovivifies the map %h and creates an entry with key $_ and increments and gives the value before increment
  • the special variable is printed because of -p switch, -l switch removes end of line on input and adds end of line on output

Nahuel Fouilleul

Posted 2019-01-08T09:27:59.477

Reputation: 5 582

That looks amazing. Care to explain? – Adám – 2019-01-11T10:42:11.080

@Adám, thank you for your feedback, sure, done – Nahuel Fouilleul – 2019-01-11T10:47:51.857

1

C (gcc), 65 62 bytes

c,d;f(a,b)int*a;{for(;c=d=b--;a[b]=d)for(;c--;d-=a[c]!=a[b]);}

Try it online!

-2 bytes thanks to ASCII-only


This felt too straightforward, but I couldn't seem to get any shorter with a different approach.

attinat

Posted 2019-01-08T09:27:59.477

Reputation: 3 495

63 – ASCII-only – 2019-01-14T04:59:19.490

@ASCII-only is this a valid answer? No header included, no declarations, it's a snippet plus many warnings although it outputs. – AZTECCO – 2019-01-14T15:16:27.870

@AZTECCO warnings are fine (stderr is ignored), as long as it does what it should it's acceptable. note that this is a function declaration, plus some variable declarations - you can put it anywhere as a top level expression and it will compile fine. a lot of c answers (and those in languages with less strict syntax) do generally have quite a few warnings because of bytesaves that aren't good code style – ASCII-only – 2019-01-14T23:33:46.783

Ok I can understand, but there's still something not right to me. If we want to test with a different set(in size) we have to modify the code, even in the print loop, plus the input should be just the set, not its size."Given a list of strictly positive integers..." so I think input should be just the list. – AZTECCO – 2019-01-15T15:37:05.180

@AZTECCO not sure if this discussion should belong in this answer's comments, but you might want to take a look at meta - specifically on I/O and answer formats.

– attinat – 2019-01-15T22:58:13.420

Ok thank you both two for helping me understand the rules here at codegolf. Short solution btw!+1 – AZTECCO – 2019-01-16T08:08:27.157

1

Pari/GP, 32 bytes

a->p=0;[polcoeff(p+=x^t,t)|t<-a]

The \$k\$-th element in the answer is the coefficient of the \$x^{a_k}\$ term in the polynomial \$\sum_{i=1}^kx^{a_i}\$.

Try it online!

alephalpha

Posted 2019-01-08T09:27:59.477

Reputation: 23 988

1

Wolfram Language (Mathematica), 33 bytes

Accumulate@#~Coefficient~#&[x^#]&

The \$k\$-th element in the answer is the coefficient of the \$x^{a_k}\$ term in the polynomial \$\sum_{i=1}^kx^{a_i}\$.

Try it online!

alephalpha

Posted 2019-01-08T09:27:59.477

Reputation: 23 988

1

Attache, 23 bytes

{`~&>Zip[_,_[0:#_::0]]}

Try it online!

Explanation

{`~&>Zip[_,_[0:#_::0]]}
{                     }    _: input (e.g., [5, 12, 10, 12, 12, 10])
             0:#_          range from 0 to length of input (inclusive)
                           e.g., [0, 1, 2, 3, 4, 5, 6]
                 ::0       descending range down to 0 for each element
                           e.g., [[0], [1, 0], [2, 1, 0], [3, 2, 1, 0], [4, 3, 2, 1, 0], [5, 4, 3, 2, 1, 0], [6, 5, 4, 3, 2, 1, 0]]
           _[       ]      get input elements at those indices
                           e.g., [[5], [12, 5], [10, 12, 5], [12, 10, 12, 5], [12, 12, 10, 12, 5], [10, 12, 12, 10, 12, 5], [nil, 10, 12, 12, 10, 12, 5]]
     Zip[_,          ]     concatenate each value with this array
                           e.g., [[5, [5]], [12, [12, 5]], [10, [10, 12, 5]], [12, [12, 10, 12, 5]], [12, [12, 12, 10, 12, 5]], [10, [10, 12, 12, 10, 12, 5]]]
   &>                      using each sub-array spread as arguments...
 `~                            count frequency
                               e.g. [12, [12, 10, 12, 5]] = 12 ~ [12, 10, 12, 5] = 2

Conor O'Brien

Posted 2019-01-08T09:27:59.477

Reputation: 36 228

1

K (ngn/k), 18 bytes

(,/.!'#'=x)@<,/.=x

Try it online!


OLD APPROACH

K (ngn/k), 27 23 22 bytes

{x[,/.=x]:,/.!'#'=x;x}

Try it online!


this is not pretty... quick and dirty solution, i will be refining this later when i get the chance to think of a better approach

explanation:

  • =x returns a dict where keys are items of x and values are their indices (3 1 4 5 9 2 6!(0 9;1 3;,2;4 8 10;5 11;,6;,7))
  • i: assign dict to i
  • #:' count values for each key (3 1 4 5 9 2 6!2 2 1 3 2 1 1)
  • !:' enumerate each value (3 1 4 5 9 2 6!(0 1;0 1;,0;0 1 2;0 1;,0;,0))
  • ,/.: extract values and flatten list (0 1 0 1 0 0 1 2 0 1 0 0)
  • x[,/.:i]: extract indices from i, flatten, and assign each value from the right-side list at these indices

annoyingly, the list is updated but a null value is returned by the assignment, so i need to return the list after the semicolon (;x)

edit: removed extraneous colons

edit2: removed unnecessary assignment

scrawl

Posted 2019-01-08T09:27:59.477

Reputation: 1 079

0

Retina 0.8.2, 30 bytes

\b(\d+)\b(?<=(\b\1\b.*?)+)
$#2

Try it online! Link includes test cases. 1-indexed. Explanation: The first part of the regex matches each integer in the list in turn. The lookbehind's group matches each occurrence of that integer on that line up to and including the current integer. The integer is then substituted with the number of matches.

Neil

Posted 2019-01-08T09:27:59.477

Reputation: 95 035

0

Batch, 61 bytes

@setlocal
@for %%n in (%*)do @set/ac=c%%n+=1&call echo %%c%%

1-indexed. Because variable substitution happens before parsing, the set/a command ends up incrementing the variable name given by concatenating the letter c with the integer from the list (numeric variables default to zero in Batch). The result is then copied to another integer for ease of output (more precisely, it saves a byte).

Neil

Posted 2019-01-08T09:27:59.477

Reputation: 95 035

0

Japt, 8 bytes

£¯YÄ è¶X

Try it here

£¯YÄ è¶X
             :Implicit input of array U
£            :Map each X at 0-based index Y
 ¯           :  Slice U to index
  YÄ         :    Y+1
     è       :  Count the elements
      ¶X     :    Equal to X

Shaggy

Posted 2019-01-08T09:27:59.477

Reputation: 24 623

0

awk 46 31 bytes

-15 bytes thanks to @Dennis

{for(;i++<NF;)$i=a[$i]++;print}

TIO

Nahuel Fouilleul

Posted 2019-01-08T09:27:59.477

Reputation: 5 582

I think {for(;i++<NF;)$i=a[$i]++;print} works. delete(a); is only needed for the test suite, no? – Dennis – 2019-01-11T01:10:31.057

@Dennis, thank you for your feedback, however DigitalTrauma's version is still shorter – Nahuel Fouilleul – 2019-01-11T08:10:09.260

0

Tcl, 48 bytes

proc C L {lmap n $L {dict g [dict inc D $n] $n}}

Try it online!

sergiol

Posted 2019-01-08T09:27:59.477

Reputation: 3 055

0

Haxe, 58 bytes

l->{var x=[0=>0];l.map(e->++x[(x[e]==null?x[e]=0:0)+e]);};

(Requires arrow functions, so 4.0+)

var x=[0=>0] declares a new IntMap, with 0 as its only key (since the question say inputs are strictly positive). Unfortunately most targets throw when adding null to a number, hence the explicit check to make sure each key is in the map before incrementing.

Also a cheeky rip off based on the JS answer:

Haxe (JS target), 41 bytes

l->{var x=[0=>0];l.map(e->x[e]=-~x[e]);};

Try both online

Aurel Bílý

Posted 2019-01-08T09:27:59.477

Reputation: 1 083

0

GO 121 Bytes (Not included new lines and tabs)

func cg(a []int) []int{
    var m = make(map[int]int)
    var r = make([]int, len(a))
    for i,v := range a{
        r[i] = m[v]
        m[v]++
    }
    return r
}

Accepts integer array and returns integer array.

the ultimate user

Posted 2019-01-08T09:27:59.477

Reputation: 101

5

Welcome to PPCG. Rare to see Go represented here. You do need to count necessary newlines, but you also have a lot of spaces that can be removed, and you can also shorten cg to c. I recommend using TIO to generate the main part of your post: Try it online!

– Adám – 2019-01-09T09:53:20.520

0

Python 2, 44 bytes

a=[]
for x in input():print a.count(x);a+=x,

Try it online!

The first thing I wrote tied Chas Brown's 43, so here's a different solution that's one byte longer.

Lynn

Posted 2019-01-08T09:27:59.477

Reputation: 55 648

0

Reticular, 17 bytes

L[ddc@c~]~*$qlbo;

Try it online!

The input list of integers is assumed to already be pushed to the stack. Run the following code to test input:

'2''7''1''8''2''8''1''8''2''8'lbL[ddc@c~]~*$qlbo;

Explanation

The pop instruction c which is supposed to: pop a list from the stack, pop the last element from that list and push this element to the stack. However, if the list occurs at more than 1 place in the stack (if it has been duplicated for example), all of the duplicated lists in the stack will also have their last element popped contrary to what one might think will happen. This is fortunately used in our favor in this puzzle.

L                 # Push length of input list to the stack.
 [      ]         # Push the following function:
  dd              # Duplicate top of stack twice.
    c             # Pop the list at top of the stack,
                    pop the last element in the list (which will pop the element of every list!)
                    and finally push it to the stack.
     @c           # Pop two items at the top of the stack (list + last element in that list).
                    then push the number of occurrences of that element in the list.
       ~          # Swap top two items in the stack (so that the popped list is on top again).
         ~        # Swap top two items in the stack.
          *       # Call the above function the same number of times as length of the input list.
           $      # Remove the item at the top of the stack (which by now is an empty list).
            q     # Reverse stack.
             lb   # Push size of stack and put that many items from the stack into a list.
               o; # Output resulting list and exit.

Wisław

Posted 2019-01-08T09:27:59.477

Reputation: 554

0

SNOBOL4 (CSNOBOL4), 63 bytes

 T =TABLE()
R I =INPUT :F(END)
 T<I> =OUTPUT =T<I> + 1 :(R)
END

Try it online!

Giuseppe

Posted 2019-01-08T09:27:59.477

Reputation: 21 077

0

C++ (gcc), 122 bytes

#import<vector>
using V=std::vector<int>;V f(V x){for(int i,t,z=x.size();t=i=z--;x[z]=t)for(;i--;)t-=x[z]!=x[i];return x;}

Try it online!

Saved 2 more bytes thanks to @ceilingcat

AZTECCO

Posted 2019-01-08T09:27:59.477

Reputation: 2 441

0

C# (.NET Core), 172 bytes

Without LINQ. 0 indexed int[] arrays.

p=>{int h=0,m=0,l=p.Length,j;var k=new int[l];if(l>0){foreach(int z in p){h=z>h?z:h;m=z<m?z:m;}for(j=m;j<=h;j++,m=0)for(int z=0;z<l;z++)k[z]=p[z]==j?m++:k[z];}return k;}

Try it online!

Destroigo

Posted 2019-01-08T09:27:59.477

Reputation: 401

0

Pyth, 7 bytes

.e/<Qkb

Try it online!

.e     Q # enumerated map over (implicit) Q (input): lambda k,b: (k=index, b=element)
  /   b  # number of occurences of b in
   <Qk   # Q[:k]

Alternative 1-based solution (7 bytes)

m/ded._

Try it online!

m    ._ # map over all prefixes of (implicit) Q (input): lambda d:
 / ed   # Number of occurences of d[-1] in
  d     #                                  d

ar4093

Posted 2019-01-08T09:27:59.477

Reputation: 531

0

SAP ABAP, 174 bytes

FORM f TABLES t.DATA r TYPE int_tab1.LOOP AT t.DATA(i) = 0.DATA(x) = sy-tabix.LOOP AT t.CHECK:sy-tabix < x,t = t[ x ].i = i + 1.ENDLOOP.APPEND i TO r.ENDLOOP.t[] = r.ENDFORM.

Subroutine which takes a table of integers and replaces all values with zero-based indices. ABAP has no array type, so a table of integers is the closest thing we have. It uses the builtin table type int_tab1 to save some bytes over declaring TYPE TABLE OF i and abuses obsolete (but still functional) internal tables with header lines, which allows us to use LOOP AT t and read t at the implicit index sy-tabix without declaring additional variables for keeping the value.


Full program with some test cases from OP can be found here. Output below: Results from the test cases

Forgot to add the two edge cases of [ ] and [42], but they work, too:
[ ] => An empty input table stays empty as the outer loop gets skipped completely
[42] => A single value in the table means table line 1 in the inner loop is skipped, since sy-tabix is equal to x - therefore i stays 0 and the output is [0].


Explanation:

FORM f TABLES t.              "Subroutine, TABLES parameters are references
  DATA r TYPE int_tab1.       "A temporary internal table for results
  LOOP AT t.                  "Go over each line in table t
    DATA(i) = 0.              "Set count to 0            (inline declaration)
    DATA(x) = sy-tabix.       "Set x to current index    (inline declaration)
    LOOP AT t.                "Go over each line in table t again
      CHECK:                  "Check whether... (works like a CONTINUE if not true)
        sy-tabix < x,         "1) ...inner LOOP index is smaller than outer index (= only check lines up to outer index - 1)
        t = t[ x ].           "2) ...value of t at inner index (implicit) is equal to value of t at outer index (x)
      i = i + 1.              "If both are true, increase the counter by 1
    ENDLOOP.                  
    APPEND i TO r.            "Add the count for this value to temporary results table
  ENDLOOP.                    
  t[] = r.                    "Fill referenced table t with the values in r.
ENDFORM.

Maz

Posted 2019-01-08T09:27:59.477

Reputation: 191

0

Gema, 32 characters

<D>=@set{$1;@add{${$1;};1}}${$1}

Outputs 1 based indexes.

Sample run:

bash-5.0$ gema '<D>=@set{$1;@add{${$1;};1}}${$1}' <<< '[5,12,10,12,12,10]'
[1,1,1,2,3,2]

Try it online!

Gema, 34 characters

<D>=${$1;0}@set{$1;@add{${$1;};1}}

Outputs 0 based indexes.

Sample run:

bash-5.0$ gema '<D>=${$1;0}@set{$1;@add{${$1;};1}}' <<< '[5,12,10,12,12,10]'
[0,0,0,1,2,1]

Try it online!

manatwork

Posted 2019-01-08T09:27:59.477

Reputation: 17 865