RFC 2550 zaman damgasını hesapla


26

RFC 2550 , herhangi bir tarihi (evrenin başlangıcından önceki ve hatta evrenin öngörülen geçmişini geçenler bile) destekleyen zaman damgasını gösteren, yer bakımından verimli bir ASCII temsili için (1 Nisan 1999'da yayınlanan) hiciv bir öneridir. RFC 2550 uyumlu bir zaman damgasını hesaplamak için kullanılan algoritma aşağıdaki gibidir (not: tüm aralıklar başlangıcı içerir, ancak sonu hariç tutar - 0 ila 10,000 her şeyin nolduğu anlamına gelir 0 <= n < 10000):

  • Yıl biçimi
    • 0 ila 10,000 arası yıllar: Sıfırlarla bırakılan 4 basamaklı bir ondalık sayı.
    • Yıl 10.000 - 100.000: A karakteriyle önceden işaretlenmiş 5 basamaklı bir ondalık sayı.
    • Yıl 100,000 için 10 30 : İngilizce alfabesinde büyük ASCII harfi kimin endeks öneki yıla ondalık sayı, 7 C 5 (B 6-basamağı için yıllar ondalık yılda basamak sayısına eşittir, eksi -digit yıllar, vs.)
    • 10 30 ila 10 56 yaş : 10,000 ila 10 30 ile aynı format , A ile başlayan harflerin başlaması ve ek olarak bir şapka ( ^) eklenmesi (böylece 10 30 yılı temsil eder ^A1000000000000000000000000000000ve 10 31 yılı temsil edilir). tarafından ^B10000000000000000000000000000000).
    • Yıl 10 56 10 -e doğru 732 : yıl iki düzeltme imi ve harfler büyük harf iki ASCII öneki. Büyük harfler, yıl içindeki eksi 57 sayısını gösteren taban-26 sayısını oluşturur.
    • Yıllar 10 732'den sonra: 10 56 - 10 732 için aynı format kullanılır, gerektiğinde ilave bir şapka ve büyük harf ekleyerek genişletilir.
    • BCE yıl (0 Yılından önce): yılın mutlak değerinin yıl dizesini hesaplar. Ardından, tüm harfleri taban-26 tamamlayıcısıyla (A <-> Z, B <-> Y, vb.) Değiştirin, tüm basamakları taban-10 tamamlayıcısıyla (0 <-> 9, 1 <-> 8, vb.) ve şapkaları ünlem işareti ( !) ile değiştirin . Yıl dizesi 4 veya daha az basamaklıysa (yani -1 ile -10.000 arası), bir eğik çizgi hazırlayın ( /). Yıl dizesi eğik çizgi veya ünlem işareti ile önizlenmemişse, bir yıldız işareti ( *) hazırlayın .
  • Aylar, günler, saatler, dakikalar ve saniyeler : bu değerler en fazla sadece 2 hane olduğundan, yıl dizisinin sağına, önem sırasının düşürülmesiyle, gerekirse oluşturmak için sıfırla doldurulmuş olarak eklenirler. 2 basamaklı dizeler.
  • Ek hassasiyet : Ek hassasiyet (milisaniye, mikrosaniye, nanosaniye, vb.) Gerekliyse, bu değerler sıfırdan 3 basamağa kadar sola doldurulur (çünkü her değer 1/1000önceki değere sahiptir ve bu nedenle en fazladır 999) ve önem sırasının düşürülmesiyle, zaman damgasının sonuna eklenmiştir.

Bu biçim, sözcük sıralamanın karşılık gelen zaman damgasının sayısal sıralamasına eşdeğer olma avantajına sahiptir - A zamanı B zamanından önce gelirse, A için zaman damgası sözcüksel sıralama uygulandığında B zaman damgasından önce gelir.

Meydan okuma

Rastgele uzun bir sayısal değer listesi göz önüne alındığında (örneğin azalan önem sırasındaki zaman değerlerine karşılık gelir [year, month, day, hour, minute, second, millisecond]), karşılık gelen RFC 2550 zaman damgasını gösterir.

kurallar

  • Çözümler verilen herhangi bir girdi için çalışmalıdır. Tek sınırlamalar zaman ve boş hafıza olmalıdır.
  • Girdi, makul, uygun herhangi bir biçimde alınabilir (örneğin, sayısal bir liste, bir dizge listesi, tek bir rakamsız karakter ile sınırlandırılmış bir dize vb.).
  • Girdi her zaman en az bir değer içerecektir (yıl). Ek değerler her zaman azalan önem sırasına göre sıralanır (örneğin, girdi hiçbir zaman bir ay değeri olmayan bir gün değeri veya ardından bir ay değeri izleyen ikinci bir değer içermez).
  • Girdi her zaman geçerli bir zaman olacaktır (örneğin, 30 Şubat için hiçbir zaman damgası olmayacak).
  • RFC 2550 zaman damgasını hesaplayan yerleşikler yasaktır.

Örnekler

Bu örnekler, girişi tek tek bir dize olarak kullanır, tek tek değerler perio ( .) ile ayrılır .

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

Referans uygulaması

#!/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)

Mutlaka -696443266.1.3.6.10.15.21.28olmalı *V3035567339896938984978971?
Neil,

11
@Neil Negatif aylar icat edene kadar. Negember.
Mego

1
@TaylorScott Ek hassasiyet : ek hassasiyet gerekirse (milisaniye, mikrosaniye, nanosaniye, vb.), Bu değerler sıfır ile 3 hane arasında bırakılır.
Mego

2
Bana soruda verilen özellik aslında RFC2550 ile eşleşmiyor gibi görünüyor. Anladığım kadarıyla, üç haneyi geçtikten sonra, harf sayısının şapka sayısından daha hızlı artması gerekir çünkü Fibonacci serisinden türetilmiştir (4 karakter 5 harf, 5 karakter 8 harf vb.) Güvenli midir? RFC'nin bu yönünü görmezden gelmemiz gerektiğini varsayalım.
James Holderness

1
@JamesHolderness Haklısın, şartnameyi bozdum. Bununla birlikte, düzeltmek için çok geç, çünkü zaten geçersiz sayılabilecek cevaplar var.
Mego

Yanıtlar:


5

JavaScript (ES6), 325 bayt

f=
s=>s.split`.`.map((n,i)=>i?`00${n}`.slice(i>5?-3:-2):n<'0'?g(n.slice(1),'!','*','/').replace(/\w/g,c=>c>'9'?(45-parseInt(c,36)).toString(36):9-c):g(n),g=(n,c='^',d='',e='',l=n.length)=>l<5?e+`000${n}`.slice(-4):l<31?d+(l+5).toString(36)+n:h(l-30,c)+n,h=(n,c)=>n?c+h(--n/26|0,c)+(n%26+10).toString(36):'').join``.toUpperCase()
;
<input oninput=o.value=f(this.value);><input id=o>

Şok edici derecede uzun.


Kolay test için bir Yığın Parçacığı ekler misiniz?
Mego

@Mego Tamamlandı. Ayrıca bazı yazım hataları sabit ki sızdı (kopyalama ve hat sarma beni karıştı çünkü yapıştırırken yanlışlıkla kod bazı silinmiş Üzgünüz..)
Neil

3

Befunge, 418 384 bayt

Bir Befunge programının ne kadar büyük olabileceğini önceden söylemek zordur ve bu konuda çalışmaya başladığımda aslında rekabet etme şansının olabileceğini düşündüm. Yanıldığımı ortaya koydu.

~:59*-!:00p:2*1\-10p:9*68*+20p>0>#~$_v
68*-:0\`30p\>>:"P"%\"P"/9+p30g#v_1+:~>
0\`v`\0:\p04<<:+1g04-$<_\49+2*v>0>+#1:#\4#g\#0`#2_130p040p5-::01-`\49+2*-:
v:$_\50p\$:130g:1+30p:!^!:-1\*<>g*"A"++\49+2*/50g1-:
_$1+7g00g40g!**:!>_40g:!v!:\g8<^00*55*g01%*2+94:p05
|#9/"P"\%"P":<:_,#!>#:<$_1-00g^v3$\_\#`\0:>#g+
>10g*20g+,1+:^v\&\0+2`4:_@#`<0+<
/*v*86%+55:p00<_$$>:#,_$1+~0^
^!>+\55+/00g1-:^

Çevrimiçi deneyin!


3

Perl 5 , 328 322 317 301 + 1 ( -a) = 302 bayt

$_=shift@F;if(($l=y/-//c)<5){s/^/0 x(4-$l)/e}elsif($l<57){s/^/'^'x($l>30).chr 65+($l-5)%26/e}else{$l-=57;do{s/\^*\K/'^'.chr 65+$l%26/e}while$l=int$l/26;s/^\^\K\D-?\d/^A$&/}if(s/-//){s%^....$%/$&%;eval join'',reverse'!/',0..9,A..Z,"y/A-Z0-9^/";s%^[^!/]%*$&%}printf$_.'%02d'x(@F>5?5:@F).'%03d'x(@F-5),@F

Çevrimiçi deneyin!

Ungolfed

$_=shift@F; # Store the year in the default variable for easier regex

if(($l=y/-//c)<5){      # if the length of the year is less than 5
    s/^/0 x(4-$l)/e         # pad with leading zeros to 4 digits
}elsif($l<57){          # if the length is less than 57
    s/^/'^'x($l>30).chr 65+($l-5)%26/e  # put a carat at the front if there are more than 30 characters
                        # and map the length minus 5 to A-Z
}else{
    $l-=57;         # offset the length by 57
    do{         
        s/\^*\K/'^'.chr 65+$l%26/e # put a carat at the front and map the length to base 26 (A-Z)
    }while$l=int$l/26;  # until the length is down to 0
    s/^\^\K\D-?\d/^A$&/ # insert an extra '^A' to pad the result to at least 2 characters if there was only 1
}
if(s/-//){          # if the year is negative
    s%^....$%/$&%;          # put a '/' in front of a 4 digit year
    eval join'',reverse'!/',0..9,A..Z,"y/A-Z0-9^/"; # map A-Z,0-9, and ^ to Z-A,9-0, and ! respectively
    s%^[^!/]%*$&%           # add a * at the front if there are no other indicators
}
printf$_.           # output the year
'%02d'x(@F>5?5:@F).             # followed by the month, day, hour, and minutes, padded to 2 digits
'%03d'x(@F-5),@F                # followed by fractional seconds, padded to three digits

3

Java 8, 653 640 637 623 bayt

s->{String r="",q="ABCDEFGHIJKLMNOP",z=q+"QRSTUVWXYZ",y="0123456789",x;int i=0,f=0,t,u;for(String p:s){if(p.charAt(0)<46){p=p.substring(1);f=1;}t=p.length();if(i++<1){r+=(t<5?"000".substring(t-1):t<32?(char)(t+60):t<58?"^"+(char)(t+34):"");if(t>57){for(r+="^^",u=675;u<t-57;u*=26)r+="^";x="";for(String c:Long.toString(t-57,26).toUpperCase().split(""))x+=z.charAt((y+q).indexOf(c));r+=x;}r+=p;if(f>0){x=t<5?"/":t<32?"*":r.replace("^","!").replaceAll("[^!]","");for(char c:r.toCharArray())x+=c>93?"":"ZYXWVUTSRQPONMLKJIHGFEDCBA9876543210".charAt((z+y).indexOf(c));r=x;}}else r+=i>6?t<2?"00"+p:t<3?0+p:p:t<2?0+p:p;}return r;}

String-Array olarak giriş ve return olarak yazın String.

Oldukça uzun olduğu ortaya çıktı (beklendiği gibi), ancak kesinlikle biraz daha golf oynayabiliyor. Sadece bir süre uğraştıktan sonra çalıştığı için memnunum.

Burada dene.

Açıklama:

  • for(String p:s){: Parçaların üzerinden döngü
    • if(p.charAt(0)<46){p=p.substring(1);f=1;}: Olumsuz olup olmadığını belirle ve varsa eksi işaretini kaldır ve baytları azaltmak için bir bayrak ayarla
    • t=p.length();: Rakam miktarını al
    • if(i++<1){: İlk sayı ise (yıl):
      • t<5?"000".substring(t-1): Eğer 0-100,000 (özel) ise: Gerekirse baştaki sıfır ekleyin
      • t<32?(char)(t+60): Eğer 100,000-10 30 (özel) ise: Bir baş harfi ekleyin
      • t<58?"^"+(char)(t+34): Eğer 10 30 -10 732 ise (özel): Değişmez "^"+ baş harf yaz
      • if(t>57)for(r+="^^",u=675;u<t-57;u*=26)r+="^";: Uygun miktarda değişmez "^"+ x="";for(String c:Long.toString(t-57,26).toUpperCase().split(""))x+=z.charAt((y+q).indexOf(c));r+=x;: baş harfleri ekleyiniz (üs-26 - alfabe dönüşümü)
      • r+=p;: Yılı sonucu sonuç dizesine ekler
      • if(f>0){: Yıl negatifse:
        • x=t<5?"/":t<32?"*":r.replace("^","!").replaceAll("[^!]","");: Geçici bir dize oluşturma xdoğru ile /, *ya da bir ya da birden fazla!
        • for(char c c:r.toCharArray())x+=c>93?"":"ZYXWVUTSRQPONMLKJIHGFEDCBA9876543210".charAt((z+y).indexOf(c));: Dönüştürmeyi yapın (A↔Z, B↔Y, 0↔9, 1↔8, vb.)
        • r=x;: Ve sonra sonucu bu geçici String olarak ayarlayın x
    • else: Ay, gün, saat, dakika, saniye, milisaniye, mikrosaniye, nanosaniye veya daha küçükse:
      • i>6?t<2?"00"+p:t<3?0+p:p: Milisaniye veya daha küçükse: Gerekirse baştaki sıfır ekleyin
      • :t<2?0+p:p;: Başka (ay, gün, saat, dakika, saniye): Gerekirse tek satır başı ekle
  • return r: Sonucu döndür

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.).- bir sayısal liste olarak girdi alabilir ve maliyetli bölmeyi ve dönüştürmeyi atlayabilirsiniz.
Mego

1
@Mego Ne yazık ki varsayılan rakamlar ( long64 bit en büyük olanıdır ), bazı girdiler için Java'da çok küçüktür, bundan Stringdaha kısadır java.math.BigInteger. Ben onu bir Stringdizi olarak değiştirdim , bu yüzden bazı baytları saklayan noktalara bölünme yapmama gerek kalmadı, bu yüzden teşekkürler.
Kevin Cruijssen

2

Excel VBA, 500 486 485 470 Bayt

Anonim VBE Acil Pencere İşlevi

İsteğe göre [A1], yıldan ay [B1], günden [C1], saatten [D1], dakikadan dakikaya [E1], saniyeden güne [F1]ve isteğe bağlı ekstra hassas bir diziden girdi alan anonim VBE acil pencere işlevi [G1:Z1], RFC2550 zaman damgasını hesaplar ve VBE acil durum penceresine çıkış yapar. Aşağıdaki belirtilen yardımcı fonksiyonunu kullanır.

n=Left([A1],1)="-":y=Mid([A1],1-n):l=Len(y):o=IIf(l<5,Right("000"&y,4),IIf(l<31,"",String(Len(b(l-30)),94))&B(l-IIf(l<31,4,30))&y):For Each c In[B1:Z1]:j=j+1:p=p+IIf(c,Format(c,IIf(j>5,"000","00")),""):Next:If n Then For i=1To Len(o):c=Asc(Mid(o,i,1)):Mid$(o,i,1)=Chr(IIf(c<60,105,155)-c):Next:?IIf(l<5,"/",IIf(InStr(1,o,"="),"","*"))Replace(o,"=","!")p:Else?o;p

Yardımcı İşlev

Baz-26 bu şekilde bir giriş numarası ve döner bu sayı alır beyan edilen yardımcı fonksiyon 1->Ave26->Z

Genel modüle yerleştirilmelidir.

Function b(n)
While n
n=n-1
d=n Mod 26+1
n=Int(n/26)
d=d+26*(d<0):n=n-(d<0)
b=Chr(64+d)+b
Wend
End Function

kullanım

Net bir modülde kullanılmalıdır veya modül vars olarak icra önce temizlenmesi gerekir j, ove pkod çalıştırılmasına başında onların varsayılan, başlatılmamış durumda olduğu varsayılır. İçin jbir olan Variant\Integerdeğişken, bu varsayılan değerdir 0ve için ove phangi, Variant\Stringdeğişkenler, bu varsayılan değeri boş dize ( "").

Bir dizi dizge olan giriş, 1:1ActiveSheet'ten alınır ve çıktı VBE hemen penceresine çıkar.

Örnek G / Ç

[A1:F1]=Split("4052107100422150625478207675901330514555829957419806023121389455865117429470888094459661251.2.3.5.7.11",".")
n=Left([A1],1)="-":y=Mid([A1],1-n):l=Len(y):o=IIf(l<5,Right("000"&y,4),IIf(l<31,"",String(Len(b(l-30)),94))&B(l-IIf(l<31,4,30))&y):For Each c In[B1:ZZ1]:j=j+1:p=p+IIf(c,Format(c,IIf(j>5,"000","00")),""):Next:If n Then For i=1To Len(o):c=Asc(Mid(o,i,1)):Mid$(o,i,1)=Chr(IIf(c<60,105,155)-c):Next:?IIf(l<5,"/",IIf(InStr(1,o,"="),"","*"))Replace(o,"=","!")p:Else?o;p
^^BI40521071004221506254782076759013305145558299574198060231213894558651174294708880944596612510203050711021028

Cells.Clear:j=0:o="":p="" '' clear the worksheet and vars
[A1:H1]=Array("-696443266","1","3","6","10","15","21","28")
n=Left([A1],1)="-":y=Mid([A1],1-n):l=Len(y):o=IIf(l<5,Right("000"&y,4),IIf(l<31,"",String(Len(b(l-30)),94))&B(l-IIf(l<31,4,30))&y):For Each c In[B1:ZZ1]:j=j+1:p=p+IIf(c,Format(c,IIf(j>5,"000","00")),""):Next:If n Then For i=1To Len(o):c=Asc(Mid(o,i,1)):Mid$(o,i,1)=Chr(IIf(c<60,105,155)-c):Next:?IIf(l<5,"/",IIf(InStr(1,o,"="),"","*"))Replace(o,"=","!")p:Else?o;p
*V3035567330103061015021028

Cells.Clear:j=0:o="":p="" '' clear the worksheet and vars
[A1]="45941"
n=Left([A1],1)="-":y=Mid([A1],1-n):l=Len(y):o=IIf(l<5,Right("000"&y,4),IIf(l<31,"",String(Len(b(l-30)),94))&B(l-IIf(l<31,4,30))&y):For Each c In[B1:ZZ1]:j=j+1:p=p+IIf(c,Format(c,IIf(j>5,"000","00")),""):Next:If n Then For i=1To Len(o):c=Asc(Mid(o,i,1)):Mid$(o,i,1)=Chr(IIf(c<60,105,155)-c):Next:?IIf(l<5,"/",IIf(InStr(1,o,"="),"","*"))Replace(o,"=","!")p:Else?o;p
A45941

Cells.Clear:j=0:o="":p="" '' clear the worksheet and vars
[A1:F1]=Split("4052107100422150625478207675901330514555829957419806023121389455865117429470888094459661251.2.3.5.7.11",".")
n=Left([A1],1)="-":y=Mid([A1],1-n):l=Len(y):o=IIf(l<5,Right("000"&y,4),IIf(l<31,"",String(Len(b(l-30)),94))&B(l-IIf(l<31,4,30))&y):For Each c In[B1:ZZ1]:j=j+1:p=p+IIf(c,Format(c,IIf(j>5,"000","00")),""):Next:If n Then For i=1To Len(o):c=Asc(Mid(o,i,1)):Mid$(o,i,1)=Chr(IIf(c<60,105,155)-c):Next:?IIf(l<5,"/",IIf(InStr(1,o,"="),"","*"))Replace(o,"=","!")p:Else?o;p
^^BI40521071004221506254782076759013305145558299574198060231213894558651174294708880944596612510203050711

Subrutin Sürüm

İsteğe göre bir yıldan itibaren [A1], aydan [B1]güne, günden [C1], saatten [D1], dakikadan [E1], saniyeden, [F1]isteğe bağlı ekstra hassas bir diziden [G1:Z1]girdi alan Alt Rutin, RFC2550 zaman damgasını hesaplar ve VBE anında penceresine çıkış yapar.

Sub R(x)
a=x(0)
n=Left(a,1)="-"'<- that `"` is only there to make sure highlighting is correct
y=Mid(a,1-n)
l=Len(y)
o=IIf(l<5,Right("000"&y,4),IIf(l<31,"",String(Len(b(l-30)),94))&B(l-IIf(l<31,4,30))&y)
If n Then For i=1To Len(o):c=Asc(Mid(o,i,1)):Mid$(o,i,1)=Chr(IIf(c<60,105,155)-c):Next:o=IIf(l<5,"/",IIf(InStr(1,o,"="),"","*"))&Replace(o,"=","!")
For j=1To UBound(x)
o=o+IIf(x(j),Format(x(j),IIf(j>5,"000","00")),"")
Next
[A2]=o
End Sub
Function b(n)
While n
n=n-1
d=n Mod 26+1
n=Int(n/26)
d=d+26*(d<0):n=n-(d<0)
b=Chr(64+d)+b
Wend
End Function

kullanım

Aralığa giriş, [A1:ZZ1]el ile, hücrelere yazarak, en soldan en sağa, gerektiği gibi veya VBE acil durum penceresinden atanarak yapılabilir.

Excel'in otomatik olarak sayıları bilimsel notasyona dönüştürmesi nedeniyle, 10 basamaktan büyük ya da ondan büyük 10 taban uzunluğuna sahip herhangi bir sayının, hücreyi bir metin hücresi olarak ayarlayarak ya da açıkça metin olarak hücreye yerleştirilmesi gerekir. değişmezi 'hücre değerinin başlangıcına hazırlayarak

Örnek G / Ç

r Split("4052107100422150625478207675901330514555829957419806023121389455865117429470888094459661251.2.3.5.7.11",".")
?[A2]  '' <- print output to VBE console
^^BI40521071004221506254782076759013305145558299574198060231213894558651174294708880944596612510203050711 ''  <- Output

r Array("47883552573911529811831375872990","1","1","2","3","5","8","13")
?[A2]
^B478835525739115298118313758729900101020305008013

r Array("-696443266","1","3","6","10","15","21","28")
?[A2]
*V3035567330103061015021028

r Array("45941")
?[A2]
A45941

Ungolfed ve Açıklaması

''  Returns RFC2550 timestamp corresponding to passed vars
Public Function RFC2550(ByVal pYear As String, ParamArray Extra() As Variant) As String

    ''  Declare Vars
    Dim Negative As Boolean, _
        leny As Long, _
        i As Long, _
        c As Byte, _
        s As Variant, _
        out As String

    ''  Check if year is negative and store the absolute value of the year
    Let Negative = Left(pYear, 1) = "-"
    Let pYear = Mid(pYear, 1 - Negative)

    ''  Take the length of the year
    Let leny = Len(pYear)
    If leny < 5 Then
        ''  If the length is less than 5, pad the year left to 4 characters 
        ''  using zeros
        Let out = Format("0000", pYear)
    Else
        ''  If the length of the year is greater than 30, then set out to be 
        ''  as string comprised of length-30 instances of `^`
        Let out = IIf(leny < 31, "", String(Len(Base26(leny - 30)), 94)) 
        ''  append the Base26 representation of the length of the year,
        ''  minus 30, if the length is greater than 30
        Let out = out & Base26(leny - IIf(leny < 31, 4, 30)) 
        ''  append the year to out
        Let out = out & pYear
    End If


    If Negative Then
        ''  iterate across out
        For i = 1 To Len(out)
            ''  store the char code for the current char
            Let c = Asc(Mid(out, i, 1))
            ''  swap letter/number with its inverse (0->9,A->Z)
            Mid$(out, i, 1) = Chr(IIf(c < 60, 105, 155) - c)
        Next i

        ''  replace `=` (the inverse of `^`) with `!`
        Let out = Replace(out, "=", "!")
        ''  Prepend either `/`, `*`, or nothing depending on length and 
        ''  start of out
        Let out = IIf(leny < 5, "/", IIf(InStr(1, out, "!"), "", "*")) & out
    End If

    Let i = 1
    For Each s In Extra
        ''  append all of the extra precision data - padding to 2 chars for 
        ''  the first 5 elements in the array (month, day, hour, minute and 
        ''  second) and to 3 chars for all following elements (milli, micro, 
        ''  nano, pico, femto, atto, zepto, yocto - seconds) with the char 0
        Let out = out & IIf(s, Format(s, IIf(i > 5, "000", "00")), "")
        Let i = i + 1
    Next

    ''  return out
    Let RFC2550 = out 

End Function


''  returns non-standard base26 version of input number 
''  1->A, 2->B,... 26->Z
Function Base26(ByVal n As Long) As String

    ''  declare vars
    Dim out As String, _
        digit As Integer

    ''  init out, digit
    Let out = ""
    Let digit = 0

    ''  iterate through n 
    While n
        ''  Decrement, hold the value of the digit
        Let n = n - 1
        Let digit = n Mod 26 + 1

        ''  divide by 26
        Let n = Int(n / 26)

        ''  correct for negative numbers
        If digit < 0 Then Let n = n + 1: Let digit = digit - 26

        ''  prepend char corresponding to the digit to out
        Let out = Chr(64 + digit) & out
    Wend

    ''  return out
    Let Base26 = out
End Function

2

Jöle , 165 126 bayt

ḣ5ṫ€3
ØD,“^ /*!”,ØA
_µ‘l26Ċṗ@€ØAẎị@
Lµç30;€”^UZFµç4⁶;µ®L>30¤?µḟ®L>4¤?;®AṾ€¤µL=4”/x2£FiЀị€2£UF¤µ®S<0¤¡
4R¬+DU$UµḢ©Ç;Ñ;ṫ6ṫ€2$$F

Çevrimiçi deneyin!

4. satır, 2. ve 3. satırların yardımı ile yıl biçimlendirmesini yapar. İlk ve son satır, girdi öğelerini uygun uzunluklarına doldurur ve sonra bunları biçimlendirilmiş yılla birleştirir.

  • _µ‘l26Ċṗ@€ØAẎị@taban 26 önekini bulur. ØAHer sayı için 1 ile tavan arasında (log 26 (kat 10 (yıl)) - n + 1)) (n = 30 veya 4'tür) olan alfabenin kartezyen gücünü alır. Zeminde (log 10 (yıl)) - n ( ị@).
  • ç30;€”^UZF yıl biçimleri> = 10 30 ( ®L>30¤?)
  • ç4⁶;yıl biçimleri <10 30 . ( Düzenleme : Kullanarak ⁶;yerine bir bayt kaydedildi ;@⁶)
  • 1RḊ <10 5 ( ®L>4¤?) için boş bir ön ek verir . Rakamların listesini alır ve daha sonra her bir öğeyi kendi içinde filtreler. Sadece bunu üretmek []için kullanmak çünkü burada çalışmıyor. Bu sadece değerlendirir []. ve []burada çalışma ve boş bir liste döndüren başka 2 bayt bulamadım.
  • ;®AṾ€¤ yılı ön eke ekler ve düzleştirir.
  • L=4”/xön ekler /, do ifadesinde do uzunluğu 4 ise, a ®S<0¤¡.
  • 2£FiЀ¹ị€2£UF¤tamamlayıcıları alır A .. Z, 0 .. 9ve ^ /*!yıl negatifse ( ®S<0¤¡). liste olan ikinci bağlantıyı ifade eder . Bu bağlantı gibi biçimlendirilmiş bir yılla , düzleştirilmiş sürümdeki her karakterin dizinini bulur, sonra bu dizinleri, her alt listenin tersine çevrilmiş düzleştirilmiş sürümünden yeni bir dize oluşturmak için kullanır;ØD,“^ *!”,ØA[['0' .. '9'], ['^',' ','/','*','!'], ['A' .. 'Z']]^C125...['9' .. '0','!','*','/',' ','^','Z' .. 'A'] verimlidir !X874.... /Her şeyi tamamlayıcısı alınmadan önce öneklendiğinden kendi kendine eşlenir.
  • L=4a®S<0x@”/;/içinde olumsuz yılların başlangıcına a ekler [-9999 .. -0001]. Benim tahminim bu kısaltılabilir. Bunu önceki do ifadesine dahil ettim (¡ ) ve 7 bayt çünkü iki yıl boyunca negatif yıllar için test yapmam gerekmiyordu.

¡4. satırda birçok kullanım var ve bunların kullanılarak sıkıştırılabileceğini düşünüyorum.? bunun yerine bunları ama bunların işe yarayacağından emin değilim. Bende ?işe ve birkaç bayt kaydedildi.

James Holderness, ilk başvurumun, 30 rakamı doğru olan yılları ele almadığını belirtti. Bu Z26 temelde önek gereken bir yıl için böcek olduğu ortaya çıktı . Görünüşe göre kullanamadım, çünkü 26'yı üsse 26'ya çevirirseniz, size [1,0]yerine26 (duh) . Bunun yerine yedek çiftleri sipariş yerine kullandım. Bunun için bir atom olduğunu sanmıyorum ama varsa birkaç baytı kurtarabilirim. Bunun düzeltilmesi bana maliyeti ~ 40 bayttı. Kesinlikle benim en uzun Jelly programım. Düzenleme : Kartezyen ürünü yapmak için daha kısa bir yol bulundu. Sonuncunun zaten iki harften fazla önek için çalıştığından emin değildim ama yeni yol işe yarıyor.

Bu yayını düzenlediğim için çok özür dilerim, kısaltmanın yollarını keşfetmeye devam ediyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.