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


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.