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.









  • 2
    \$\begingroup\$ So basically the number of times it has appeared the sequence so far? \$\endgroup\$ – Jo King Jan 8 at 9:41
  • 1
    \$\begingroup\$ @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. \$\endgroup\$ – Adám Jan 8 at 9:42

41 Answers 41


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


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]
    return r

Accepts integer array and returns integer array.

  • 5
    \$\begingroup\$ 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! \$\endgroup\$ – Adám Jan 9 at 9:53

Python 2, 44 bytes

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.


Reticular, 17 bytes


Try it online!

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



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.

SNOBOL4 (CSNOBOL4), 63 bytes

 T<I> =OUTPUT =T<I> + 1 :(R)

Try it online!


awk 46 31 bytes

-15 bytes thanks to @Dennis



  • \$\begingroup\$ I think {for(;i++<NF;)$i=a[$i]++;print} works. delete(a); is only needed for the test suite, no? \$\endgroup\$ – Dennis Jan 11 at 1:10
  • \$\begingroup\$ @Dennis, thank you for your feedback, however DigitalTrauma's version is still shorter \$\endgroup\$ – Nahuel Fouilleul Jan 11 at 8:10

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!


Pyth, 7 bytes


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)


Try it online!

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

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].


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
    APPEND i TO r.            "Add the count for this value to temporary results table
  t[] = r.                    "Fill referenced table t with the values in r.

Gema, 32 characters


Outputs 1 based indexes.

Sample run:

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

Try it online!

Gema, 34 characters


Outputs 0 based indexes.

Sample run:

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

Try it online!


C++ (gcc), 122 bytes

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


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.