RFC 2550 là một đề xuất châm biếm (xuất bản vào ngày 1 tháng 4 năm 1999) cho một biểu diễn dấu thời gian ASCII hiệu quả trong không gian có thể hỗ trợ bất kỳ ngày nào (ngay cả những ngày trước khi bắt đầu vũ trụ và những ngày đã qua dự đoán của vũ trụ). Thuật toán tính toán dấu thời gian tuân thủ RFC 2550 như sau (lưu ý: tất cả các phạm vi bao gồm bắt đầu nhưng loại trừ kết thúc - 0 đến 10.000 có nghĩa là tất cả n
ở đâu 0 <= n < 10000
):
- Định dạng năm
- Năm 0 đến 10.000: số thập phân gồm 4 chữ số, được đệm trái bằng số không.
- Năm 10.000 đến 100.000: số thập phân gồm 5 chữ số, có tiền tố là ký tự A.
- Năm 100.000 đến 10 30 : số thập phân của năm, có tiền tố là chữ cái ASCII viết hoa có chỉ số trong bảng chữ cái tiếng Anh bằng số chữ số trong năm thập phân, trừ 5 (B cho 6 năm chữ số, C cho 7 -thần năm, v.v.).
- Năm 10 30 đến 10 56 : cùng định dạng từ 10.000 đến 10 30 , bắt đầu các chữ cái bằng A và thêm tiền tố vào một dấu mũ (
^
) vào chuỗi (vì vậy năm 10 30 được biểu thị^A1000000000000000000000000000000
và năm 10 31 được biểu thị bởi^B10000000000000000000000000000000
). - Năm 10 56 đến 10 732 : năm được tiền tố bởi hai dấu mũ và hai chữ cái viết hoa ASCII. Các chữ cái viết hoa tạo thành một số cơ sở-26 đại diện cho số chữ số trong năm, trừ 57.
- Năm 10 732 trở đi: định dạng tương tự cho 10 56 đến 10 732 được sử dụng, mở rộng nó bằng cách thêm một dấu mũ và chữ hoa khi cần thiết.
- Năm BCE (trước năm 0): tính chuỗi năm của giá trị tuyệt đối của năm. Sau đó, thay thế tất cả các chữ cái bằng phần bù cơ sở 26 của chúng (A <-> Z, B <-> Y, v.v.), thay thế tất cả các chữ số bằng phần bù cơ số 10 của chúng (0 <-> 9, 1 <-> 8, v.v.) và thay thế dấu mũ bằng dấu chấm than (
!
). Nếu chuỗi năm có 4 chữ số trở xuống (nghĩa là -1 đến -10.000), hãy thêm dấu gạch chéo (/
). Nếu chuỗi năm không được bắt đầu bằng dấu gạch chéo về phía trước hoặc dấu chấm than, hãy thêm dấu hoa thị (*
).
- Tháng, ngày, giờ, phút và giây : vì các giá trị này chỉ có tối đa 2 chữ số, chúng chỉ đơn giản được gắn vào bên phải của chuỗi năm, theo thứ tự giảm dần có ý nghĩa, được đệm trái bằng số 0 nếu cần để hình thành Chuỗi 2 chữ số.
- Độ chính xác bổ sung : nếu độ chính xác bổ sung (dưới dạng mili giây, micro giây, nano giây, v.v.) là cần thiết, các giá trị đó được đệm trái với số 0 đến 3 chữ số (vì mỗi giá trị là
1/1000
giá trị trước đó và do đó nhiều nhất là999
) và được thêm vào cuối dấu thời gian, theo thứ tự giảm dần có ý nghĩa.
Định dạng này có lợi ích của việc sắp xếp từ vựng tương đương với sắp xếp số của dấu thời gian tương ứng - nếu thời gian A đến trước thời gian B, thì dấu thời gian cho A sẽ xuất hiện trước dấu thời gian cho B khi áp dụng sắp xếp từ vựng.
Các thách thức
Đưa ra một danh sách dài các giá trị số tùy ý (tương ứng với các giá trị thời gian theo thứ tự quan trọng giảm dần, ví dụ [year, month, day, hour, minute, second, millisecond]
), xuất ra dấu thời gian RFC 2550 tương ứng.
Quy tắc
- Các giải pháp phải làm việc cho bất kỳ đầu vào nhất định. Những hạn chế duy nhất nên là thời gian và bộ nhớ có sẵn.
- Đầu vào có thể được lấy theo bất kỳ định dạng hợp lý, thuận tiện nào (chẳng hạn như danh sách các số, danh sách các chuỗi, một chuỗi được phân tách bằng một ký tự không có chữ số, v.v.).
- Đầu vào sẽ luôn chứa ít nhất một giá trị (năm). Các giá trị bổ sung luôn theo thứ tự có ý nghĩa giảm dần (ví dụ: đầu vào sẽ không bao giờ chứa giá trị ngày mà không có giá trị tháng hoặc giá trị thứ hai theo sau là giá trị tháng).
- Đầu vào sẽ luôn là thời gian hợp lệ (ví dụ: sẽ không có bất kỳ dấu thời gian nào cho ngày 30 tháng 2).
- Nội dung tính toán dấu thời gian RFC 2550 bị cấm.
Ví dụ
Các ví dụ này sử dụng đầu vào dưới dạng một chuỗi, với các giá trị riêng được phân tách bằng dấu chấm ( .
).
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
Thực hiện tham khảo
#!/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
phải*V3035567339896938984978971
vậy chứ?