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
อย่างไร