RFC 2550 타임 스탬프 계산


26

RFC 2550 은 우주를 시작하기 전의 날짜와 우주의 예상 끝을 지나친 날짜를 지원할 수있는 공간 효율적인 ASCII 타임 스탬프의 ASCII 표현에 대한 풍자 제안 (1999 년 4 월 1 일에 게시)입니다. RFC 2550 호환 타임 스탬프를 계산하는 알고리즘은 다음과 같습니다 (참고 : 모든 범위는 시작을 포함하지만 끝을 제외합니다-0에서 10,000은 모두 n여기서 의미 0 <= n < 10000).

  • 연도 형식
    • Years 0-10,000 : 왼쪽에 0으로 채워지는 4 자리 10 진수입니다.
    • 10,000 ~ 100,000 년 : 문자 A가 앞에 붙는 5 자리 10 진수
    • 년 10-10 30 : 연도의 10 진수, 영어 알파벳의 색인이 10 년의 자릿수, 5를 뺀 5와 같은 대문자 ASCII 문자가 앞에 붙습니다 (7은 B, 6 자리는 C, 7은 C) -자리 연도 등).
    • 년 10 30 10 56 10 10,000 같은 형식 : 30 , A를 통해 문자부터 추가적으로 캐럿 (접두어 ^년 10되도록 (문자열) (30) 로 표시 ^A1000000000000000000000000000000하고, 연도 (10) (31)가 표시된다 에 의해 ^B10000000000000000000000000000000).
    • Years 10 56 to 10 732 : 연도는 두 개의 캐럿과 두 개의 ASCII 대문자로 시작합니다. 대문자는 연도의 자릿수에서 빼기 (57)를 나타내는 밑이 26 인 숫자를 형성합니다.
    • Year 10 732 이후 : 10 56 ~ 10 732 와 동일한 형식 이 사용되며 필요한 경우 추가 캐럿과 대문자를 추가하여 확장합니다.
    • BCE 연도 (0 년 이전) : 연도 절대 값의 연도 문자열을 계산합니다. 그런 다음 모든 문자를 밑이 26 인 보수 (A <-> Z, B <-> Y 등)로 바꾸고, 모든 숫자를 밑이 10 인 보수 (0 <-> 9, 1 <-> 8, 캐럿을 느낌표 ( !)로 바꿉니다 . 연도 문자열이 4 자리 이하 (예 : -1 ~ -10,000)이면 슬래시 ( /)를 추가하십시오 . 연도 문자열 앞에 슬래시 나 느낌표가 붙지 않으면 별표 ( *)를 추가하십시오 .
  • 월, 일, 시간, 분 및 초 :이 값은 최대 2 자리 숫자이므로 연도의 오른쪽에 중요도의 내림차순으로 추가되며, 필요한 경우 0으로 왼쪽 채워집니다. 2 자리 문자열.
  • 추가 정밀도 : 추가 정밀도 (밀리 초, 마이크로 초, 나노초 등의 형태)가 필요한 경우 해당 값은 0에서 3 자리로 채워집니다 (각 값은 1/1000이전 값이므로 최대 값입니다 999). 타임 스탬프의 끝에 중요도의 내림차순으로 추가됩니다.

이 형식은 어휘 정렬이 해당 타임 스탬프의 숫자 정렬과 동등하다는 이점이 있습니다. 시간 A가 시간 B보다 먼저 오면 어휘 정렬이 적용될 때 A의 타임 스탬프가 B의 타임 스탬프보다 먼저 나옵니다.

도전

임의의 긴 숫자 값 목록 (예 : 중요도의 내림차순으로 시간 값에 해당)이 주어진 [year, month, day, hour, minute, second, millisecond]경우 해당 RFC 2550 타임 스탬프를 출력합니다.

규칙

  • 주어진 입력에 대해 솔루션이 작동해야합니다. 시간과 사용 가능한 메모리 만 제한해야합니다.
  • 입력은 합리적이고 편리한 형식 (숫자 목록, 문자열 목록, 숫자가 아닌 단일 문자로 구분 된 문자열 등)으로 가져올 수 있습니다.
  • 입력은 항상 하나 이상의 값 (연도)을 포함합니다. 추가 값은 항상 중요도의 내림차순으로 표시됩니다 (예 : 입력에 월 값이없는 일 값 또는 월 값 뒤에 두 번째 값이 포함되지 않음).
  • 입력은 항상 유효한 시간입니다 (예 : 2 월 30 일의 타임 스탬프 없음).
  • RFC 2550 타임 스탬프를 계산하는 빌트인은 금지되어 있습니다.

이 예제는 입력을 단일 문자열로 사용하며 개별 값은 마침표 ( .)로 구분됩니다 .

1000.12.31.13.45.16.8 -> 10001231134516008
12.1.5.1 -> 0012010501
45941 -> A45941
8675309.11.16 -> C86753091116
47883552573911529811831375872990.1.1.2.3.5.8.13 -> ^B478835525739115298118313758729900101020305008013
4052107100422150625478207675901330514555829957419806023121389455865117429470888094459661251.2.3.5.7.11 -> ^^BI40521071004221506254782076759013305145558299574198060231213894558651174294708880944596612510203050711
-696443266.1.3.6.10.15.21.28 -> *V3035567330103061015021028
-5342 -> /4657
-4458159579886412234725624633605648497202 -> !Q5541840420113587765274375366394351502797

참조 구현

#!/usr/bin/env python

import string

# thanks to Leaky Nun for help with this
def base26(n):
    if n == 0:
        return ''
    digits = []
    while n:
        n -= 1
        n, digit = divmod(n, 26)
        digit += 1
        if digit < 0:
            n += 1
            digit -= 26
        digits.append(digit)
    return ''.join(string.ascii_uppercase[x-1] for x in digits[::-1])

year, *vals = input().split('.')

res = ""
negative = False

if year[0] == '-':
    negative = True
    year = year[1:]

if len(year) < 5:
    y = "{0:0>4}".format(year)
elif len(year) <= 30:
    y = "{0}{1}".format(string.ascii_uppercase[len(year)-5], year)
else:
    b26len = base26(len(year)-30)
    y = "{0}{1}{2}".format('^'*len(b26len), b26len, year)

if negative:
    y = y.translate(str.maketrans(string.ascii_uppercase+string.digits+'^', string.ascii_uppercase[::-1]+string.digits[::-1]+'!'))
    if len(year) == 4:
        y = '/' + y
    if y[0] not in ['/', '!']:
        y = '*' + y

res += y
for val in vals[:5]: #month, day, hour, minute, second
    res += '{0:0>2}'.format(val)

for val in vals[5:]: #fractional seconds
    res += '{0:0>3}'.format(val)

print(res)

반드시 -696443266.1.3.6.10.15.21.28있어야 *V3035567339896938984978971합니까?
Neil

11
@Neil 부정적인 달을 발명 할 때까지. 9 월
Mego

1
@TaylorScott 추가 정밀도 : 추가 정밀도 (밀리 초, 마이크로 초, 나노초 등의 형태)가 필요한 경우 해당 값은 0에서 3 자리로 채워집니다.
Mego

2
질문에 주어진 사양이 실제로 RFC2550과 일치하지 않는 것처럼 보입니다. 내가 알기로, 세 개의 캐럿을 지나면 피보나치 시리즈에서 파생 된 문자 (캐럿 4 개는 5 글자, 5 개 캐럿은 8 글자 등)에서 파생되기 때문에 문자 수가 캐럿보다 빠르게 증가해야합니다. RFC의 측면을 무시해야한다고 가정합니까?
James Holderness

1
@JamesHolderness 당신이 맞아요, 나는 사양을 엉망으로 만들었습니다. 그러나 무효화 된 답변이 이미 있으므로 수정하기에는 너무 늦습니다.
Mego

답변:


5

자바 스크립트 (ES6), 325 바이트

f=
s=>s.split`.`.map((n,i)=>i?`00${n}`.slice(i>5?-3:-2):n<'0'?g(n.slice(1),'!','*','/').replace(/\w/g,c=>c>'9'?(45-parseInt(c,36)).toString(36):9-c):g(n),g=(n,c='^',d='',e='',l=n.length)=>l<5?e+`000${n}`.slice(-4):l<31?d+(l+5).toString(36)+n:h(l-30,c)+n,h=(n,c)=>n?c+h(--n/26|0,c)+(n%26+10).toString(36):'').join``.toUpperCase()
;
<input oninput=o.value=f(this.value);><input id=o>

놀랍도록 길다.


손쉬운 테스트를 위해 Stack Snippet을 추가 하시겠습니까?
Mego

@ 메고 완료. 또한 일부 오타를 수정한다는 점에서 기었다 (복사하고 줄 바꿈이 저를 혼동하기 때문에 붙여 넣을 때 실수로 코드의 일부를 삭제 아차..)

3

비 펀지, 418 384 바이트

Befunge 프로그램의 규모가 어느 정도인지 사전에 말하기는 어렵고,이 작업을 시작했을 때 실제로 경쟁 할 가능성이 있다고 생각했습니다. 내가 틀렸다는 것이 밝혀졌다.

~:59*-!:00p:2*1\-10p:9*68*+20p>0>#~$_v
68*-:0\`30p\>>:"P"%\"P"/9+p30g#v_1+:~>
0\`v`\0:\p04<<:+1g04-$<_\49+2*v>0>+#1:#\4#g\#0`#2_130p040p5-::01-`\49+2*-:
v:$_\50p\$:130g:1+30p:!^!:-1\*<>g*"A"++\49+2*/50g1-:
_$1+7g00g40g!**:!>_40g:!v!:\g8<^00*55*g01%*2+94:p05
|#9/"P"\%"P":<:_,#!>#:<$_1-00g^v3$\_\#`\0:>#g+
>10g*20g+,1+:^v\&\0+2`4:_@#`<0+<
/*v*86%+55:p00<_$$>:#,_$1+~0^
^!>+\55+/00g1-:^

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


3

Perl 5 , 328322317301 + 1 ( -a) = 302 바이트

$_=shift@F;if(($l=y/-//c)<5){s/^/0 x(4-$l)/e}elsif($l<57){s/^/'^'x($l>30).chr 65+($l-5)%26/e}else{$l-=57;do{s/\^*\K/'^'.chr 65+$l%26/e}while$l=int$l/26;s/^\^\K\D-?\d/^A$&/}if(s/-//){s%^....$%/$&%;eval join'',reverse'!/',0..9,A..Z,"y/A-Z0-9^/";s%^[^!/]%*$&%}printf$_.'%02d'x(@F>5?5:@F).'%03d'x(@F-5),@F

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

언 골프

$_=shift@F; # Store the year in the default variable for easier regex

if(($l=y/-//c)<5){      # if the length of the year is less than 5
    s/^/0 x(4-$l)/e         # pad with leading zeros to 4 digits
}elsif($l<57){          # if the length is less than 57
    s/^/'^'x($l>30).chr 65+($l-5)%26/e  # put a carat at the front if there are more than 30 characters
                        # and map the length minus 5 to A-Z
}else{
    $l-=57;         # offset the length by 57
    do{         
        s/\^*\K/'^'.chr 65+$l%26/e # put a carat at the front and map the length to base 26 (A-Z)
    }while$l=int$l/26;  # until the length is down to 0
    s/^\^\K\D-?\d/^A$&/ # insert an extra '^A' to pad the result to at least 2 characters if there was only 1
}
if(s/-//){          # if the year is negative
    s%^....$%/$&%;          # put a '/' in front of a 4 digit year
    eval join'',reverse'!/',0..9,A..Z,"y/A-Z0-9^/"; # map A-Z,0-9, and ^ to Z-A,9-0, and ! respectively
    s%^[^!/]%*$&%           # add a * at the front if there are no other indicators
}
printf$_.           # output the year
'%02d'x(@F>5?5:@F).             # followed by the month, day, hour, and minutes, padded to 2 digits
'%03d'x(@F-5),@F                # followed by fractional seconds, padded to three digits

3

자바 8, 653 640 637 623 바이트

s->{String r="",q="ABCDEFGHIJKLMNOP",z=q+"QRSTUVWXYZ",y="0123456789",x;int i=0,f=0,t,u;for(String p:s){if(p.charAt(0)<46){p=p.substring(1);f=1;}t=p.length();if(i++<1){r+=(t<5?"000".substring(t-1):t<32?(char)(t+60):t<58?"^"+(char)(t+34):"");if(t>57){for(r+="^^",u=675;u<t-57;u*=26)r+="^";x="";for(String c:Long.toString(t-57,26).toUpperCase().split(""))x+=z.charAt((y+q).indexOf(c));r+=x;}r+=p;if(f>0){x=t<5?"/":t<32?"*":r.replace("^","!").replaceAll("[^!]","");for(char c:r.toCharArray())x+=c>93?"":"ZYXWVUTSRQPONMLKJIHGFEDCBA9876543210".charAt((z+y).indexOf(c));r=x;}}else r+=i>6?t<2?"00"+p:t<3?0+p:p:t<2?0+p:p;}return r;}

String-array로 입력 하고 return-type을로 입력하십시오 String.

꽤 긴 것으로 나타 났지만 (예상대로) 확실히 더 골프를 칠 수 있습니다. 나는 꽤 오랫동안 그것을 다루고 나서 그것이 기쁘다 ..

여기에서 시도하십시오.

설명:

  • for(String p:s){: 부품을 반복
    • if(p.charAt(0)<46){p=p.substring(1);f=1;}: 음수인지 확인하고 음수이면 빼기 부호를 제거하고 바이트를 줄이기 위해 플래그를 설정하십시오.
    • t=p.length();: 자릿수 확보
    • if(i++<1){: 첫 번째 숫자 인 경우 (연도) :
      • t<5?"000".substring(t-1): 0-100,000 (제외) 인 경우 : 필요한 경우 앞에 0을 추가하십시오.
      • t<32?(char)(t+60): 100,000-10 30 (독점) 인 경우 : 선행 편지 추가
      • t<58?"^"+(char)(t+34): 그것의 경우 10 (30) -10 (732) (전용) : 리터럴 추가 "^"+ 선도 편지
      • if(t>57)for(r+="^^",u=675;u<t-57;u*=26)r+="^";: 적절한 양의 리터럴 "^"+ x="";for(String c:Long.toString(t-57,26).toUpperCase().split(""))x+=z.charAt((y+q).indexOf(c));r+=x;: 선행 문자 추가 (base-26을 알파벳 변환으로)
      • r+=p;: 연도 자체를 결과 문자열에 추가
      • if(f>0){: 연도가 마이너스 인 경우 :
        • x=t<5?"/":t<32?"*":r.replace("^","!").replaceAll("[^!]","");: 임시 문자열을 만듭니다 x올바른로 /, *또는 하나 또는 여러 개의!
        • for(char c c:r.toCharArray())x+=c>93?"":"ZYXWVUTSRQPONMLKJIHGFEDCBA9876543210".charAt((z+y).indexOf(c));: 변환 (A↔Z, B↔Y, 0↔9, 1↔8 등)
        • r=x;: 그런 다음 결과를이 임시 문자열로 설정하십시오. x
    • else: 월, 일, 시간, 분, 초, 밀리 초, 마이크로 초, 나노초 이하인 경우 :
      • i>6?t<2?"00"+p:t<3?0+p:p: 밀리 초 이하인 경우 : 필요한 경우 앞에 0을 추가하십시오.
      • :t<2?0+p:p;: 기타 (월, 일, 시간, 분, 초) : 필요한 경우 단일 선행 0 추가
  • return r: 결과를 반환

Input may be taken in any reasonable, convenient format (such as a list of numerics, a list of strings, a string delimited by a single non-digit character, etc.).-숫자 목록으로 입력을 받아 비용이 많이 드는 분할 및 변환을 건너 뛸 수 있습니다.
Mego

1
@Mego 불행히도 기본 숫자 ( long64 비트가 가장 큰)는 Java에서 일부 입력에 비해 너무 작으므로 String보다 짧습니다 java.math.BigInteger. String그래도 -array로 변경 했으므로 점으로 분할 할 필요가 없으므로 바이트를 절약 할 수 있으므로 감사합니다.
Kevin Cruijssen

2

엑셀 VBA, 500 486 485 470 바이트

익명 VBE 즉시 창 기능

[A1], 월 [B1], 일 [C1], 시간 [D1], 분 [E1], 초, [F1]초정밀 배열 (선택 사항) 을 년 단위 로 가져 오는 익명 VBE 즉시 창 기능 [G1:Z1]은 RFC2550 타임 스탬프를 계산하고 VBE 즉시 창으로 출력합니다. 아래에 선언 된 도우미 함수를 사용합니다.

n=Left([A1],1)="-":y=Mid([A1],1-n):l=Len(y):o=IIf(l<5,Right("000"&y,4),IIf(l<31,"",String(Len(b(l-30)),94))&B(l-IIf(l<31,4,30))&y):For Each c In[B1:Z1]:j=j+1:p=p+IIf(c,Format(c,IIf(j>5,"000","00")),""):Next:If n Then For i=1To Len(o):c=Asc(Mid(o,i,1)):Mid$(o,i,1)=Chr(IIf(c<60,105,155)-c):Next:?IIf(l<5,"/",IIf(InStr(1,o,"="),"","*"))Replace(o,"=","!")p:Else?o;p

도우미 기능

입력 숫자를 가져 와서 밑수 26으로 해당 숫자를 반환하는 선언 된 도우미 함수 1->A26->Z

공용 모듈에 배치해야합니다.

Function b(n)
While n
n=n-1
d=n Mod 26+1
n=Int(n/26)
d=d+26*(d<0):n=n-(d<0)
b=Chr(64+d)+b
Wend
End Function

용법

일반 모듈에서 사용하거나 모듈을 vars로 실행하기 전에 지워야합니다. j , o그리고 p코드의 실행의 시작 부분에 기본, 초기화되지 않은 상태에있는 것으로 가정한다. 들어 jA는 어떤 Variant\Integer변수가이 기본 값이 0과를 위해 op있는, Variant\String변수,이 기본 값은 빈 문자열 ( "").

문자열 배열 인 입력 1:1은 ActiveSheet 에서 가져 오고 VBE 즉시 창으로 출력됩니다.

샘플 I / O

[A1:F1]=Split("4052107100422150625478207675901330514555829957419806023121389455865117429470888094459661251.2.3.5.7.11",".")
n=Left([A1],1)="-":y=Mid([A1],1-n):l=Len(y):o=IIf(l<5,Right("000"&y,4),IIf(l<31,"",String(Len(b(l-30)),94))&B(l-IIf(l<31,4,30))&y):For Each c In[B1:ZZ1]:j=j+1:p=p+IIf(c,Format(c,IIf(j>5,"000","00")),""):Next:If n Then For i=1To Len(o):c=Asc(Mid(o,i,1)):Mid$(o,i,1)=Chr(IIf(c<60,105,155)-c):Next:?IIf(l<5,"/",IIf(InStr(1,o,"="),"","*"))Replace(o,"=","!")p:Else?o;p
^^BI40521071004221506254782076759013305145558299574198060231213894558651174294708880944596612510203050711021028

Cells.Clear:j=0:o="":p="" '' clear the worksheet and vars
[A1:H1]=Array("-696443266","1","3","6","10","15","21","28")
n=Left([A1],1)="-":y=Mid([A1],1-n):l=Len(y):o=IIf(l<5,Right("000"&y,4),IIf(l<31,"",String(Len(b(l-30)),94))&B(l-IIf(l<31,4,30))&y):For Each c In[B1:ZZ1]:j=j+1:p=p+IIf(c,Format(c,IIf(j>5,"000","00")),""):Next:If n Then For i=1To Len(o):c=Asc(Mid(o,i,1)):Mid$(o,i,1)=Chr(IIf(c<60,105,155)-c):Next:?IIf(l<5,"/",IIf(InStr(1,o,"="),"","*"))Replace(o,"=","!")p:Else?o;p
*V3035567330103061015021028

Cells.Clear:j=0:o="":p="" '' clear the worksheet and vars
[A1]="45941"
n=Left([A1],1)="-":y=Mid([A1],1-n):l=Len(y):o=IIf(l<5,Right("000"&y,4),IIf(l<31,"",String(Len(b(l-30)),94))&B(l-IIf(l<31,4,30))&y):For Each c In[B1:ZZ1]:j=j+1:p=p+IIf(c,Format(c,IIf(j>5,"000","00")),""):Next:If n Then For i=1To Len(o):c=Asc(Mid(o,i,1)):Mid$(o,i,1)=Chr(IIf(c<60,105,155)-c):Next:?IIf(l<5,"/",IIf(InStr(1,o,"="),"","*"))Replace(o,"=","!")p:Else?o;p
A45941

Cells.Clear:j=0:o="":p="" '' clear the worksheet and vars
[A1:F1]=Split("4052107100422150625478207675901330514555829957419806023121389455865117429470888094459661251.2.3.5.7.11",".")
n=Left([A1],1)="-":y=Mid([A1],1-n):l=Len(y):o=IIf(l<5,Right("000"&y,4),IIf(l<31,"",String(Len(b(l-30)),94))&B(l-IIf(l<31,4,30))&y):For Each c In[B1:ZZ1]:j=j+1:p=p+IIf(c,Format(c,IIf(j>5,"000","00")),""):Next:If n Then For i=1To Len(o):c=Asc(Mid(o,i,1)):Mid$(o,i,1)=Chr(IIf(c<60,105,155)-c):Next:?IIf(l<5,"/",IIf(InStr(1,o,"="),"","*"))Replace(o,"=","!")p:Else?o;p
^^BI40521071004221506254782076759013305145558299574198060231213894558651174294708880944596612510203050711

Sub일상적인 버전

년부터 [A1], 월부터 [B1], 일부터 [C1], 시간까지 입력을받는 선언 된 서브 루틴[D1] , 분 [E1], 초, 초에서 [F1]선택적인 추가 정밀 배열[G1:Z1] 은 RFC2550 타임 스탬프를 계산하고 VBE 즉시 창으로 출력합니다.

Sub R(x)
a=x(0)
n=Left(a,1)="-"'<- that `"` is only there to make sure highlighting is correct
y=Mid(a,1-n)
l=Len(y)
o=IIf(l<5,Right("000"&y,4),IIf(l<31,"",String(Len(b(l-30)),94))&B(l-IIf(l<31,4,30))&y)
If n Then For i=1To Len(o):c=Asc(Mid(o,i,1)):Mid$(o,i,1)=Chr(IIf(c<60,105,155)-c):Next:o=IIf(l<5,"/",IIf(InStr(1,o,"="),"","*"))&Replace(o,"=","!")
For j=1To UBound(x)
o=o+IIf(x(j),Format(x(j),IIf(j>5,"000","00")),"")
Next
[A2]=o
End Sub
Function b(n)
While n
n=n-1
d=n Mod 26+1
n=Int(n/26)
d=d+26*(d<0):n=n-(d<0)
b=Chr(64+d)+b
Wend
End Function

용법

필요 [A1:ZZ1]에 따라 셀에 입력하거나 가장 왼쪽에서 가장 오른쪽으로 VBE 즉시 창에서 할당 하여 범위에 대한 입력을 수동으로 수행 할 수 있습니다.

참고로 Excel 자동 변환 숫자를 과학적 표기법으로 변환하기 때문에 셀의 길이를 12 자리 이상인 숫자는 셀을 텍스트 셀로 설정하거나 '셀 값의 시작 부분에 리터럴 을 추가하여

샘플 I / O

r Split("4052107100422150625478207675901330514555829957419806023121389455865117429470888094459661251.2.3.5.7.11",".")
?[A2]  '' <- print output to VBE console
^^BI40521071004221506254782076759013305145558299574198060231213894558651174294708880944596612510203050711 ''  <- Output

r Array("47883552573911529811831375872990","1","1","2","3","5","8","13")
?[A2]
^B478835525739115298118313758729900101020305008013

r Array("-696443266","1","3","6","10","15","21","28")
?[A2]
*V3035567330103061015021028

r Array("45941")
?[A2]
A45941

Ungolfed 및 설명

''  Returns RFC2550 timestamp corresponding to passed vars
Public Function RFC2550(ByVal pYear As String, ParamArray Extra() As Variant) As String

    ''  Declare Vars
    Dim Negative As Boolean, _
        leny As Long, _
        i As Long, _
        c As Byte, _
        s As Variant, _
        out As String

    ''  Check if year is negative and store the absolute value of the year
    Let Negative = Left(pYear, 1) = "-"
    Let pYear = Mid(pYear, 1 - Negative)

    ''  Take the length of the year
    Let leny = Len(pYear)
    If leny < 5 Then
        ''  If the length is less than 5, pad the year left to 4 characters 
        ''  using zeros
        Let out = Format("0000", pYear)
    Else
        ''  If the length of the year is greater than 30, then set out to be 
        ''  as string comprised of length-30 instances of `^`
        Let out = IIf(leny < 31, "", String(Len(Base26(leny - 30)), 94)) 
        ''  append the Base26 representation of the length of the year,
        ''  minus 30, if the length is greater than 30
        Let out = out & Base26(leny - IIf(leny < 31, 4, 30)) 
        ''  append the year to out
        Let out = out & pYear
    End If


    If Negative Then
        ''  iterate across out
        For i = 1 To Len(out)
            ''  store the char code for the current char
            Let c = Asc(Mid(out, i, 1))
            ''  swap letter/number with its inverse (0->9,A->Z)
            Mid$(out, i, 1) = Chr(IIf(c < 60, 105, 155) - c)
        Next i

        ''  replace `=` (the inverse of `^`) with `!`
        Let out = Replace(out, "=", "!")
        ''  Prepend either `/`, `*`, or nothing depending on length and 
        ''  start of out
        Let out = IIf(leny < 5, "/", IIf(InStr(1, out, "!"), "", "*")) & out
    End If

    Let i = 1
    For Each s In Extra
        ''  append all of the extra precision data - padding to 2 chars for 
        ''  the first 5 elements in the array (month, day, hour, minute and 
        ''  second) and to 3 chars for all following elements (milli, micro, 
        ''  nano, pico, femto, atto, zepto, yocto - seconds) with the char 0
        Let out = out & IIf(s, Format(s, IIf(i > 5, "000", "00")), "")
        Let i = i + 1
    Next

    ''  return out
    Let RFC2550 = out 

End Function


''  returns non-standard base26 version of input number 
''  1->A, 2->B,... 26->Z
Function Base26(ByVal n As Long) As String

    ''  declare vars
    Dim out As String, _
        digit As Integer

    ''  init out, digit
    Let out = ""
    Let digit = 0

    ''  iterate through n 
    While n
        ''  Decrement, hold the value of the digit
        Let n = n - 1
        Let digit = n Mod 26 + 1

        ''  divide by 26
        Let n = Int(n / 26)

        ''  correct for negative numbers
        If digit < 0 Then Let n = n + 1: Let digit = digit - 26

        ''  prepend char corresponding to the digit to out
        Let out = Chr(64 + digit) & out
    Wend

    ''  return out
    Let Base26 = out
End Function

2

젤리 , 165126 바이트

ḣ5ṫ€3
ØD,“^ /*!”,ØA
_µ‘l26Ċṗ@€ØAẎị@
Lµç30;€”^UZFµç4⁶;µ®L>30¤?µḟ®L>4¤?;®AṾ€¤µL=4”/x2£FiЀị€2£UF¤µ®S<0¤¡
4R¬+DU$UµḢ©Ç;Ñ;ṫ6ṫ€2$$F

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

라인 4는 라인 2와 3의 도움으로 연도 형식을 수행합니다. 첫 번째와 마지막 라인은 입력 요소를 적절한 길이로 채우지 않고 형식화 된 연도와 연결합니다.

  • _µ‘l26Ċṗ@€ØAẎị@기본 26 접두사를 찾습니다. ØA1과 ceil (log 26 (floor (log 10 (year))-n + 1)) 사이의 각 숫자에 대해 알파벳 ( ) 의 데카르트 힘을 취합니다 (n은 30 또는 4 임).이 목록에 색인을 가져옵니다. 바닥 포함 (로그 10 (년))-n (ị@ ).
  • ç30;€”^UZF 연도> = 10 30 (®L>30¤? )
  • ç4⁶;연도 <10 30 형식 . ( 편집 : ⁶;대신을 사용하여 바이트를 저장했습니다. ;@⁶)
  • 1RḊ <10 5 년 동안 빈 접두사 제공 (®L>4¤? ) . 자릿수 목록을 취한 다음 모든 요소 자체를 필터링합니다. 여기서 작동하지 않기 []때문에 이것을 사용하여 산출 하십시오. 이것은로 평가됩니다 []. 그리고 []여기에 작동하지 않습니다와 나는 빈리스트를 돌려 다른 2 바이트를 찾을 수 없습니다.
  • ;®AṾ€¤ 접두사에 연도를 추가하고 평평하게 만듭니다.
  • L=4”/x/do 문에서 연도의 길이가 4 인 경우 접두사 a®S<0¤¡ .
  • 2£FiЀ¹ị€2£UF¤의 보완을 얻어 A .. Z, 0 .. 9^ /*!연도 음수이면 ( ®S<0¤¡). ØD,“^ *!”,ØA목록 인 두 번째 링크를 나타냅니다 [['0' .. '9'], ['^',' ','/','*','!'], ['A' .. 'Z']]. ^C125...이 링크 와 같이 형식 이 지정된 연도 를 사용 하면 병합 된 버전에서 각 문자의 색인을 찾은 다음 해당 색인을 사용 하여 병합 된 버전의 새 문자열을 구성합니다. 하여 각 하위 목록이 반전되는 예 ['9' .. '0','!','*','/',' ','^','Z' .. 'A']: yielding) !X874.... /모든 것이 보완되기 전에 접두사가 붙기 때문에 자체적으로 매핑됩니다.
  • L=4a®S<0x@”/;/에서 마이너스 년의 시작 부분에 a 를 추가합니다 [-9999 .. -0001]. 내 추측은 이것이 단축 될 수 있다는 것입니다.이전 do 문 ( ¡)에 이것을 포함 시켰고 음수 년을 두 번 테스트 할 필요가 없기 때문에 7 바이트를 절약했습니다.

¡4 라인 에는 많은 용도 가 있으며 사용하여 압축 할 수 있다고 생각합니다? 대신 대신 하지만 어떻게 작동하는지 잘 모르겠습니다. 나는 ?일을하고 몇 바이트를 절약했습니다.

제임스 홀더 니스 (James Holderness)는 첫 번째 제출이 30 자리가 올바른 연도를 처리하지 못했다고 지적했다. 버그는 Zbase 26 접두사에 a가 필요한 해였습니다 . 26을 26으로 변환 할 때 [1,0]대신 대신 제공 하기 때문에 사용할 수없는 것으로 나타났습니다26 (duh) . 대신 나는 주문 쌍을 교체와 함께 사용했습니다. 나는 그것에 대한 원자가 없다고 생각하지만 거기에 있다면 몇 바이트를 절약 할 수 있습니다. 이 문제를 해결하면 ~ 40 바이트의 비용이 들었습니다. 확실히 나의 가장 긴 젤리 프로그램. 편집 : 직교 곱을 수행하는 더 짧은 방법을 찾았습니다. 어쨌든 마지막 문자가 두 개 이상의 문자로 접두사를 사용했는지 확실하지 않지만 새로운 방식으로 작동한다는 것을 알았습니다.

이 게시물을 여러 번 편집하여 죄송합니다. 계속해서 단축하는 방법을 계속 찾고 있습니다.

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