RFC 2550 adalah proposal satiris (diterbitkan pada 1 April 1999) untuk representasi ASCII yang efisien ruang dari cap waktu yang dapat mendukung tanggal apa pun (bahkan yang sebelum permulaan alam semesta dan yang melewati akhir alam semesta yang diprediksi). Algoritma untuk menghitung stempel waktu yang kompatibel dengan RFC 2550 adalah sebagai berikut (catatan: semua rentang mencakup awal tetapi mengecualikan akhir - 0 hingga 10.000 berarti semua n
tempat 0 <= n < 10000
):
- Format tahun
- Tahun 0 hingga 10.000: angka desimal 4 digit, diisi dengan angka nol.
- Tahun 10.000 hingga 100.000: angka desimal 5 digit, diawali dengan karakter A.
- Tahun 100.000 hingga 10 30 : angka desimal untuk tahun tersebut, diawali dengan huruf ASCII huruf besar yang indeksnya dalam alfabet bahasa Inggris sama dengan jumlah digit pada tahun desimal, minus 5 (B untuk tahun 6-digit, C untuk 7 -digit tahun, dll.).
- Tahun 10 30 hingga 10 56 : format yang sama dengan 10.000 hingga 10 30 , mulai huruf-hurufnya dengan A, dan tambahan awalan tanda sisipan (
^
) ke string (sehingga tahun 10 30 diwakili oleh^A1000000000000000000000000000000
, dan tahun 10 31 diwakili oleh oleh^B10000000000000000000000000000000
). - Tahun 10 56 hingga 10 732 : tahun diawali oleh dua tanda sisipan dan dua huruf besar ASCII. Huruf besar membentuk angka basis-26 yang mewakili jumlah digit pada tahun tersebut, minus 57.
- Tahun 10 732 dan seterusnya: format yang sama untuk 10 56 hingga 10 732 digunakan, memperpanjangnya dengan menambahkan tanda sisipan dan huruf besar tambahan bila perlu.
- Tahun SM (sebelum Tahun 0): hitung string tahun dari nilai absolut tahun tersebut. Kemudian, ganti semua huruf dengan komplemen base-26 mereka (A <-> Z, B <-> Y, dll.), Ganti semua digit dengan komplemen base-10 mereka (0 <-> 9, 1 <-> 8, dll.), dan ganti caret dengan tanda seru (
!
). Jika string tahun adalah 4 digit atau kurang (yaitu -1 hingga -10.000), tambahkan garis miring (/
). Jika string tahun tidak diawali dengan garis miring ke depan atau tanda seru, tambahkan tanda bintang (*
).
- Bulan, hari, jam, menit, dan detik : karena nilai-nilai ini hanya 2 digit paling banyak, mereka hanya ditambahkan ke kanan string tahun, dalam urutan penurunan signifikansi, berlapis kiri dengan nol jika perlu untuk membentuk String 2 digit.
- Tambahan presisi : jika presisi tambahan (dalam bentuk milidetik, mikrodetik, nanodetik, dll.) Diperlukan, nilai-nilai tersebut dibiarkan dengan nol hingga 3 digit (karena setiap nilai
1/1000
dari nilai sebelumnya, dan dengan demikian paling banyak999
) dan ditambahkan ke akhir timestamp, dalam urutan signifikansi yang menurun.
Format ini memiliki manfaat penyortiran leksikal yang setara dengan penyortiran numerik cap waktu yang sesuai - jika waktu A datang sebelum waktu B, maka timestamp untuk A akan datang sebelum timestamp untuk B ketika penyortiran leksikal diterapkan.
Tantangan
Diberikan daftar panjang nilai numerik yang sewenang-wenang (sesuai dengan nilai waktu dalam urutan signifikansi yang menurun, misalnya [year, month, day, hour, minute, second, millisecond]
), mengeluarkan stempel waktu RFC 2550 yang sesuai.
Aturan
- Solusi harus bekerja untuk setiap input yang diberikan. Satu-satunya batasan harus waktu dan memori yang tersedia.
- Input dapat diambil dalam format yang wajar dan nyaman (seperti daftar angka, daftar string, string yang dibatasi oleh karakter non-digit tunggal, dll.).
- Input akan selalu mengandung setidaknya satu nilai (tahun). Nilai tambahan selalu dalam urutan signifikansi yang menurun (mis. Input tidak akan pernah berisi nilai hari tanpa nilai bulan, atau nilai kedua diikuti oleh nilai bulan).
- Input akan selalu menjadi waktu yang valid (mis. Tidak akan ada cap waktu untuk 30 Februari).
- Builtin yang menghitung cap waktu RFC 2550 dilarang.
Contohnya
Contoh-contoh ini menggunakan input sebagai string tunggal, dengan nilai-nilai individual dipisahkan oleh titik ( .
).
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
Implementasi referensi
#!/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
seharusnya begitu*V3035567339896938984978971
?Jawaban:
JavaScript (ES6), 325 byte
Sangat panjang.
sumber
Befunge,
418384 byteSulit untuk mengatakan sebelumnya seberapa besar program Befunge kemungkinan akan berakhir, dan ketika saya mulai bekerja pada ini saya pikir itu mungkin benar-benar memiliki peluang untuk bersaing. Ternyata saya salah.
Cobalah online!
sumber
Perl 5 ,
328 322 317301 + 1 (-a
) = 302 byteCobalah online!
Tidak disatukan
sumber
Java 8,
653640637623 byteMasukkan as
String
-array dan ketik kembali sebagaiString
.Ternyata cukup panjang (seperti yang diharapkan), tetapi pasti bisa bermain golf lagi. Aku hanya senang itu bekerja setelah mengutak-atiknya cukup lama ..
Coba di sini.
Penjelasan:
for(String p:s){
: Loop bagian-bagianif(p.charAt(0)<46){p=p.substring(1);f=1;}
: Tentukan apakah itu negatif, dan jika ya, hapus tanda minus dan atur bendera untuk mengurangi bytet=p.length();
: Dapatkan jumlah digitif(i++<1){
: Jika ini angka pertama (tahun):t<5?"000".substring(t-1)
: Jika 0-100.000 (eksklusif): tambahkan nol terkemuka jika perlut<32?(char)(t+60)
: Jika 100.000-10 30 (eksklusif): Tambahkan surat terkemukat<58?"^"+(char)(t+34)
: Jika 10 30 -10 732 (eksklusif): Tambahkan huruf literal"^"
+ terkemukaif(t>57)for(r+="^^",u=675;u<t-57;u*=26)r+="^";
: Tambahkan jumlah huruf"^"
+x="";for(String c:Long.toString(t-57,26).toUpperCase().split(""))x+=z.charAt((y+q).indexOf(c));r+=x;
: utama yang tepat (basis-26 ke konversi alfabet)r+=p;
: Tambahkan tahun itu sendiri ke String-hasilif(f>0){
: Jika tahun itu negatif:x=t<5?"/":t<32?"*":r.replace("^","!").replaceAll("[^!]","");
: Buat String tempx
dengan benar/
,*
atau satu atau beberapa!
for(char c c:r.toCharArray())x+=c>93?"":"ZYXWVUTSRQPONMLKJIHGFEDCBA9876543210".charAt((z+y).indexOf(c));
: Lakukan konversi (A↔Z, B↔Y, 0↔9, 1↔8, dll.)r=x;
: Dan kemudian atur hasilnya ke String temp inix
else
: Jika bulan, hari, jam, menit, detik, milidetik, mikrodetik, nanodetik, atau lebih kecil:i>6?t<2?"00"+p:t<3?0+p:p
: Jika milidetik atau lebih kecil: Tambahkan nol terkemuka jika perlu:t<2?0+p:p;
: Lain-lain (bulan, hari, jam, menit, detik): Tambahkan nol memimpin tunggal jika perlureturn r
: Kembalikan hasilnyasumber
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.).
- Anda dapat mengambil input sebagai daftar angka, dan melewati pemisahan dan konversi yang mahal.long
dengan 64 bit sebagai yang terbesar) terlalu kecil di Jawa untuk beberapa input, jadiString
lebih pendek darijava.math.BigInteger
. Saya mengubahnya menjadiString
-array, jadi saya tidak perlu melakukan split dengan titik-titik, yang menyelamatkan beberapa byte, jadi terima kasih.Excel VBA,
500486485470 BytesFungsi Jendela Segera VBE Anonim
Fungsi jendela langsung VBE anonim yang mengambil input dari tahun
[A1]
, bulan dari[B1]
, hari dari[C1]
, jam dari[D1]
, menit dari[E1]
, detik dari[F1]
dan array presisi ekstra opsional dari[G1:Z1]
, menghitung cap waktu RFC2550 dan output ke jendela langsung VBE. Manfaatkan fungsi pembantu yang dinyatakan di bawah ini.Fungsi Penolong
Deklarasi fungsi pembantu yang mengambil nomor input dan mengembalikan nomor itu di base-26 sedemikian rupa sehingga
1->A
dan26->Z
Harus ditempatkan dalam modul publik.
Pemakaian
Harus digunakan dalam modul yang jelas, atau modul harus dibersihkan sebelum eksekusi sebagai vars
j
,o
danp
diasumsikan dalam keadaan default dan tidak diinisialisasi pada awal pelaksanaan kode. Untukj
, yang merupakanVariant\Integer
variabel, nilai default ini adalah0
dan untuko
danp
, yang merupakanVariant\String
variabel, nilai default ini adalah string kosong (""
).Input, array string, diambil dari
1:1
pada ActiveSheet dan output ke jendela langsung VBE.Contoh I / O
Sub
Versi rutinMenyatakan Subrutin yang mengambil input dari tahun
[A1]
, bulan dari[B1]
, hari dari[C1]
, jam dari[D1]
, menit dari[E1]
, detik dari[F1]
dan array presisi ekstra opsional dari[G1:Z1]
, menghitung cap waktu RFC2550 dan output ke jendela langsung VBE.Pemakaian
Input ke kisaran
[A1:ZZ1]
dapat dilakukan secara manual, dengan mengetik ke dalam sel, dari paling kiri ke paling kanan, sesuai kebutuhan atau dengan menetapkan dari jendela langsung VBE.Sebagai catatan, karena angka konversi otomatis Excel menjadi notasi ilmiah, angka apa pun yang memiliki panjang basis-10 sama dengan atau lebih besar dari 12 digit harus dimasukkan ke dalam sel secara eksplisit sebagai teks baik dengan mengatur sel menjadi sel teks atau dengan menambahkan awal literal
'
ke awal nilai selContoh I / O
Tidak Dijelaskan Dan Dijelaskan
sumber
Jelly ,
165126 byteCobalah online!
Baris 4 melakukan pemformatan tahun dengan bantuan dari baris 2 dan 3. Baris pertama dan terakhir berurusan dengan nol yang mengisi elemen input dengan panjang yang sesuai kemudian menggabungkannya dengan tahun yang diformat.
_µ‘l26Ċṗ@€ØAẎị@
menemukan awalan base 26. Dibutuhkan kekuatan kartesius dari alfabet (ØA
) untuk setiap angka antara 1 dan langit-langit (log 26 (lantai 10 (tahun 10 )) - n +1)) (di mana n adalah 30 atau 4) kemudian mendapat indeks ke dalam daftar ini dengan lantai (log 10 (tahun)) - n (ị@
).ç30;€”^UZF
format tahun> = 10 30 (®L>30¤?
)ç4⁶;
format tahun <10 30 . ( Edit : Menyimpan byte dengan menggunakan⁶;
alih-alih;@⁶
)1RḊ
ḟ
memberikan awalan kosong selama bertahun-tahun <10 5 (®L>4¤?
). Dibutuhkan daftar digit kemudian memfilter setiap elemen itu sendiri. Hanya menggunakan ini untuk menghasilkan[]
karena⁸
tidak berfungsi di sini.Ini hanya mengevaluasi[]
.⁸
dan[]
tidak bekerja di sini dan saya tidak dapat menemukan 2 byte lain yang mengembalikan daftar kosong.;®AṾ€¤
menambahkan tahun ke awalan kemudian meratakannya.L=4”/x
awalan a/
jika panjang tahun adalah 4 pada pernyataan do dari®S<0¤¡
.2£FiЀ¹ị€2£UF¤
mengambil pelengkapA .. Z
,0 .. 9
dan^ /*!
jika tahun itu negatif (®S<0¤¡
).2£
merujuk ke tautan kedua,ØD,“^ *!”,ØA
yang merupakan daftar[['0' .. '9'], ['^',' ','/','*','!'], ['A' .. 'Z']]
. Dengan tahun yang diformat seperti^C125...
tautan ini menemukan indeks setiap karakter dalam versi yang diratakan2£
kemudian menggunakan indeks tersebut untuk membuat string baru dari versi yang diratakan di2£
mana setiap sublist dibalik, yaitu['9' .. '0','!','*','/',' ','^','Z' .. 'A']
menghasilkan!X874...
./
peta itu sendiri karena diawali sebelum semuanya diambil komplemennya.Saya akhirnya memasukkan ini dalam pernyataan do (L=4a®S<0x@”/;
menambahkan a/
ke awal tahun negatif di[-9999 .. -0001]
. Dugaan saya, ini bisa dipersingkat.¡
) sebelumnya dan menyimpan 7 byte karena saya tidak perlu menguji untuk tahun negatif dua kali.Ada banyak kegunaanSaya mulai¡
pada baris 4 dan saya pikir mereka dapat dikompres dengan menggunakan?
sebagai gantinya, tetapi saya tidak yakin bagaimana cara membuatnya agar berfungsi.?
bekerja dan menyimpan beberapa byte.James Holderness menunjukkan bahwa pengajuan pertama saya tidak menangani tahun dengan 30 digit benar. Ternyata bug itu untuk setiap tahun yang membutuhkan
Z
awalan base 26. Ternyata saya tidak bisa menggunakanṃ
karena ketika Anda mengkonversi 26 ke basis 26 itu memberi Anda[1,0]
alih-alih26
(ya). Sebagai gantinya saya menggunakan pasangan yang dipesan dengan pengganti. Saya tidak berpikir ada atom untuk itu tetapi jika ada saya dapat menyimpan beberapa byte. Memperbaiki ini berakhir dengan biaya saya ~ 40 byte. Pasti program Jelly terlama saya. Sunting : Menemukan cara yang lebih singkat untuk melakukan produk kartesius. Saya menyadari bahwa saya tidak yakin bahwa yang terakhir bekerja untuk awalan dengan lebih dari dua huruf, tetapi cara baru itu berhasil.Maaf untuk berkali-kali saya mengedit posting ini, saya terus mencari cara untuk memperpendeknya.
sumber