Обчисліть мітку RFC 2550


26

RFC 2550 - сатирична пропозиція (опублікована 1 квітня 1999 р.) Щодо космічного представлення ASCII часових позначок, які можуть підтримувати будь-яку дату (навіть ті, що були до початку Всесвіту, і ті, що минули передбачуваний кінець Всесвіту). Алгоритм обчислення часової позначки, сумісної з RFC 2550, такий (примітка: всі діапазони включають початок, але виключають кінець - від 0 до 10000 означає все, nде 0 <= n < 10000):

  • Формат року
    • Роки від 0 до 10000: 4-значний десятковий номер, обкладений лівими нулями.
    • Роки від 10 000 до 100 000: 5-значний десятковий номер з префіксом символу А.
    • Роки 100 000 до 10 30 : десяткове число за рік з префіксом великої літери ASCII, індекс в англійському алфавіті якого дорівнює кількості цифр у десятковому році мінус 5 (B для 6-значного року, C для 7 -дигіт років тощо).
    • Року 10 30 до 10 56 : той же формат , як 10000 до 10 30 , починаючи з буквою понад з А, і додатково префіксами каретки ( ^) до рядка (так рік 10 30 представлено ^A1000000000000000000000000000000, і рік 10 31 представлена по ^B10000000000000000000000000000000).
    • Роки 10 56 до 10 732 : рік є префіксом двома символами та двома великими літерами ASCII. Прописні літери утворюють базове число-26, що представляє кількість цифр за рік, мінус 57.
    • Роки 10 732 і далі: використовується той самий формат від 10 56 до 10 732 , розширюючи його, додаючи додаткову карету та великі літери, коли це необхідно.
    • BCE років (до року 0): обчислити рядок року за абсолютною величиною року. Потім замініть усі літери на їх доповнення базою-26 (A <-> Z, B <-> Y тощо), замініть усі цифри на доповнення бази-10 (0 <-> 9, 1 <-> 8, тощо) та замініть догляд на знак оклику ( !). Якщо рядок року становить 4 цифри або менше (тобто від -1 до -10 000), додайте косу рису вперед ( /). Якщо рядок року не префіксований косою рисою чи знаком оклику, додайте зірочку ( *).
  • Місяці, дні, години, хвилини та секунди : оскільки ці значення є лише колись двома цифрами, їх просто додають праворуч від рядка року, у порядку зменшення, за необхідністю, щоб утворити ліворуч з нулями. Двозначні рядки.
  • Додаткова точність : якщо потрібна додаткова точність (у формі мілісекунд, мікросекунд, наносекунд тощо), ці значення заливаються нулями до трьох цифр (оскільки кожне значення є 1/1000попереднім значенням, і таким чином є максимум 999) і додається до кінця часової позначки, у порядку зменшення значення.

Цей формат має перевагу того, що лексичне сортування еквівалентне чисельному сортуванням відповідної часової позначки - якщо час A настає до часу B, то часова марка для A настане перед часовою позначкою для B при застосуванні лексичного сортування.

Змагання

З огляду на довільно довгий список числових значень (відповідних тимчасовим значенням у порядку зменшення, наприклад [year, month, day, hour, minute, second, millisecond]), виведіть відповідну мітку RFC 2550.

Правила

  • Рішення повинні працювати для будь-якого даного вводу. Єдиними обмеженнями повинні бути час та доступна пам'ять.
  • Введення даних може здійснюватися в будь-якому розумному, зручному форматі (наприклад, список числових даних, список рядків, рядок, обмежений одним нецифровим символом тощо).
  • Вхід завжди буде містити принаймні одне значення (рік). Додаткові значення завжди знаходяться в порядку зменшення значення (наприклад, введення ніколи не буде містити денного значення без місячного значення або другого значення, а потім значення місяця).
  • Введення завжди буде дійсним часом (наприклад, не буде жодних часових позначок на 30 лютого).
  • Вбудовані, які обчислюють часові позначки RFC 2550, заборонені.

Приклади

У цих прикладах використовується введення як один рядок, окремі значення розділені періодами ( .).

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

Довідкова реалізація

#!/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має бути *V3035567339896938984978971?
Ніл

11
@Neil Доки ми не вигадаємо негативні місяці. Negember.
Мего

1
@TaylorScott Додаткова точність : якщо потрібна додаткова точність (у вигляді мілісекунд, мікросекунд, наносекунд тощо), ці значення заливаються нулями до 3 цифр.
Мего

2
Мені здається, що специфікація, наведена у питанні, насправді не відповідає RFC2550. Як я розумію, коли ви пройдете три курси, кількість букв має збільшуватися швидше, ніж догляд, оскільки це походить із серії Фібоначчі (4 карети означає 5 букв, 5 карту - 8 літер тощо)? Чи безпечно це припустимо, що ми повинні ігнорувати цей аспект RFC?
Джеймс Холдернесс

1
@JamesHolderness Ти маєш рацію, я зіпсував специфікацію. Однак виправити це вже пізно, оскільки вже є відповіді, які були б визнані недійсними.
Мего

Відповіді:


5

JavaScript (ES6), 325 байт

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>

Шокуюче довго.


Ви б не хотіли додати фрагмент стека для легкого тестування?
Мего

@Mego Готово. Також виправили деякі помилки, які прокралися (я випадково видалив частину коду при копіюванні та вставці, тому що обтікання рядків плутало мене. На жаль)
Ніл

3

Befunge, 418 384 байт

Важко заздалегідь сказати, наскільки велика програма Befunge, ймовірно, закінчиться, і коли я почав працювати над цим, я подумав, що це може мати певний шанс змагатися. Виявляється, я помилявся.

~: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-:^

Спробуйте в Інтернеті!


3

Perl 5 , 328 322 317 301 + 1 ( -a) = 302 байти

$_=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

Спробуйте в Інтернеті!

Безумовно

$_=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 байт

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масив та тип повернення як String.

Виявилося досить довгим (як очікувалося), але напевно можна пограти ще трохи. Я просто радий, що це працює після того, як довгий час поспілкувався з ним.

Спробуйте тут.

Пояснення:

  • for(String p:s){: Петля на частини
    • if(p.charAt(0)<46){p=p.substring(1);f=1;}: Визначте, чи він негативний, а якщо він є, видаліть знак мінус та встановіть прапор для зменшення байтів
    • t=p.length();: Отримайте кількість цифр
    • if(i++<1){: Якщо це перший номер (рік):
      • t<5?"000".substring(t-1): Якщо це 0-100 000 (виключно): додайте нульові нулі, якщо потрібно
      • t<32?(char)(t+60): Якщо це 100 000-10 30 (ексклюзивно): додайте провідну літеру
      • t<58?"^"+(char)(t+34): Якщо це 10 30 -10 732 (ексклюзивно): додайте буквальне значення"^" + провідне письмо
      • 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; : провідні літери (база-26 до перетворення алфавіту)
      • r+=p;: Додайте сам рік до результату String
      • if(f>0){: Якщо рік був негативним:
        • x=t<5?"/":t<32?"*":r.replace("^","!").replaceAll("[^!]","");Створіть тимчасову рядок xз правильним /, *або один або кілька!
        • for(char c c:r.toCharArray())x+=c>93?"":"ZYXWVUTSRQPONMLKJIHGFEDCBA9876543210".charAt((z+y).indexOf(c));: Проведіть конверсію (A↔Z, B↔Y, 0↔9, 1↔8 тощо)
        • r=x;: А потім встановіть результат на цей тимчасовий рядок x
    • else: Якщо це місяць, дні, години, хвилини, секунди, мілісекунди, мікросекунди, наносекунди або менше:
      • i>6?t<2?"00"+p:t<3?0+p:p: Якщо це мілісекунди або менше: додайте провідні нулі, якщо потрібно
      • :t<2?0+p:p;: Інше (місяць, дні, години, хвилини, секунди): Додайте єдиний провідний нуль, якщо потрібно
  • return 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.).- ви можете взяти введення як список числових даних і пропустити дороге розщеплення та перетворення.
Мего

1
@Mego На жаль, чисельність за замовчуванням ( longз 64 бітами є найбільшими) на Java для деяких входів занадто мала, тому Stringкоротша, ніж java.math.BigInteger. Я змінив його на String-array, тому мені не потрібно робити розділення на крапки, які зберегли деякі байти, тож спасибі.
Кевін Круїссен

2

Excel VBA, 500 486 485 470 байт

Анонімна функція негайного вікна VBE

Анонімна функція негайного вікна VBE, яка приймає введення як рік з [A1], місяць з [B1], дні з [C1], години з [D1], хвилини з [E1], секунди з, [F1]і необов'язковий додатковий точний масив з [G1:Z1], обчислює часову позначку RFC2550 і виводить до безпосереднього вікна VBE. Використовується оголошена помічна функція нижче.

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

Функція помічника

Задекларована функція помічника, яка приймає вхідне число і повертає це число в базовій-26 так, що 1->A і26->Z

Потрібно розмістити в загальнодоступному модулі.

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

Використання

Повинен бути використаний у прозорому модулі, або модуль повинен бути очищений перед виконанням як варс j, oі pвважається, що він знаходиться в їхньому за замовчуванні, неініціалізованому стані на початку виконання коду. Для j, яка є Variant\Integerзмінною, це значення за замовчуванням0 і для, oі pякі є Variant\Stringзмінними, це значення за замовчуванням - порожній рядок ( "").

Вхід, масив рядків, береться з 1:1ActiveSheet, а вихід - до безпосереднього вікна VBE.

Зразок вводу / виводу

[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

Subрутинна версія

Задекларована підпрограма, яка приймає дані як рік з [A1], місяць з [B1], дні з [C1], години з [D1], хвилини від [E1], секунди від, [F1]і необов'язковий додатковий точний масив з [G1:Z1], обчислює часову позначку RFC2550 і виводить на безпосереднє вікно VBE.

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

Використання

Введення в діапазон [A1:ZZ1]може бути здійснено або вручну, ввівши в комірки, від крайнього лівого до правого краю, за необхідності, або шляхом призначення з прямого вікна VBE.

Зауважимо, що завдяки автоматичному перетворенню чисел Excel у наукові позначення будь-які числа, довжина основи 10 яких дорівнює або перевищує 12 цифр, повинні бути вставлені в комірку явно як текст, встановивши комірку як текстову клітинку або попередньо додавши буквальне 'значення до початку значення комірки

Зразок вводу / виводу

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

Непорочний і пояснений

''  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

Желе , 165 126 байт

ḣ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

Спробуйте в Інтернеті!

Рядок 4 виконує форматування року за допомогою рядків 2 і 3. Перший і останній рядки мають справу з нульовим підбиванням елементів вхідних даних до їх належної довжини, а потім приєднання їх до форматованого року.

  • _µ‘l26Ċṗ@€ØAẎị@знаходить основу 26 префікса. ØAДля кожного числа між 1 і стелею потрібна декартова сила алфавіту ( ) (log 26 (пол (журнал 10 (рік 10 )) - n + 1)) (де n або 30 або 4), а потім отримує індекси до цього списку з підлогою (журнал 10 (рік)) - n (ị@ ).
  • ç30;€”^UZF формати років> = 10 30 ( ®L>30¤?)
  • ç4⁶;формати років <10 30 . ( Редагувати : збережений байт, використовуючи ⁶;замість ;@⁶)
  • 1RḊ дає порожній префікс років <10 5 ( ®L>4¤?). Він бере список цифр, а потім фільтрує кожен елемент у собі. Просто використовуючи це, щоб отримати вихід, []оскільки тут не працює. Це просто оцінює []. і []не працюю тут, і я не зміг знайти ще 2 байти, які повертають порожній список.
  • ;®AṾ€¤ додає рік до префікса, а потім розгладжує.
  • L=4”/xпрефіксів a, /якщо довжина року дорівнює 4 в операторі do ®S<0¤¡.
  • 2£FiЀ¹ị€2£UF¤приймає доповнення A .. Z, 0 .. 9і ^ /*!якщо рік негативний ( ®S<0¤¡). посилається на друге посилання, ØD,“^ *!”,ØAяке є списком [['0' .. '9'], ['^',' ','/','*','!'], ['A' .. 'Z']]. З відформатованим роком, як ^C125...це посилання, знаходить індекс кожного символу в сплющеній версії, а потім використовує ці індекси для побудови нового рядка з сплющеної версії де кожен підпис перевертається, тобто ['9' .. '0','!','*','/',' ','^','Z' .. 'A']дає вихід !X874.... /мапи до себе, тому що це префікс, перш ніж все буде прийнято.
  • L=4a®S<0x@”/;додає /початок негативних років у Росії[-9999 .. -0001] . Я здогадуюсь, що це можна скоротити. У кінцевому підсумку я включив це в попередній оператор do ( ¡) і врятував 7 байт, тому що тоді мені не потрібно було тестувати мінус два рази.

¡Рядок 4 використовує дуже багато, і я думаю, що їх можна стиснути за допомогою? натомість, але я не знаю, як змусити їх працювати. Я взявся ?за роботу і врятував кілька байт.

Джеймс Холдернес зазначив, що моє перше подання не сприймало років з 30 цифрами правильно. Виявилося, що помилка була на будь-який рік, який потребував Zу базовій приставці 26. Виявляється, я не міг використовувати, тому що коли ви перетворюєте 26 в базову 26, це дає вам [1,0]замість 26(duh). Натомість я використав замовлені пари із заміною. Я не думаю, що для цього є атом, але якщо є, я можу зберегти кілька байт. Виправлення цього в кінцевому рахунку коштувало мені ~ 40 байт. Безумовно, моя найдовша програма Jelly досі. Редагувати : Знайдено коротший спосіб зробити декартовий продукт. Я зрозумів, що не впевнений, що останній працював над префіксами з більш ніж двома літерами, але новий спосіб працює.

Вибачте за те, що я багато разів редагував цю публікацію, я просто продовжую розкривати способи її скорочення.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.