RFC 2550 - это сатирическое предложение (опубликовано 1 апреля 1999 г.) для представления меток времени в формате ASCII с эффективным использованием пространства, которое может поддерживать любую дату (даже те, которые предшествуют началу вселенной и те, которые прошли после предсказанного конца вселенной). Алгоритм вычисления временной метки, соответствующей RFC 2550, следующий (примечание: все диапазоны включают начало, но исключают конец - от 0 до 10000 означают все n
где 0 <= n < 10000
):
- Формат года
- Годы от 0 до 10000: четырехзначное десятичное число, дополненное нулями.
- Годы от 10 000 до 100 000: пятизначное десятичное число с префиксом символа А.
- Годы от 100 000 до 10 30 : десятичное число для года с префиксом буквы ASCII в верхнем регистре, индекс которого в английском алфавите равен количеству цифр в десятичном году, минус 5 (B для 6-значных лет, C для 7 лет и т. д.).
- Годы с 10 30 по 10 56 : тот же формат, что и с 10 000 до 10 30 , начиная буквы с буквы A и дополнительно добавляя
^
к строке символ вставки ( ) (таким образом, год 10 30 обозначен^A1000000000000000000000000000000
, а год 10 31 представлен по^B10000000000000000000000000000000
). - Годы с 10 56 по 10 732 : году предшествуют две строчные буквы и две заглавные буквы ASCII. Заглавные буквы образуют число из 26 цифр, обозначающее количество цифр в году, минус 57.
- Года 10 732 и далее: тот же формат 10 56 10 732 используются, расширяя его путем добавления дополнительной каретки и прописными букв , когда это необходимо.
- Годы до н.э. (до года 0): вычислите строку года абсолютного значения года. Затем замените все буквы их дополнением к основанию-26 (A <-> Z, B <-> Y и т. Д.), Замените все цифры их дополнением к основанию-10 (0 <-> 9, 1 <-> 8, и т. д.) и замените каретки восклицательными знаками (
!
). Если строка года состоит из 4 цифр или менее (то есть от -1 до -10 000), добавьте косую черту (/
). Если строка года не имеет префикс перед косой чертой или восклицательный знак, добавьте звездочку (*
).
- Месяцы, дни, часы, минуты и секунды : поскольку эти значения не более 2 цифр, они просто добавляются справа от строки года, в порядке убывания значимости, с добавлением нуля слева при необходимости для формирования 2-значные строки.
- Дополнительная точность : если требуется дополнительная точность (в виде миллисекунд, микросекунд, наносекунд и т. Д.), Эти значения дополняются слева от нуля до 3 цифр (поскольку каждое значение имеет
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
?Ответы:
JavaScript (ES6), 325 байт
Шокирующе долго.
источник
Befunge,
418384 байтаТрудно сказать заранее, насколько велика может быть программа Befunge, и когда я начал работать над этим, я подумал, что у нее действительно есть шанс на конкуренцию. Оказывается, я был неправ.
Попробуйте онлайн!
источник
Perl 5 ,
328, 322, 317,301 + 1 (-a
) = 302 байта.Попробуйте онлайн!
Ungolfed
источник
Java 8,
653640637623 байтаВведите как
String
-array и тип возврата как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-100000 (исключение): добавьте ведущие нули, если необходимо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;
: Добавьте год к строке результата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.).
- вы можете взять ввод в виде списка чисел и пропустить дорогостоящее разделение и преобразование.long
с 64- битными значениями являются самыми большими) в Java слишком малы для некоторых входных данных, поэтому ониString
корочеjava.math.BigInteger
. Я изменил его наString
-array, так что мне не нужно делать разбиение по точкам, что позволило сэкономить несколько байтов, так что спасибо.Excel VBA,
500486485470 байтAnonymous VBE Immediate Window Function
Функция анонимного непосредственного окна VBE, которая принимает входные данные из года
[A1]
, месяца[B1]
, дней[C1]
, часов[D1]
, минут[E1]
, секунд[F1]
и дополнительного массива с дополнительной точностью[G1:Z1]
, вычисляет временную метку RFC2550 и выводит ее в окно немедленного VBE. Использует объявленную вспомогательную функцию ниже.Вспомогательная функция
Объявленная вспомогательная функция, которая принимает входной номер и возвращает этот номер в base-26, так что
1->A
и26->Z
Должен быть помещен в публичный модуль.
использование
Должен использоваться в модуле очистки, или модуль должен быть очищен перед выполнением в качестве переменных
j
,o
иp
предполагается, что он находится в их неинициализированном состоянии по умолчанию в начале выполнения кода. Дляj
, который являетсяVariant\Integer
переменной, это значение по умолчанию равно0
и дляo
иp
, которые являютсяVariant\String
переменными, это значение по умолчанию является пустой строкой (""
).Input, массив строк, берется из
1:1
ActiveSheet, а вывод - в непосредственное окно VBE.Образец ввода / вывода
Sub
рутинная версияОбъявленная подпрограмма, которая принимает входные данные как год от
[A1]
, месяц с[B1]
, дни с[C1]
, часы с[D1]
, минуты с[E1]
, секунды с[F1]
и необязательный массив дополнительной точности с[G1:Z1]
, вычисляет временную метку RFC2550 и выводит ее в непосредственное окно VBE.использование
Ввод в диапазон
[A1:ZZ1]
может быть сделан либо вручную, путем ввода в ячейки, слева направо, по мере необходимости, либо путем назначения из непосредственного окна VBE.Следует отметить, что из-за автоматического преобразования чисел Excel в научную нотацию любые числа, длина основания которых равна 12 или превышает 12 цифр, должны быть явно вставлены в ячейку в виде текста либо путем установки ячейки в текстовую ячейку, либо добавляя литерал
'
к началу значения ячейкиОбразец ввода / вывода
Неуправляемый и объясненный
источник
Желе ,
165126 байтовПопробуйте онлайн!
Строка 4 выполняет форматирование года с помощью строк 2 и 3. Первая и последняя строка имеют дело с нулевым заполнением элементов ввода до их надлежащей длины, а затем объединяют их с форматированным годом.
_µ‘l26Ċṗ@€ØAẎị@
находит префикс базы 26 Он принимает декартову степень алфавита (ØA
) для каждого числа от 1 до ceil (log 26 (floor (log 10 (year)) - 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¤¡
).2£
ссылается на вторую ссылку,ØD,“^ *!”,ØA
которая является списком[['0' .. '9'], ['^',' ','/','*','!'], ['A' .. 'Z']]
. С форматированным годом, подобным^C125...
этой ссылке, находит индекс каждого символа в сглаженной версии, а2£
затем использует эти индексы для построения новой строки из сглаженной версии, в2£
которой каждый подсписок обращен, то есть['9' .. '0','!','*','/',' ','^','Z' .. 'A']
дает!X874...
./
сопоставляется с самим собой, потому что он имеет префикс, прежде чем все будет принято его дополнение.В итоге я включил это в предыдущую инструкцию do (L=4a®S<0x@”/;
добавляет/
к началу отрицательных лет в[-9999 .. -0001]
. Я думаю, это можно сократить.¡
) и сохранил 7 байтов, потому что тогда мне не нужно было проверять отрицательные годы дважды.ВЯ получил¡
строке 4 есть много применений, и я думаю, что их можно сжать, используя?
вместо этого, но я не уверен, как заставить их работать.?
работу и сэкономил несколько байтов.Джеймс Холдернесс отметил, что в моем первом представлении не было написано лет с правильными 30 цифрами. Оказалось, что ошибка была для любого года, который нуждался
Z
в префиксе base 26. Оказывается, я не мог использовать,ṃ
потому что когда вы конвертируете 26 в базу 26, это дает вам[1,0]
вместо26
(дух). Вместо этого я использовал заказанные пары с заменой. Я не думаю, что для этого есть атом, но если он есть, я могу сэкономить несколько байтов. Исправление этого стоило мне ~ 40 байт. Определенно моя самая длинная программа желе еще. Изменить : Нашел более короткий способ сделать декартово произведение. Я понял, что не уверен, что последний работает для префиксов с более чем двумя буквами, но новый способ работает.Извините за то, что много раз редактировал этот пост, я просто продолжаю находить способы его сокращения.
источник