คำนวณเวลาประทับ RFC 2550


26

RFC 2550เป็นข้อเสนอเชิงเสียดสี (เผยแพร่เมื่อวันที่ 1 เมษายน 1999) สำหรับการเป็นตัวแทน ASCII ที่มีประสิทธิภาพในอวกาศของการประทับเวลาที่สามารถรองรับวันใด ๆ (แม้กระทั่งก่อนที่จะถึงจุดเริ่มต้นของจักรวาล อัลกอริทึมสำหรับการคำนวณเวลาประทับที่สอดคล้องกับ RFC 2550 มีดังต่อไปนี้ (หมายเหตุ: ทุกช่วงรวมถึงจุดเริ่มต้น แต่ไม่รวมจุดสิ้นสุด - 0 ถึง 10,000 หมายถึงทุกnตำแหน่ง0 <= n < 10000):

  • รูปแบบปี
    • ปีที่ 0 ถึง 10,000: ตัวเลขทศนิยม 4 หลักพร้อมเบาะซ้ายด้วยเลขศูนย์
    • ปี 10,000 ถึง 100,000: ตัวเลขทศนิยม 5 หลักนำหน้าด้วยอักขระ A
    • ปีที่ 100,000 ถึง 10 30 : จำนวนทศนิยมสำหรับปีนำหน้าด้วยตัวอักษร ASCII ตัวพิมพ์ใหญ่ที่มีดัชนีในตัวอักษรภาษาอังกฤษเท่ากับจำนวนตัวเลขในปีทศนิยมลบ 5 (B สำหรับ 6 หลักปี, C สำหรับ 7 -digit ปี ฯลฯ )
    • ปีที่ 10 30ถึง 10 56 : รูปแบบเดียวกับ 10,000 ถึง 10 30เริ่มต้นตัวอักษรด้วย A และนำหน้าเครื่องหมายคาเร็ต ( ^) ไปยังสายอักขระเพิ่มเติม ( ) ไปยังสตริง (ดังนั้นปี 10 30จะถูกแทนด้วย^A1000000000000000000000000000000และปี 10 31แสดง โดย^B10000000000000000000000000000000)
    • ปีที่ 10 56ถึง 10 732 : ปีนำหน้าด้วยเครื่องหมายสองตัวและสองตัวอักษร ASCII สองตัว ตัวอักษรตัวพิมพ์ใหญ่เป็นตัวเลขฐาน 26 ซึ่งแสดงถึงจำนวนหลักในปีนั้นลบด้วย 57
    • ปีที่ 10 732เป็นต้นไป: ใช้รูปแบบเดียวกันสำหรับ 10 56ถึง 10 732ขยายออกโดยเพิ่มเครื่องหมายรูปหมวกและตัวพิมพ์ใหญ่เพิ่มเติมเมื่อจำเป็น
    • BCE ปี (ก่อนหน้าปี 0): คำนวณสตริงปีของค่าสัมบูรณ์ของปี จากนั้นแทนที่ตัวอักษรทั้งหมดด้วยส่วนเติมเต็ม -26 (A <-> Z, B <-> Y ฯลฯ ) แทนที่ตัวเลขทั้งหมดด้วยส่วนเติมเต็มฐาน 10 (0 <-> 9, 1 <-> 8, ฯลฯ ) และแทนที่คาเร็ตด้วยเครื่องหมายอัศเจรีย์ ( !) หากสตริงปีคือ 4 หลักหรือน้อยกว่า (เช่น -1 ถึง -10,000) ให้ใส่เครื่องหมายทับหน้า ( /) หากสตริงปีไม่ได้ขึ้นต้นด้วยเครื่องหมายทับซ้ายหรือเครื่องหมายอัศเจรีย์ให้ใส่เครื่องหมายดอกจัน ( *)
  • เดือน, วัน, ชั่วโมง, นาทีและวินาที : เนื่องจากค่าเหล่านี้เป็นเพียงตัวเลข 2 หลักเท่านั้นพวกมันจะถูกผนวกเข้าทางด้านขวาของสตริงปีเพื่อลดลำดับความสำคัญโดยมีเบาะซ้ายเป็นศูนย์ถ้าจำเป็นต้องสร้าง สตริง 2 หลัก
  • ความแม่นยำเพิ่มเติม : หากต้องการความแม่นยำเพิ่มเติม (ในรูปของมิลลิวินาทีไมโครวินาทีนาโนวินาที ฯลฯ ) จำเป็นต้องใช้ค่าเหล่านั้นจะถูกเสริมด้วยซ้ายเป็นศูนย์ด้วยตัวเลข 3 หลัก (เพราะแต่ละค่าเป็น1/1000ค่าก่อนหน้านี้และเป็นอย่างมาก999) และผนวกเข้ากับจุดสิ้นสุดของการประทับเวลาเพื่อลดลำดับความสำคัญลง

รูปแบบนี้มีประโยชน์ในการจัดเรียงคำศัพท์เทียบเท่ากับการเรียงลำดับตัวเลขของการประทับเวลาที่สอดคล้องกัน - ถ้าเวลา A มาก่อนเวลา B จากนั้นการประทับเวลาสำหรับ A จะมาก่อนการประทับเวลาสำหรับ B เมื่อใช้การเรียงลำดับศัพท์

ความท้าทาย

รับรายการค่าตัวเลขแบบยาวโดยพลการ (สอดคล้องกับค่าเวลาในการลดลำดับความสำคัญเช่น[year, month, day, hour, minute, second, millisecond]) ส่งออกการประทับเวลา RFC 2550 ที่สอดคล้องกัน

กฎระเบียบ

  • วิธีแก้ปัญหาจะต้องใช้กับอินพุตที่กำหนด ข้อ จำกัด เท่านั้นควรเป็นเวลาและหน่วยความจำที่มีอยู่
  • อินพุตอาจถูกนำมาใช้ในรูปแบบที่สมเหตุสมผลและสะดวก (เช่นรายการตัวเลขรายการสตริงสตริงที่คั่นด้วยอักขระที่ไม่ใช่ตัวเลขหลักเดียวเป็นต้น)
  • ข้อมูลที่ป้อนจะมีอย่างน้อยหนึ่งค่า (ปี) ค่าเพิ่มเติมอยู่ในลำดับที่มีนัยสำคัญลดลงเสมอ (เช่นอินพุทจะไม่มีค่าวันที่ไม่มีค่าเดือนหรือค่าที่สองตามด้วยค่าเดือน)
  • ข้อมูลที่ป้อนจะเป็นเวลาที่ถูกต้องเสมอ (เช่นจะไม่มีการประทับเวลาใด ๆ ในวันที่ 30 กุมภาพันธ์)
  • Builtins ซึ่งคำนวณเวลา 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 จนกว่าเราจะประดิษฐ์เดือนเชิงลบ Negember
Mego

1
@TaylorScott ความแม่นยำเพิ่มเติม : หากต้องการความแม่นยำเพิ่มเติม (ในรูปแบบของมิลลิวินาทีไมโครวินาทีนาโนวินาที ฯลฯ ) จำเป็นต้องใช้ค่าเหล่านั้นจะถูกเติมด้วยเลขศูนย์เป็น 3 หลัก
Mego

2
ฉันดูเหมือนว่าข้อมูลจำเพาะที่ระบุในคำถามไม่ตรงกับ RFC2550 ตามที่ฉันเข้าใจแล้วเมื่อคุณได้รับสามคาเร็ตจำนวนตัวอักษรควรจะเพิ่มขึ้นเร็วกว่าคาเร็ตเนื่องจากมันมาจากซีรีส์ Fibonacci (คาเร็ต 4 ตัวหมายถึงตัวอักษร 5 ตัวตัวอักษร 5 ตัวหมายถึง 8 ตัวอักษร ฯลฯ ) สมมติว่าเราควรเพิกเฉยต่อประเด็นเรื่อง RFC นั้น
James Holderness

1
@ JamesHolderness คุณพูดถูกฉันทำสเป็คผิด อย่างไรก็ตามมันสายเกินไปที่จะแก้ไขเพราะมีคำตอบอยู่แล้วที่จะทำให้ใช้การไม่ได้
Mego

คำตอบ:


5

JavaScript (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

@Mego เรียบร้อยแล้ว ยังแก้ไขความผิดพลาดบางอย่างที่พุ่งเข้าหา (ฉันลบรหัสบางส่วนเมื่อคัดลอกและวางเพราะการตัดบรรทัดทำให้ฉันสับสนอ๊ะ)
Neil

3

Befunge, 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 , 328 322 317 301 + 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

ลองออนไลน์!

Ungolfed

$_=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

Java 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 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 (พิเศษ): เพิ่มศูนย์นำถ้าจำเป็น
      • 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;: ตัวอักษรนำ (ฐาน -26 เป็นการแปลงตัวอักษร)
      • r+=p;: เพิ่มปีลงในสตริงผลลัพธ์
      • if(f>0){: ถ้าปีเป็นลบ:
        • x=t<5?"/":t<32?"*":r.replace("^","!").replaceAll("[^!]","");: สร้าง String ชั่วคราว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;: จากนั้นตั้งค่าผลลัพธ์เป็น String ชั่วคราว x
    • else: หากเป็นเดือน, วัน, ชั่วโมง, นาที, วินาที, มิลลิวินาที, ไมโครวินาที, นาโนวินาทีหรือเล็กกว่า:
      • i>6?t<2?"00"+p:t<3?0+p:p: ถ้าเป็นมิลลิวินาทีหรือเล็กกว่า: เพิ่มศูนย์นำหน้าถ้าจำเป็น
      • :t<2?0+p:p;: อื่น (เดือน, วัน, ชั่วโมง, นาที, วินาที): เพิ่มศูนย์นำเดี่ยวถ้าจำเป็น
  • 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
numerics @Mego เริ่มต้น แต่น่าเสียดายที่ ( long64 บิตที่ใหญ่ที่สุด) มีขนาดเล็กเกินไปใน Java สำหรับบางส่วนของปัจจัยการผลิตเพื่อให้สั้นกว่าString java.math.BigIntegerฉันเปลี่ยนมันเป็นString-array แต่ฉันไม่จำเป็นต้องทำทีละจุดซึ่งบันทึกไว้จำนวนไบต์ดังนั้นขอบคุณ
Kevin Cruijssen

2

Excel VBA, 500 486 485 470 ไบต์

ไม่ระบุชื่อ VBE ฟังก์ชั่นหน้าต่างทันที

ฟังก์ชันหน้าต่างแบบไม่ระบุชื่อ VBE แบบทันทีที่รับอินพุตเป็นปีจาก[A1]เดือนจาก[B1]วัน[C1]ชั่วโมงชั่วโมง[D1]นาทีจาก[E1]วินาที[F1]และอาร์เรย์พิเศษที่มีความแม่นยำเพิ่มเติมจาก[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->Aและ26->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จะถือว่าเป็นค่าเริ่มต้นของพวกเขารัฐเตรียมที่จุดเริ่มต้นของการดำเนินการของรหัส สำหรับjซึ่งเป็นVariant\Integerตัวแปรค่าดีฟอลต์นี้คือ0และสำหรับoและpซึ่งเป็น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 ให้เป็นสัญกรณ์วิทยาศาสตร์ตัวเลขใด ๆ ที่มีความยาวฐาน 10 หรือเท่ากับ 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

เยลลี่ , 165 126 ไบต์

ḣ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 ใช้พลังงานคาร์ทีเซียนของตัวอักษร ( ØA) สำหรับแต่ละหมายเลขระหว่าง 1 ถึงเพดาน (บันทึก26 (ชั้น (บันทึก10 (ปี)) - 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คำนำหน้า/ถ้าความยาวของปีคือ 4 ®S<0¤¡ในงบทำของ
  • 2£FiЀ¹ị€2£UF¤ใช้เวลาในการเติมเต็มของA .. Z, 0 .. 9และ^ /*!ถ้าปีเป็นลบ ( ®S<0¤¡) หมายถึงการเชื่อมโยงที่สองซึ่งเป็นรายการØD,“^ *!”,ØA [['0' .. '9'], ['^',' ','/','*','!'], ['A' .. 'Z']]ด้วยการจัดรูปแบบปีเช่น^C125...ลิงค์นี้จะค้นหาดัชนีของตัวละครแต่ละตัวในรุ่นแบนแล้วใช้ดัชนีผู้สร้างสตริงใหม่จากรุ่นของบี้ที่แต่ละรายการย่อยเป็นสิ่งที่ตรงกันข้ามคือยอม['9' .. '0','!','*','/',' ','^','Z' .. 'A'] แผนที่ไปยังตัวเองเพราะมันจะนำหน้าก่อนที่ทุกอย่างจะได้รับการเสริม!X874.../
  • L=4a®S<0x@”/;เพิ่มไปยังจุดเริ่มต้นของปีที่ผ่านมาติดลบใน/ [-9999 .. -0001]ฉันเดาว่านี่จะสั้นลงได้ ฉันลงเอยด้วยการรวมสิ่งนี้ไว้ในคำสั่ง do ก่อนหน้า ( ¡) และบันทึกไว้ 7 ไบต์เพราะจากนั้นฉันไม่จำเป็นต้องทดสอบปีที่เป็นลบสองครั้ง

มีประโยชน์หลายอย่าง¡ในบรรทัดที่ 4 และฉันคิดว่าพวกเขาสามารถบีบอัดได้โดยใช้?แทน แต่ฉันไม่แน่ใจว่าจะนำไปใช้ได้อย่างไร ฉัน?ต้องทำงานและบันทึกไว้สองสามไบต์

James Holderness ชี้ให้เห็นว่าการส่งครั้งแรกของฉันไม่ได้จัดการกับปีที่ถูกต้อง 30 หลัก มันกลับกลายเป็นข้อผิดพลาดสำหรับปีใด ๆ ที่จำเป็นต้องมีZในคำนำหน้า 26 ฐาน ปรากฎว่าฉันไม่สามารถใช้เพราะเมื่อคุณแปลง 26 เป็นฐาน 26 มันจะให้คุณ[1,0]แทน26(duh) ฉันใช้คำสั่งซื้อแทนการเปลี่ยนแทน ฉันไม่คิดว่าจะมีอะตอมสำหรับสิ่งนั้น แต่ถ้ามีฉันสามารถบันทึกไม่กี่ไบต์ การแก้ไขนี้ทำให้ฉันมีค่าใช้จ่ายประมาณ 40 ไบต์ แน่นอนที่สุดโปรแกรม Jelly ที่ยาวนานที่สุดของฉัน แก้ไข : พบวิธีที่สั้นกว่าในการทำผลิตภัณฑ์คาร์ทีเซียน ฉันรู้ว่าฉันไม่แน่ใจว่าตัวอักษรตัวสุดท้ายทำงานกับคำนำหน้าด้วยตัวอักษรมากกว่าสองตัวอยู่แล้ว แต่วิธีการใหม่ใช้งานได้

ขออภัยหลายครั้งที่ฉันแก้ไขโพสต์นี้ฉันเพิ่งค้นพบวิธีการทำให้สั้นลง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.