g | x | w | all
Bytes Lang Time Link
051Desmos250924T023302ZDesmosEn
032Arturo250918T165212Zchunes
042Factor250917T185842Zchunes
039Python250915T151108ZAlbert.L
003Jelly250916T231224ZJonathan
012Pip p250916T200342ZDLosc
046Haskell250916T110012ZRubenVer
028x86_64 machine code250916T140910ZIfier
022R250915T152502ZGiuseppe
044Haskell250916T111736Zxnor
110Haskell250916T061536ZDannyu N
028JavaScript ES12250915T131823ZArnauld
003MATL250916T042733ZLuis Men
00405AB1E250915T235834ZLucenapo
053Maple250915T234340Zdharr
037Google Sheets250915T204031Zdoubleun
013Charcoal250915T145049ZNeil
027APLNARS250915T144719ZRosario
031Ruby250915T142830ZG B
004Vyxal 3250915T135258ZThemooni
002TinyAPL250915T135049ZRubenVer
003Uiua250915T131742Zlyxal

Desmos, 51 Bytes

f(a)=b[a[i]=a.unique][1]fori=b
b=[1...a.count][a=a]

This works by looping over the array a, and for each element, the new value is the index of that item in the "unique" array, which is the array of unique items in the array a, in order of when they appear.

b=                             // Initialise b
  [1...a.count]                // Make a list of consecutive numbers up to the length of the "a" array
               [a=a]           // Filter array by if that element of a = itself (this makes sure that if a is an empty array, b is empty as well, instead of [1,0])

f(a)=                          // Declare main function
                        fori=b // Loop for every element in b
     b[             ][1]       // Loop over b and find the first element in b that satisfies the following condition
       a[i]=a.unique           // The item being checked by the outer loop is equivalent to the b'th element of the "unique items" list

Try it in Desmos!

Arturo, 32 bytes

$->a[map a=>[1+index unique a&]]

Try it!

Factor, 42 bytes

[ dup members zip-index substitute 1 v+n ]

Attempt This Online!


Factor + math.extras, 28 bytes

[ unique-indices nip 1 v+n ]

Attempt This Online!

Python, 39 bytes

lambda L:map([*dict(zip(L,L))].index,L)

Attempt This Online!

Output is zero-based.

If you must have one-based, @Lucenaposition has a 2 byte fix:

Python, 41 bytes

lambda L:map([L,*dict(zip(L,L))].index,L)

Attempt This Online!

Notes

We use a dict where a set would appear more logical, because dicts are guaranteed to keep key creation order.

Jelly, 3 bytes

QiⱮ

A monadic Link that accepts a list of positive integers and yields its lexicographically minimal relabeling.

Try it online!

How?

QiⱮ - Link: list of positive integers, L
Q   - deduplicate {L}
  Ɱ - map with:
 i  -   first 1-index of {current element of L} in {deduplicated L}

Pip -p, 12 bytes

U:(UQg)@?_Mg

Attempt This Online!

Explanation

U:(UQg)@?_Mg
          Mg  Map this function to the list of command-line arguments:
       @?       Find the first (0-based) index of
         _      The function argument
  (UQg)         In the uniquified list of command-line arguments
U:            Increment the result list to make it 1-based

Haskell, 46 bytes

import Data.List
flip elemIndex.(:)0.nub>>=map

Returns a [Maybe Int] where all the maybes are (trivially) Justs, which is allowed.

Thanks @xnor and @Wheat Wizard for -14

Explanation: index of each element of the input in the unique elements of the input prefixed with 0 (which is always extraneous and therefore amounts to adding 1 to the indices)

x86_64 machine code, 28 bytes

Running on Godbolt

0:  53                      push   rbx
1:  e3 17                   jrcxz  1a <end>
3:  52                      push   rdx
4:  5b                      pop    rbx
5:  31 c0                   xor    eax,eax
0000000000000007 <load>:
7:  ac                      lods   al,BYTE PTR ds:[rsi]
8:  0f b6 d0                movzx  edx,al
b:  d7                      xlat   BYTE PTR ds:[rbx]
c:  84 c0                   test   al,al
e:  75 07                   jne    17 <store>
0000000000000010 <mklabel>:
10: fe c4                   inc    ah
12: 88 24 13                mov    BYTE PTR [rbx+rdx*1],ah
15: 88 e0                   mov    al,ah
0000000000000017 <store>:
17: aa                      stos   BYTE PTR es:[rdi],al
18: e2 ed                   loop   7 <load>
000000000000001a <end>:
1a: 5b                      pop    rbx
1b: c3                      ret

Uses sysv calling convention, takes a C-style function interface of:

void relabel(unsigned char* out, unsigned char* original, unsigned char* table, unsigned long long count)

where out is an appropriately sized output buffer and table is a zero-initialised array of bytes equal in size to at least the number of unique symbols in the input + 1.

It simply goes through the input, looks up the translation for the character in a lookup table, generates a lookup table entry is the translation is 0 (uninitialised), and then stores the translated character in the output. I'm treating output bytes at 8-bit binary numbers instead of characters.

R, 22 bytes

\(a)match(a,unique(a))

Attempt This Online!

Self-applied match() very nearly has this functionality.

Thanks to jared_mamrot and SamR in the comments for prompting discussion around factor(): At first glance, since factors are stored as integers, it seems that factor should be a complete answer at 6 bytes, but unfortunately by default the levels are computed as sort(unique(x)), where the sort screws up the lexicographically first relabelling, so we end up with \(a)factor(a,unique(a)), which is 23 bytes, and technically prints out the original array.

Haskell, 44 bytes

map=<<g
g(h:t)n|h==n=1|1>0=1+g[x|x<-t,x/=h]n

Try it online!

Look ma, no imports!

The main function is pointfree for f l=g l<$>l.

The helper g takes a list and a value n, and counts the distinct elements up to the first appearance of n. With nub, this could be 1+length(nub$fst$span(/=n)l), but nub requires an import. Instead, g recurses, adding 1 for each new element until it reaches the target value n (with base value 1 for 1-indexing), and filtering out repeats of the current element h in its recursive call.

Haskell, 110 bytes

i!(x@(Left _):xs)=i:(i+1)!map(\y->if y==x then Right i else y)xs
i!(Right x:xs)=x:i!xs
_!_=[]
f x=1!map Left x

Try it online!

Lesson of today: Either is useful.

JavaScript (ES12), 28 bytes

a=>a.map(k=v=>a[-v]||=k=-~k)

Attempt This Online!

Commented

a =>        // a[] = input array, re-used to store the new labels
            //       using negative keys
a.map(k =   // k = counter, initially zero'ish
v =>        // for each value v in a[]:
  a[-v] ||= //   use a[-v] if it's already defined,
    k = -~k //   otherwise increment k and set a[-v] to this value
)           // end of map()

MATL, 3 bytes

7#u

Try it online! Or verify test cases 1, 2, 3, 4.

The code inputs a numerical vector, and print the output with a number on each line. The empty input produces the correct output but exits with an error (allowed by default).

How it works

     % Implicit input: numerical vector
#7u  % Call 'unique' with its third output, and with 'stable' input flag (default)
     % Implicit display

05AB1E, 4 bytes

Ùsk>

Try it online!

Maple, 53 bytes

s->subs((v:=ListTools:-MakeUnique(s))=~{$nops(v)},s);

The unique entries in order (v) are elementwise equated to 1,2,3,..(number in v), and used as substitution rules in s. ListTools:-MakeUnique is frustratingly verbose, but still shorter than anything I can think of that processes the list one entry as a time, such as

proc(s)q:=1;[seq(if(assigned(w[i]),w[i],(w[i]:=q++)),i=s)]end; (64 bytes)

Google Sheets, 37 bytes

=index(ifna(match(A:A,unique(A:A),)))

...not the typical use of the index(match()) pattern, using index() as array enabler only.

screenshot

Charcoal, 13 bytes

I⊕Eθ⌕Φθ⁼μ⌕θλι

Try it online! Link is to verbose version of code. Explanation:

   θ            Input array
  E             Map over values
            ι   Current value
    ⌕           Find index in
      θ         Input array
     Φ          Filtered where
        μ       Inner index
       ⁼        Equals
         ⌕      First index of
           λ    Inner value in
          θ     Input array
 ⊕              Convert to 1-indexing
I               Cast to string
                Implicitly print

APL(NARS), 27 chars

{⍬≡w←⍵:⍬⋄↑+/k×⍳≢k←{w=⍵}¨∪⍵}

input one array, ouput one array. Make one array of binary array where are each element, multiply for according iota array of right lengh and sum. Because the output was right enclosed, get the first ↑.

Test:

  f←{⍬≡w←⍵:⍬⋄↑+/k×⍳≢k←{w=⍵}¨∪⍵}
  f ⍬
┌0─┐
│ 0│
└~─┘
  f ,9
┌1─┐
│ 1│
└~─┘
 f 2 3 2 2 4 5 4 4 2
┌9─────────────────┐
│ 1 2 1 1 3 4 3 3 1│
└~─────────────────┘
  f 3 4 2 1 1 1 1 1 1 
┌9─────────────────┐
│ 1 2 3 4 4 4 4 4 4│
└~─────────────────┘

Ruby, 31 bytes

->l{l.map{|x|1+(l|l).index(x)}}

Try it online!

Vyxal 3, 4 bytes

u¨F›

Vyxal It Online!

u¨F›­⁡​‎‎⁡⁠⁢‏⁠‎⁡⁠⁣‏‏​⁡⁠⁡‌⁢​‎‎⁡⁠⁡‏‏​⁡⁠⁡‌⁣​‎‎⁡⁠⁤‏‏​⁡⁠⁡‌­
 ¨F   # ‎⁡find each
u     # ‎⁢unique element in the input
   ›  # ‎⁣increment the index
💎

Created with the help of Luminespire.

<script type="vyxal3">
u¨F›
</script>
<script>
    args=[["[]"],["[9]"],["[2,3,2,2,4,5,4,4,2]"],["[3,4,2,1,1,1,1,1,1,1]"]]
</script>
<script src="https://themoonisacheese.github.io/snippeterpreter/snippet.js" type="module"/>

TinyAPL, 2 bytes

=⑴

Explanation: classify with index origin 1.

Uiua, 3 bytes

+1⊛

Try it Online

Saw the challenge specs and immediately thought of classify in uiua lol.

Explained

+1⊛­⁡​‎‎⁡⁠⁣‏‏​⁡⁠⁡‌⁢​‎‎⁡⁠⁡‏⁠‎⁡⁠⁢‏‏​⁡⁠⁡‌­
  ⊛  # ‎⁡Assign a unique index to each unique item in the input
+1   # ‎⁢and add 1 to each index.
💎

Created with the help of Luminespire.