RFC 2550 jest satyryczną propozycją (opublikowaną 1 kwietnia 1999 r.) Dotyczącą energooszczędnej reprezentacji ASCII znaczników czasu, które mogą obsługiwać dowolną datę (nawet te przed początkiem wszechświata i te, które minęły przewidywany koniec wszechświata). Algorytm obliczania znacznika czasu zgodnego z RFC 2550 jest następujący (uwaga: wszystkie zakresy obejmują początek, ale wykluczają koniec - od 0 do 10 000 oznacza wszystko n
gdzie 0 <= n < 10000
):
- Format roku
- Lata od 0 do 10 000: 4-cyfrowa liczba dziesiętna, uzupełniona lewymi zerami.
- Lata od 10 000 do 100 000: 5-cyfrowa liczba dziesiętna, poprzedzona znakiem A.
- Lata od 100 000 do 10 30 : liczba dziesiętna dla roku, poprzedzona wielką literą ASCII, której indeks w alfabecie angielskim jest równy liczbie cyfr w roku dziesiętnym, minus 5 (B dla 6 cyfr, C dla 7 - lata cyfrowe itp.).
- Lata 10 30 do 10 56 : ten sam format co 10 000 do 10 30 , rozpoczynając litery od A i dodatkowo poprzedzając znak daszka (
^
) ciągiem (więc rok 10 30 jest reprezentowany przez^A1000000000000000000000000000000
, a rok 10 31 jest reprezentowany przez^B10000000000000000000000000000000
). - Lata 10 56 do 10 732 : rok jest poprzedzony dwoma CARETS i dwa ASCII wielkimi literami. Wielkie litery tworzą liczbę podstawową 26 reprezentującą liczbę cyfr w roku, minus 57.
- Lata 10 732 i następne: stosuje się ten sam format dla 10 56 do 10 732 , rozszerzając go, dodając w razie potrzeby dodatkowy znak karetki i wielką literę.
- Lata pne (przed rokiem 0): obliczenie ciągu roku bezwzględnej wartości roku. Następnie zamień wszystkie litery na ich uzupełnienie podstawy-26 (A <-> Z, B <-> Y itd.), Zamień wszystkie cyfry na uzupełnienie podstawy-10 (0 <-> 9, 1 <-> 8, itp.) i zamień karetki wykrzyknikami (
!
). Jeśli ciąg roku ma 4 cyfry lub mniej (tj. Od -1 do -10 000), wstaw ukośnik (/
). Jeśli ciąg roku nie jest poprzedzony ukośnikiem lub wykrzyknikiem, wstaw gwiazdkę (*
).
- Miesiące, dni, godziny, minuty i sekundy : ponieważ te wartości są najwyżej 2 cyframi, są one po prostu dodawane po prawej stronie ciągu roku, w kolejności malejącej znaczenia, w razie potrzeby uzupełniane lewymi zerami 2-cyfrowe ciągi znaków.
- Dodatkowa precyzja : jeśli potrzebna jest dodatkowa precyzja (w postaci milisekund, mikrosekund, nanosekund itp.), Wartości te są dopełniane od zera do 3 cyfr (ponieważ każda wartość ma
1/1000
poprzednią wartość, a zatem najwyżej999
) i dołączane na końcu znacznika czasu, w malejącym porządku ważności.
Ten format ma tę zaletę, że sortowanie leksykalne jest równoważne sortowaniu numerycznemu odpowiedniego znacznika czasu - jeśli czas A nastąpi przed czasem B, to znacznik czasu A pojawi się przed znacznikiem czasu B, gdy zastosowane zostanie sortowanie leksykalne.
Wyzwanie
Biorąc pod uwagę dowolnie długą listę wartości liczbowych (odpowiadających wartościom czasu w malejącym porządku istotności, np. [year, month, day, hour, minute, second, millisecond]
), Wypisz odpowiedni znacznik czasu RFC 2550.
Zasady
- Rozwiązania muszą działać dla każdego danego wkładu. Jedynymi ograniczeniami powinien być czas i dostępna pamięć.
- Dane wejściowe mogą być podejmowane w dowolnym rozsądnym, wygodnym formacie (takim jak lista cyfr, lista ciągów, ciąg ograniczony pojedynczym znakiem innym niż cyfra itp.).
- Dane wejściowe zawsze będą zawierać co najmniej jedną wartość (rok). Dodatkowe wartości są zawsze w malejącym porządku ważności (np. Dane wejściowe nigdy nie będą zawierać wartości dziennej bez wartości miesiąca lub drugiej wartości, po której następuje wartość miesiąca).
- Dane wejściowe zawsze będą ważne (np. 30 lutego nie będzie żadnych znaczników czasu).
- Wbudowane obliczenia znaczników czasu RFC 2550 są zabronione.
Przykłady
W tych przykładach zastosowano dane wejściowe jako pojedynczy ciąg znaków, a poszczególne wartości oddzielono kropkami ( .
).
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
Realizacja referencyjna
#!/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
powinno być*V3035567339896938984978971
?