인덱스에서 엑셀 열 이름 생성


21

이것은 실제 문제에서 비롯된 것입니다. 물론 우리는 그것을 해결했지만 너무 길고 로터리 솔루션이라는 것을 더 잘할 수 있다고 생각합니다. 그러나 내 동료 중 누구도 그것을 간결하게 작성하는 방법을 생각할 수 없습니다. 따라서 코드 골프로 표시합니다.

Excel에서 열 머리글을 표시하는 것과 같은 방식으로 음이 아닌 정수를 문자열로 변환하는 것이 목표입니다. 그러므로:

0 -> A
1 -> B
...
25 -> Z
26 -> AA
27 -> AB
...
51 -> AZ
52 -> BA
...
16,383 -> XFD

적어도 16,383까지 작동 해야하지만 그 이상도 허용됩니다 (보너스 포인트는 없음). C # 솔루션을 기대하고 있지만 코드 골프의 전통에 따라 실제 프로그래밍 언어를 환영합니다.


16383이 XFD 여야합니까? 676과 702의 혜택은 무엇입니까?
피터 테일러

이것이 Excel에서 보여주는 것입니다. 웹에서 16384 개의 열이있는 것을 발견했습니다. 내일 우리의 (작동하는 것으로 알려진) 코드로 테스트 할 것입니다 (지금 살고있는 늦은 밤입니다).
Vilx-

또한 Excel 자체를 테스트 한 결과 676 = ZA 및 702 = AAA임을 알 수 있습니다.
Vilx-

1
내가 요구하는 이유는 간단한 26 코드를 작성하고 정확하게 맞는 결과를 얻었지만 676과 702에서 파산했기 때문입니다.
Peter Taylor

1
예. Base-26이 아닙니다. 그게 문제입니다. ;)
Vilx-

답변:



20

엑셀 공식 :), 36 자

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

용법:

여기에 이미지 설명을 입력하십시오

죄송합니다, 저항 할 수 없습니다 ...


아아! 나는 실제로 이것을 금지하는 것을 생각했지만 게시물에서 언급하는 것을 잊었습니다! : D 여전히 Excel 수식은 프로그래밍 언어가 아닙니다 (예, Excel VBA도 제한을 벗어남). : P
Vilx-

@ Vilx- 고마워 누군가가 더 짧은 해결책을 생각해 냈습니다. 나는 엑셀 공식을 사용하여 골프 대회에서 우승 한 유일한 사람인 역사를 입력하고 싶지 않습니다 :)
Dr. belisarius

나는 여전히 당신의 대답을 받아 들일 것입니다. > : D
Vilx-

3
<laughter type="evil">Muhahahahaha!</laughter>
Vilx-

4
다음으로 교체 "1"하여 2 바이트를 삭제할 수 있습니다.1
Taylor Scott

9

펄, 17 자

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

..운영자는 마법의 자동 증가와 같은 일을하지만, 임시 변수 및 루프에 대한 필요없이. 하지 않는 strict subs범위에의 barewords A와는 XFD문자열로 해석됩니다.

( 이 답변은 익명의 사용자 가 기존 답변을 수정 한 것으로 제안 되었습니다 . 별도의 답변이 필요하다고 생각하고 답변 을 받았습니다 . 답변받는 것이 공정하지 않기 때문에 저는 ' 커뮤니티 위키로 만들었습니다. )


지금까지 가장 짧은 대답이므로 더 짧은 해결책을 찾을 때까지 (수락 가능) (Personal으로 만 사용 가능) : P Ironic.
Vilx-

1
질문은 입력과 출력이 어떻게 수행되는지에 대해 모호하기 때문에 실제로 이것을 상당히 단축시킬 수 있습니다. 예를 들어 입력이 입력 $_되고 출력이 표현식의 값인 (A..XFD)[$_]경우 12 개의 문자 만으로도 문제 를 해결합니다 .
Ilmari Karonen

죄송합니다. 어떻게 실행해야합니까? perl 5.18에서는 -E에 대한 인수로 제공 될 때 아무것도 인쇄하지 않습니다.
Ed Avis

@EdAvis : 숫자를 입력하기를 기다리고 있습니다. 또는 번호를 파일에 넣고 할 수 perl -E 'say[A..XFD]->[<>]' < number.txt있습니다. 또는 그것을 지원하는 쉘에서 명령 줄에 입력하십시오 perl -E 'say[A..XFD]->[<>]' <<< 123.
Ilmari Karonen

1
나는이가 최적화 될 수 있다고 생각say+(A..XFD)[<>]
콘라드 보로프스키

6

C, 53 자

망치로 골프를 치는 것과 같습니다.

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

일반 버전 :

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

사용법은 다음과 같습니다.

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

5

하스켈, 48

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

덜 골프 :

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

설명

Haskell의 결합기 sequence는 작업 목록을 가져 와서 수행하여 각 작업의 결과를 목록으로 반환합니다. 예를 들면 다음과 같습니다.

sequence [getChar, getChar, getChar]

다음과 같습니다.

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

Haskell에서 액션은 값처럼 취급되며 >>=(바인드)와 return프리미티브를 사용하여 서로 붙어 있습니다 . Monad 인스턴스 를 사용하여 이러한 연산자를 구현하는 경우 모든 유형은 "조치"가 될 수 있습니다 .

또한 목록 유형에는 모나드 인스턴스가 있습니다. 예를 들면 다음과 같습니다.

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

이것은 같습니다 [(1,4),(1,5),(1,6),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6)]. 목록 이해가 놀랍도록 비슷한 점에 주목하십시오.

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

리스트는 일종의 "조치"이기 때문에리스트 sequence와 함께 사용할 수 있습니다 . 위와 같이 표현할 수 있습니다 :

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

따라서, sequence우리에게 무료로 조합을 제공합니다!

따라서 목록을 작성하려면 다음을 수행하십시오.

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

전달할 목록을 작성하면됩니다. sequence

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

그런 다음 목록 concatMap에 모두 적용 sequence하고 결과 목록을 연결하는 데 사용하십시오. 우연히도 목록에 concatMap대한 =<<기능이므로 목록 모나드를 사용하면 여기에서 몇 문자를 면도 할 수 있습니다.



3

루비, 35 자

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

용법:

puts e[16383]   # XFD

참고 : 재귀를 사용하는 더 짧은 버전 (30 자)도 있습니다.

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

그러나이 함수를 사용하면 루비 인터프리터에 따라 많은 수의 스택 크기를 늘려야 할 수 있습니다.


3

그루비, 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) }

3

파이썬 45 51

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

당신이 당겨 2 괄호를 제거 할 수 있습니다 +chr(65+i%26)내부를 테스트 i>=0당신에게 1 개 문자 : 절약,
놈들

또한 사용하여 오프 4 개 문자를 면도 할 수 f=lambda i:보다는def f(i):return
Strigoides

실제로 37 번 이상에서는 잘 작동하지 않습니다. 이 코드를 약간 업데이트해야했습니다.f = lambda i: i >= 0 and f(math.floor(i / 26 - 1)) + chr(int(round(65 + i % 26))) or ''
user007

2

스칼라, 62 자

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

용법:

println(f(16383))

보고:

XFD

Simply scala 에서 시도해 볼 수 있습니다 . 함수를 복사하여 붙여넣고 f(some integer)결과를 보는 데 사용 하십시오.


당신은 사건 ""+에 필요하지 않습니다 else.
피터 테일러

2

Excel VBA, 31 바이트

셀에서 입력 [A1]을 받고 VBE 즉시 창으로 출력하는 익명 VBE 즉시 창 기능

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


2

PHP, 30 바이트

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

`-nr '을 사용하여 파이프로 실행하거나 온라인으로 시도하십시오 .


나는 이것이 필요한 것을하지 않는다고 확신합니다. 후 Z갈 것 [보다는 AA.
Vilx-

@ Vilx- PHP를 잘 모른다는 증거로 사용합니다. 나는 TiO를 추가했다; 직접 참조하십시오.
Titus

이런 ... 네 말이 맞아! 나는 PHP를 상당히 잘 알고 있지만 이상한 것들로 가득 차서 모든 것을 알 수는 없습니다. 이 특별한 이상은 나를 버렸다. 여기, 공감대와 사과드립니다!
Vilx-

1

VBA / VB6 / VBScript (비 엑셀), 73 바이트

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

전화 s(16383)가 돌아옵니다 XFC.


PPCG에 오신 것을 환영합니다! VB에 익숙하지 않은 사용자에 대한 설명을 추가 할 수 있습니까?
AdmBorkBork

1
@AdmBorkBork 이전 답변에 추가 할 것이 많지 않고 언어 바인딩 만!
LS_ᴅᴇᴠ

이 모든 경우에 실패 표시 i>675 -가 s(676)=A@@(예상 YZ) s(677)=A@A(예정 ZA)
테일러 스콧

1
@TaylorScott 당신이 맞아요. 작업 중 ...
LS_ᴅᴇᴠ

1
@TaylorScott Corrected, +6 bytes ... 감사합니다.
LS_ᴅᴇᴠ

1

자바 스크립트, 147 바이트

나는 비슷한 문제가 있었다. 이것이 솔루션의 골프입니다. 엑셀 열은 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))}

1 개의 지표를 사용하지 않고 확장 :

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));
}

1
TIO 링크를 추가 할 수 있습니다. 그 외에는 첫 번째 좋은 대답입니다. PPCG에 오신 것을 환영합니다.
Muhammad Salman

7 년 전 질문에 대답하는 것도 좋은 생각이 아닙니다.
Muhammad Salman

좋아, nvm 이것은 여러 수준에서 잘못되었습니다. 내가 어떻게 이것을 보지 못했는지
Muhammad Salman

나는이 질문을하고 싶었지만 복제품이었다. 나는 확실히 당신은 @MuhammadSalman에서 얻고 있지 않다 무엇을
MattH

잠시 후 다시 연락 드리겠습니다. PPCG에 오신 것을 환영합니다. 좋은 대답입니다. Plz는 답변을 작성할 때 전체 프로그램 또는 기능을 제공해야합니다.
Muhammad Salman

1

Java, 57 바이트 (재귀)

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

온라인으로 사용해보십시오.

설명:

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 바이트 (반복)

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

온라인으로 사용해보십시오.

설명:

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

안녕. 죄송하지만 코드를 훔쳤습니다 : 여기 . :)
Muhammad Salman

@MuhammadSalman Hehe, 문제 없습니다. 나는 실제로 Scala 답변 에서 내 것을 얻었다 . ;)
Kevin Cruijssen

1

넷째 (gforth) , 59 바이트

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

온라인으로 사용해보십시오!

설명

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


1

파워 쉘, 68 바이트

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

대체 재귀 버전, 68 바이트 :

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

테스트 스크립트 :

$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"
}

산출:

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

참고 : Powershell은 div운영자를 제공하지 않습니다 .


0

하스켈, 48

나는 다른 하스켈 항목을 이길 수 있다고 생각했지만 아아 ...

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

나는이 문자에서 몇 가지 문자를 면도 할 수 있다고 확신하지만 Haskell에서 거의 1 년 동안 코딩하지 않았으므로 매우 녹슬 었습니다.

우아하다고 부르는 것이 아닙니다.


나쁘지 않다! :) 그러나 Ha-3 년이 지난 후에도 여전히 C # 솔루션은 없습니다. : D
Vilx-

하하. 그러나 C # 솔루션은 이와 동일한 방법으로 작성하는 것이 쉽지 않습니다. string f(int n){return n<0?"":f(n/26-1)+(char)(n%26+65);}57 자이므로 답변으로 게시하면 기분이 나빠질 것입니다.
Fors

0

Jq 1.5 , 71 바이트

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

의 입력이 필요 N합니다. 예 :

def N:16383;

넓히는:

[                       # 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

온라인으로 사용해보십시오!



당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.