g | x | w | all
Bytes Lang Time Link
007Jelly250826T210404ZAdam
093JavaScript Node.js250826T095807ZFhuvi
063Julia240616T165718ZGlory2Uk
039C GCC230227T074611ZPeter
030Excel230226T202750ZJos Wool
027Factor + successor221022T192104Zchunes
026Ruby221022T164956ZJordan
032Excel MS365221022T153741ZMayukh B
058Icon190512T081938ZGalen Iv
029><>190416T121132ZEmigna
030PHP181020T045124ZTitus
068Powershell181021T095125Zmazzy
1614Perl 6160416T080148Znull
065R180503T000616ZJayCe
059Forth gforth180501T162501Zreffu
050JavaScript Node.js180501T154447ZMuhammad
057Java180501T152620ZKevin Cr
147Javascript180501T145359ZMattH
073VBA/VB6/VBScript nonExcel171017T154310ZLS_ᴅᴇᴠ
071Jq 1.5171017T162429Zjq170727
031Excel VBA170712T095418ZTaylor R
048Haskell150405T100416ZFors
017Perl120922T202706ZIlmari K
nan120923T142848ZDaniel
047Groovy111125T145112ZArmand
026Perl111125T131015ZToto
062Scala111124T233031ZGareth
053C111125T102136ZAlexande
035Ruby111125T095826ZHoward
036Excel Formula111125T043738ZDr. beli
048Haskell111125T004710ZJoey Ada

Jelly, 8 7 bytes

‘ḃ26ịØA

Attempt This Online!

I’m surprised this has not been posted yet.

‘ḃ26ịØA
‘       Add 1
 ḃ26    Convert to bijective base 26
    ịØA Index into the uppercase alphabet

Jelly almost has a built-in for this (), but unfortunately it uses the normal base, not the bijective base.

JavaScript (Node.js), 93 bytes

Terrible solution that took a lot of trial and error to make, and uses JS base-36 "letters" to directly produce the expected result in one shot...

For example, to produce AAA we need to transform 702 into 13330 so that it gives aaa in JS base-36.

Of course it will never beat the optimal JS solution, but i wonder if it still can be golfed further while keeping the base-36 idea.

n=>(n+((n/26|0)+1)*10+324*(n>25)+11664*(n>701)+((n-26)/676|0)*360).toString(36).toUpperCase()

Try it online!


((n/26|0)+1)*10 -> skips 10 values every 26 values, to handle the right-most character

324*(n>25) -> skips 324 values after 25, to directly go from Z to AA

11664*(n>701) -> skips 11664 values after 701, to directly go from ZZ to A0A (and not AAA because of the next line)

((n-26)/676|0)*360 -> manages the middle character to jump directly to A after each Z every time the left-most character changes

Julia, 63 bytes

f=(n,u=Char(mod(n,26)+65))->n<26 ? u : string(f(fld(n,26)-1),u)

Attempt This Online!

Recursion algorhythm taken from JayCe's and Kevin Cruijssen's answers [1],[2]

C (GCC), 39 bytes

f(i){i>25&&f(i/26-1);putchar(65+i%26);}

Try It Online!

Explanation:

f(i)
{
    // If i cannot be represented as a single letter
    i>25 &&
        // Print the next letter
        f(i/26-1);
    
    // Print the current letter
    putchar(65+i%26);
}

I thought using 0-based indexing was a little strange, so here's 1-based indexing in the same number of bytes:

f(i){i-->26&&f(i/26);putchar(65+i%26);}

Try It Online!

Excel, 30 bytes

=@TEXTSPLIT(ADDRESS(1,A1,4),1)

Factor + successor, 27 bytes

[ "A"[ successor ] repeat ]

Attempt This Online!

Yup, Factor has a vocab for this.

Ruby, 26 bytes

->n{(?A..).take(n+1).last}

Attempt This Online!

Excel (MS365), 32 bytes.

=TEXTBEFORE(ADDRESS(1,A1,4),"1")

enter image description here

Icon, 58 bytes

procedure f(n);return(n<0&"")|f(n/26-1)||char(65+n%26);end

Try it online!

><>, 29 bytes

!v:2d*%:"A"+@-2d*,1-:0(?!
$<o

Try it online!

PHP, 30 bytes

for($c=A;$argn--;)$c++;echo$c;

Run as pipe with `-nr' or try it online.

Powershell, 68 bytes

param($n)for(;$n-ge0;$n=($n-$r)/26-1){$s=[char](($r=$n%26)+65)+$s}$s

Alternative recursive version, 68 bytes:

filter g{if($_-ge0){(($_-($r=$_%26))/26-1|f)+[char]($r+65)}else{''}}

Test script:

$f = {

param($n)for(;$n-ge0;$n=($n-$r)/26-1){$s=[char](($r=$n%26)+65)+$s}$s

}

filter g{if($_-ge0){(($_-($r=$_%26))/26-1|f)+[char]($r+65)}else{''}}


@(
    ,(0 , "A")
    ,(1 , "B")
    ,(25 , "Z")
    ,(26 , "AA")
    ,(27 , "AB")
    ,(51 , "AZ")
    ,(52 , "BA")
    ,(676 , "ZA")
    ,(702 , "AAA")
    ,(16383 , "XFD")
) | % {
    $n, $expected = $_
    $result = &$f $n
    # $result = $n|g      # Alternative
    "$($result-eq$expected): $result"
}

Output:

True: A
True: B
True: Z
True: AA
True: AB
True: AZ
True: BA
True: ZA
True: AAA
True: XFD

Note: Powershell does not provide a div operator.

Perl 6, 16 14 bytes

{("A"..*)[$_]}

Works even beyond XFD. Thanks to infinite lists in Perl 6, this doesn't take forever (and a half) to execute.

Try it online!

R, 65 bytes

Recursive answer as are many previous answers.

function(n,u=LETTERS[n%%26+1])"if"(n<=25,u,paste0(g(n%/%26-1),u))

Try it online!

Forth (gforth), 59 bytes

: f dup 0< if drop else 26 /mod 1- recurse 65 + emit then ;

Try it online!

Explanation

dup 0<            \ duplicate the top of the stack and check if negative
if drop           \ if negative, drop the top of the stack
else              \ otherwise
   26 /mod        \ divide by 26 and get the quotient and remainder
   1- recurse     \ subtract one from quotient and recurse on result
   65 + emit      \ add 65 to remainder and output ascii char
then              \ exit if statement

JavaScript (Node.js), 50 bytes

f=_=>_<0?'':f(_/26-1)+String.fromCharCode(_%26+65)

Try it online!

Seeing that a lot of people started answering this I answered too.

Note :

This is basically a rip off of @kevinCruijssen's answer in Java shortened thanks to this being JS.

Java, 57 bytes (recursive)

String f(int n){return n<0?"":f(n/26-1)+(char)(n%26+65);}

Try it online.

Explanation:

String f(int n){        // Recursive method with integer parameter and String return-type
  return n<0?           //  If `n` is negative:
    ""                  //   Return an empty String
   :                    //  Else:
    f(n/26-1)           //   Recursive call with `n` integer-divided by 26, minus 1
    +(char)(n%26+65);}  //   And append `n%26+65` as character

Java 10, 62 bytes (iterative)

n->{var r="";for(;n>=0;n=n/26-1)r=(char)(n%26+65)+r;return r;}

Try it online.

Explanation:

n->{                      // Method with integer parameter and String return-type
  var r="";               //  Result-String, starting empty
  for(;n>=0;              //  Loop as long as `n` is not negative
      n=n/26-1)           //    After every iteration: divide `n` by 26, and subtract 1
    r=(char)(n%26+65)+r;  //   Prepend `n%26+65` as character to the result-String
  return r;}              //  Return the result-String

Javascript, 147 bytes

I had a similar problem. This is the golf of the solution. Excel columns are bijective base-26.

n=>{f=Math.floor;m=Math.max;x=m(0,f((n-24)/676));y=m(0,f(n/26-x*26));return String.fromCharCode(...[x,y,n+1-x*676-y*26].filter(d=>d).map(d=>d+64))}

Expanded, except using 1-indices:

function getColName(colNum){ // example: 16384 => "XFD"
    let mostSig = Math.max(0, Math.floor((colNum - 26 - 1)/26**2));
    let midSig = Math.max(0, Math.floor((colNum - mostSig*26**2 - 1)/26));
    let leastSig = colNum - mostSig*26**2 - midSig*26;

    return String.fromCharCode(...[mostSig,midSig,leastSig].filter(d=>d).map(d=>d+64));
}

VBA/VB6/VBScript (non-Excel), 73 bytes

Function s(i):While i:i=i-1:s=Chr(i Mod 26+65)&s:i=i\26:Wend:End Function

Calling s(16383) will return XFC.

Jq 1.5, 71 bytes

[range(1;4)as$l|[65+range(26)]|implode/""|combinations($l)]|map(add)[N]

Expects input in N. e.g.

def N:16383;

Expanded:

[                       # create array with
   range(1;4) as $l     #  for each length 1,2,3
 | [65+range(26)]       #   list of ordinal values A-Z
 | implode/""           #   converted to list of strings ["A", "B", ...]
 | combinations($l)     #   generate combinations of length $l
]
| map(add)[N]           # return specified element as a string

Try it online!

Excel VBA, 31 Bytes

Anonymous VBE immediate window function that takes input from cell [A1] and outputs to the VBE immediate window

?Replace([Address(1,A1,4)],1,"")

Haskell, 48

I really thought that I would be able beat the other Haskell entry, but alas...

f(-1)=""
f n=f(div n 26-1)++[toEnum$mod n 26+65]

I am certain it is possible to shave a couple of characters off this, but I haven't coded in Haskell for nearly a year, so I am quite rusty.

It's not exactly what you would call elegant.

Perl, 17 characters

say[A..XFD]->[<>]

The .. operator does the same thing as the magical auto-increment, but without the need for the temporary variable and loop. Unless strict subs is in scope, the barewords A and XFD are interpreted as strings.

(This answer was suggested by an anonymous user as an edit to an existing answer. I felt it deserves to be a separate answer, and have made it one. Since it wouldn't be fair for me to gain rep from it, I've made it Community Wiki.)

Python 45 51

f=lambda i:i>=0and f(i/26-1)+chr(65+i%26)or''

Groovy, 47

m={it<0?'':m(((int)it/26)-1)+('A'..'Z')[it%26]}

[0:'A',1:'B',25:'Z',
        26:'AA',
        27:'AB',
        51:'AZ',
        52:'BA',
        16383:'XFD'].collect {k,v-> assert v == m(k);m(k) }

Perl, 26 characters

$x='A';map$x++,1..<>;say$x

Scala, 62 characters

def f(i:Int):String=if(i<0)""else f((i/26)-1)+(i%26+65).toChar

Usage:

println(f(16383))

returns:

XFD

You can try this on Simply scala. Copy and paste the function and use f(some integer) to see the result.

C, 53 characters

It's like playing golf with a hammer...

char b[4],*p=b+3;f(i){i<0||(*--p=i%26+65,f(i/26-1));}

Normal version:

char b[4];
char *p = b+3;
void f(int i) {
    if (i >= 0) {
        --p;
        *p = i%26 + 65;
        f(i/26-1);
    }
}

And the usage is like that:

int main(int argc, char *argv[])
{
    f(atoi(argv[1]));
    printf("%s\n", p);
    return 0;
}

Ruby, 35 characters

e=->n{a=?A;n.times{a.next!};a}

Usage:

puts e[16383]   # XFD

Note: There is also a shorter version (30 characters) using recursion.

    e=->n{n<1??A:e[n-1].next}

But using this function you might have to increase the stack size for large numbers depending on your ruby interpreter.

Excel Formula:), 36 chars

=SUBSTITUTE(ADDRESS(1,A1,4),"1","")

Usage:

enter image description here

Sorry, couldn't resist ...

Haskell, 48

f=(!!)(sequence=<<(tail$iterate(['A'..'Z']:)[]))

Less golfed:

f n = (concatMap sequence $ tail $ iterate (['A'..'Z'] :) []) !! n

Explanation

Haskell's sequence combinator takes a list of actions and performs them, returning the result of each action in a list. For example:

sequence [getChar, getChar, getChar]

is equivalent to:

do
    a <- getChar
    b <- getChar
    c <- getChar
    return [a,b,c]

In Haskell, actions are treated like values, and are glued together using the >>= (bind) and return primitives. Any type can be an "action" if it implements these operators by having a Monad instance.

Incidentally, the list type has a monad instance. For example:

do
    a <- [1,2,3]
    b <- [4,5,6]
    return (a,b)

This equals [(1,4),(1,5),(1,6),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6)] . Notice how the list comprehension is strikingly similar:

[(a,b) | a <- [1,2,3], b <- [4,5,6]]

Because lists are a type of "action", we can use sequence with lists. The above can be expressed as:

sequence [[1,2,3],[4,5,6]]

Thus, sequence gives us combinations for free!

Thus, to build the list:

["A","B"..."Z","AA","AB"]

I just need to build lists to pass to sequence

[['A'..'Z'],['A'..'Z','A'..'Z'],...]

Then use concatMap to both apply sequence to the lists, and concatenate the resulting lists. Coincidentally, concatMap is the =<< function for lists, so the list monad lets me shave a few characters here, too.