RFC 2550 ist ein satirischer Vorschlag (veröffentlicht am 1. April 1999) für eine platzsparende ASCII-Darstellung von Zeitstempeln, die jedes Datum unterstützen können (auch solche vor dem Beginn des Universums und solche nach dem prognostizierten Ende des Universums). Der Algorithmus zur Berechnung eines RFC 2550 konforme Zeitstempel folgt wie (Anmerkung: alle Bereiche umfassen den Start , aber ausschließen das Ende - 0 bis 10.000 Mittel alle n
wo 0 <= n < 10000
):
- Jahresformat
- Jahre 0 bis 10.000: eine 4-stellige Dezimalzahl, links mit Nullen aufgefüllt.
- Jahre 10.000 bis 100.000: eine 5-stellige Dezimalzahl mit vorangestelltem Buchstaben A.
- Jahre 100.000 bis 10 30 : Die Dezimalzahl für das Jahr, vorangestellt mit dem ASCII-Großbuchstaben, dessen Index im englischen Alphabet der Anzahl der Stellen im Dezimaljahr entspricht, minus 5 (B für 6-stellige Jahre, C für 7) Jahre usw.).
- Jahre 10 30 bis 10 56 : dasselbe Format wie 10.000 bis 10 30 , wobei die Buchstaben mit A beginnen und
^
der Zeichenfolge zusätzlich ein Caret ( ) vorangestellt wird (also das Jahr 10 30 durch^A1000000000000000000000000000000
und das Jahr 10 31 durch dargestellt wird) von^B10000000000000000000000000000000
). - Jahre 10 56 bis 10 732 : Dem Jahr werden zwei Carets und zwei ASCII-Großbuchstaben vorangestellt. Die Großbuchstaben bilden eine Zahl zur Basis 26, die die Anzahl der Stellen im Jahr minus 57 darstellt.
- Ab 10 732 Jahren: Es wird dasselbe Format für 10 56 bis 10 732 verwendet. Bei Bedarf werden ein zusätzliches Caret und ein Großbuchstabe hinzugefügt.
- BCE-Jahre (vor Jahr 0): Berechnet die Jahreszeichenfolge des absoluten Wertes des Jahres. Ersetzen Sie dann alle Buchstaben durch das Basiskomplement 26 (A <-> Z, B <-> Y usw.) und alle Ziffern durch das Basiskomplement 10 (0 <-> 9, 1 <-> 8). usw.) und ersetzen Sie Carets durch Ausrufezeichen (
!
). Wenn die Jahreszeichenfolge 4 Stellen oder weniger enthält (dh -1 bis -10.000), stellen Sie einen Schrägstrich (/
) voran . Wenn der Jahreszeichenfolge kein Schrägstrich oder Ausrufezeichen vorangestellt ist, stellen Sie ein Sternchen (*
) voran .
- Monate, Tage, Stunden, Minuten und Sekunden : Da es sich bei diesen Werten immer nur um höchstens 2 Ziffern handelt, werden sie einfach in absteigender Reihenfolge der Signifikanz rechts von der Jahreszeichenfolge angehängt und bei Bedarf mit Nullen links aufgefüllt 2-stellige Zeichenfolge.
- Zusätzliche Genauigkeit : Wenn eine zusätzliche Genauigkeit (in Form von Millisekunden, Mikrosekunden, Nanosekunden usw.) erforderlich ist, werden diese Werte mit Nullen bis zu drei Stellen links aufgefüllt (da jeder Wert
1/1000
den vorherigen Wert hat und somit höchstens999
). und in absteigender Reihenfolge der Signifikanz an das Ende des Zeitstempels angehängt.
Dieses Format hat den Vorteil, dass die lexikalische Sortierung der numerischen Sortierung des entsprechenden Zeitstempels entspricht. Wenn Zeit A vor Zeit B liegt, liegt der Zeitstempel für A vor dem Zeitstempel für B, wenn die lexikalische Sortierung angewendet wird.
Die Herausforderung
Geben Sie bei einer beliebig langen Liste numerischer Werte (die beispielsweise Zeitwerten in absteigender Reihenfolge der Signifikanz [year, month, day, hour, minute, second, millisecond]
entsprechen) den entsprechenden RFC 2550-Zeitstempel aus.
Regeln
- Lösungen müssen für jede Eingabe funktionieren. Die einzigen Einschränkungen sollten die Zeit und der verfügbare Speicher sein.
- Die Eingabe kann in jedem vernünftigen, praktischen Format erfolgen (z. B. eine Liste von Ziffern, eine Liste von Zeichenfolgen, eine Zeichenfolge, die durch ein einzelnes nichtstelliges Zeichen begrenzt ist, usw.).
- Die Eingabe enthält immer mindestens einen Wert (das Jahr). Zusätzliche Werte sind immer in absteigender Reihenfolge der Signifikanz (z. B. enthält die Eingabe niemals einen Tageswert ohne einen Monatswert oder einen zweiten Wert, gefolgt von einem Monatswert).
- Die Eingabe wird immer eine gültige Zeit sein (z. B. werden für den 30. Februar keine Zeitstempel angezeigt).
- Builtins, die RFC 2550-Zeitstempel berechnen, sind verboten.
Beispiele
In diesen Beispielen wird die Eingabe als einzelne Zeichenfolge verwendet, wobei die einzelnen Werte durch Punkte ( .
) getrennt sind.
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
Referenzimplementierung
#!/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
doch sein*V3035567339896938984978971
?