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
?Odpowiedzi:
JavaScript (ES6), 325 bajtów
Szokująco długo.
źródło
Befunge,
418384 bajtówTrudno z góry powiedzieć, jak duży może być program Befunge, a kiedy zacząłem nad tym pracować, pomyślałem, że może mieć szansę na konkurowanie. Okazuje się, że się myliłem.
Wypróbuj online!
źródło
Perl 5 ,
328 322 317301 + 1 (-a
) = 302 bajtówWypróbuj online!
Nie golfił
źródło
Java 8,
653640637623 bajtówWpisz jako
String
-array i return-type asString
.Okazało się, że jest dość długi (zgodnie z oczekiwaniami), ale zdecydowanie można go jeszcze zagrać w golfa. Cieszę się, że to działa po dłuższej zabawie…
Wypróbuj tutaj.
Wyjaśnienie:
for(String p:s){
: Pętla nad częściamiif(p.charAt(0)<46){p=p.substring(1);f=1;}
: Określ, czy jest ujemny, a jeśli tak, usuń znak minus i ustaw flagę, aby zmniejszyć liczbę bajtówt=p.length();
: Uzyskaj liczbę cyfrif(i++<1){
: Jeśli jest to pierwsza liczba (rok):t<5?"000".substring(t-1)
: Jeśli jest to 0-100 000 (wyłącznie): w razie potrzeby dodaj wiodące zerat<32?(char)(t+60)
: Jeśli jest 100 000–10 30 (wyłącznie): dodaj literę wiodącąt<58?"^"+(char)(t+34)
: Jeśli jest to 10 30 -10 732 (wyłącznie): Dodaj dosłowny"^"
+ wiodącą nasif(t>57)for(r+="^^",u=675;u<t-57;u*=26)r+="^";
: Dodaj odpowiednią ilość literału"^"
+x="";for(String c:Long.toString(t-57,26).toUpperCase().split(""))x+=z.charAt((y+q).indexOf(c));r+=x;
: wiodące litery (konwersja od 26 do alfabetu)r+=p;
: Dodaj sam rok do ciągu wynikowegoif(f>0){
: Jeśli rok był ujemny:x=t<5?"/":t<32?"*":r.replace("^","!").replaceAll("[^!]","");
: Utwórz ciąg tymczasowyx
z poprawnym/
,*
jednym lub wieloma!
for(char c c:r.toCharArray())x+=c>93?"":"ZYXWVUTSRQPONMLKJIHGFEDCBA9876543210".charAt((z+y).indexOf(c));
: Wykonaj konwersję (A*Z, B*Y, 0 SAR 9, 1 SAR 8 itd.)r=x;
: A następnie ustaw wynik na ten temp Stringx
else
: Jeśli jest to miesiąc, dni, godziny, minuty, sekundy, milisekundy, mikrosekundy, nanosekundy lub mniejsze:i>6?t<2?"00"+p:t<3?0+p:p
: Jeśli jest to milisekunda lub mniejsza: W razie potrzeby dodaj wiodące zera:t<2?0+p:p;
: W przeciwnym razie (miesiąc, dni, godziny, minuty, sekundy): W razie potrzeby dodaj pojedyncze wiodące zeroreturn r
: Zwraca wynikźródło
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.).
- możesz wziąć dane wejściowe jako listę liczbową i pominąć kosztowne dzielenie i konwersję.long
64 największe są największe) są zbyt małe w Javie dla niektórych danych wejściowych, więcString
są krótsze niżjava.math.BigInteger
.String
Zmieniłem go jednak na tablicę, więc nie muszę robić podziału na kropki, co oszczędzało niektóre bajty, więc dziękuję.Excel VBA,
500486485470 bajtówAnonimowa funkcja natychmiastowego okna VBE
Anonimowa funkcja bezpośredniego okna VBE, która pobiera dane jako rok od
[A1]
, miesiąc od[B1]
, dni od[C1]
, godziny od[D1]
, minuty od[E1]
, sekundy od[F1]
i opcjonalna tablica o dodatkowej precyzji od[G1:Z1]
, oblicza znacznik czasu RFC2550 i wysyła dane do bezpośredniego okna VBE. Wykorzystuje zadeklarowaną funkcję pomocnika poniżej.Funkcja pomocnika
Zadeklarowana funkcja pomocnicza, która pobiera numer wejściowy i zwraca tę liczbę w bazie 26, tak że
1->A
i26->Z
Musi zostać umieszczony w module publicznym.
Stosowanie
Muszą być stosowane w sposób jasny moduł lub moduł musi być usunięte przed wykonaniem co Vars
j
,o
ip
zakłada się, że w ich stanie niezainicjowane domyślnie na początku wykonanie kodu. Dlaj
, która jestVariant\Integer
zmienną, ta wartość domyślna to,0
a dlao
ip
, które sąVariant\String
zmiennymi, ta wartość domyślna jest pustym ciągiem (""
).Dane wejściowe, tablica ciągów znaków, są pobierane z
1:1
arkusza ActiveSheet, a dane wyjściowe są przekazywane do bezpośredniego okna VBE.Próbki we / wy
Sub
rutynowa wersjaZadeklarowany podprogram, który pobiera dane wejściowe jako rok od
[A1]
, miesiąc od[B1]
, dni od[C1]
, godziny od[D1]
, minuty od[E1]
, sekundy od[F1]
i opcjonalna tablica o dodatkowej precyzji od[G1:Z1]
, oblicza znacznik czasu RFC2550 i wysyła dane do bezpośredniego okna VBE.Stosowanie
Wprowadzanie do zakresu
[A1:ZZ1]
można wykonać ręcznie, wpisując do komórki, od lewej do prawej, w zależności od potrzeb, lub przypisując z bezpośredniego okna VBE.Należy zauważyć, że ze względu na automatyczne konwertowanie liczb Excela na notację naukową, wszelkie liczby o długości 10-bazowej równej lub większej niż 12 cyfr muszą zostać wstawione do komórki jawnie jako tekst poprzez ustawienie komórki jako komórki tekstowej lub przygotowując literał
'
na początek wartości komórkiPróbki we / wy
Nieoznakowany i wyjaśniony
źródło
Galaretka ,
165126 bajtówWypróbuj online!
Wiersz 4 wykonuje formatowanie roku przy pomocy wierszy 2 i 3. Pierwszy i ostatni wiersz dotyczą zerowania wypełniania elementów danych wejściowych do ich odpowiedniej długości, a następnie łączenia ich ze sformatowanym rokiem.
_µ‘l26Ċṗ@€ØAẎị@
znajduje 26 podstawowy prefiks. Pobiera kartezjańską moc alfabetu (ØA
) dla każdej liczby od 1 do sufitu (log 26 (floor (log 10 (year)) - n + 1)) (gdzie n to 30 lub 4), a następnie pobiera indeksy do tej listy z podłogą (log 10 (rok)) - n (ị@
).ç30;€”^UZF
formaty lat> = 10 30 (®L>30¤?
)ç4⁶;
formaty lat <10 30 . ( Edycja : Zapisano bajt za pomocą⁶;
zamiast;@⁶
)1RḊ
ḟ
daje pusty prefiks dla lat <10 5 (®L>4¤?
). Pobiera listę cyfr, a następnie odfiltrowuje każdy element sam w sobie. Po prostu używam tego do plonu,[]
ponieważ⁸
tutaj nie działa.To tylko ocenia[]
.⁸
i[]
nie działają tutaj i nie mogłem znaleźć kolejnych 2 bajtów, które zwrócą pustą listę.;®AṾ€¤
dołącza rok do przedrostka, a następnie spłaszcza go.L=4”/x
przedrostki a,/
jeśli długość roku wynosi 4 w instrukcji do z®S<0¤¡
.2£FiЀ¹ị€2£UF¤
przyjmuje uzupełnieniaA .. Z
,0 .. 9
a^ /*!
jeśli rok jest ujemny (®S<0¤¡
).2£
odnosi się do drugiego linku,ØD,“^ *!”,ØA
którym jest lista[['0' .. '9'], ['^',' ','/','*','!'], ['A' .. 'Z']]
. Przy sformatowanym roku takim jak^C125...
ten link znajduje indeks każdego znaku w spłaszczonej wersji,2£
a następnie używa tych indeksów do skonstruowania nowego ciągu ze spłaszczonej wersji2£
miejsca odwrócenia każdej podlisty, tj .['9' .. '0','!','*','/',' ','^','Z' .. 'A']
Plonu!X874...
./
odwzorowuje się do siebie, ponieważ jest prefiksowany, zanim wszystko zostanie uzupełnione.Skończyło się na tym, że umieściłem to w poprzedniej instrukcji do (L=4a®S<0x@”/;
dodaje/
na początku lat ujemnych w[-9999 .. -0001]
. Domyślam się, że można to skrócić.¡
) i zapisałem 7 bajtów, ponieważ wtedy nie musiałem dwukrotnie testować ujemnych lat.WZacząłem¡
linii 4 jest wiele zastosowań i myślę, że można by je skompresować, używając?
zamiast tego, ale nie jestem pewien, jak sprawić, by działały.?
pracować i zaoszczędziłem kilka bajtów.James Holderness zwrócił uwagę, że moje pierwsze zgłoszenie nie dotyczyło lat z poprawnymi 30 cyframi. Okazało się, że błąd występował w każdym roku, który wymagał
Z
prefiksu podstawowego 26. Okazuje się, że nie mogłem użyć,ṃ
ponieważ po przekonwertowaniu 26 na bazę 26 daje to[1,0]
zamiast26
(duh). Zamiast tego użyłem zamówionych par z zamiennikiem. Nie sądzę, że jest do tego atom, ale jeśli tak, mogę zaoszczędzić kilka bajtów. Naprawienie tego kosztowało mnie ~ 40 bajtów. Zdecydowanie mój najdłuższy jak dotąd program Jelly. Edycja : Znaleziono krótszy sposób wykonania produktu kartezjańskiego. Uświadomiłem sobie, że nie jestem pewien, czy ostatni działał dla prefiksów z więcej niż dwiema literami, ale nowy sposób działa.Przepraszam, że wiele razy edytowałem ten post, po prostu odkrywam sposoby jego skracania.
źródło