Прыжок за високосные секунды!


28

Поскольку сегодня отмечается 26-й прыжок в секунду , ваша задача будет выводить дату и время каждой прыжковой секунды в GMT или UTC, которая произошла до сих пор, а также дату, которая произошла сегодня.

вход

Там нет ввода.

Выход

1972-06-30 23:59:60
1972-12-31 23:59:60
1973-12-31 23:59:60
1974-12-31 23:59:60
1975-12-31 23:59:60
1976-12-31 23:59:60
1977-12-31 23:59:60
1978-12-31 23:59:60
1979-12-31 23:59:60
1981-06-30 23:59:60
1982-06-30 23:59:60
1983-06-30 23:59:60
1985-06-30 23:59:60
1987-12-31 23:59:60
1989-12-31 23:59:60
1990-12-31 23:59:60
1992-06-30 23:59:60
1993-06-30 23:59:60
1994-06-30 23:59:60
1995-12-31 23:59:60
1997-06-30 23:59:60
1998-12-31 23:59:60
2005-12-31 23:59:60
2008-12-31 23:59:60
2012-06-30 23:59:60
2015-06-30 23:59:60

правила

Поскольку я сомневаюсь, что есть много встроенных модулей, которые позволяют високосные секунды, я позволю им.

Стандартные лазейки запрещены.

Самый короткий код выигрывает.

Формат даты должен содержать месяц с нулем и год из 4 цифр, а также военное время и пробел, отделяющий время от даты. Ставить UTCв конце необязательно. Ваш выбор тире или косой черты.

РЕДАКТИРОВАТЬ: Да, как и предполагалось, это стало проблемой кодирования. Если бы только кодирование могло решить проблему високосного второго, ... тогда весь наш код был бы намного более практичным. Может быть, нам нужны идеи для более забавных задач с практическим использованием?


Требуется ли для выходных данных иметь такое точное распределение, или оно может иметь какое-либо распределение, если есть 26 дат?
Исмаэль Мигель

2
@IsmaelMiguel Они должны быть в таком порядке.
mbomb007

Не по теме, но, глядя на список, я задаюсь вопросом, почему нам нужно меньше високосных секунд в наши дни, чем в прошлом веке.
Мистер Листер

@MrLister Просмотр связанной статьи в Википедии. Я думаю, что это связано с изменением скорости вращения Земли.
mbomb007

Ответы:


25

CJam, 72 70 69 64 байта

26,"~g¼K&Béx¸¦­Ø"240bFbf{<1b2md\1972+'-@6X$4*-'-Z3$" 23:59:60"N}

Попробуйте онлайн в интерпретаторе CJam .

идея

Мы начинаем с кодирования каждой високосной секунды как 2 * (Y - 1972) + D , где D равно 1, если это происходит в декабре, и 0 в противном случае.

Массив всех закодированных високосных секунд:

[0 1 3 5 7 9 11 13 15 18 20 22 26 31 35 37 40 42 44 47 50 53 67 73 80 86]

Давайте назовем этот массив L .

Поскольку массив находится в порядке возрастания, мы можем хранить последовательные различия вместо фактических чисел:

[1 2 2 2 2 2 2 2 3 2 2 4 5 4 2 3 2 2 3 3 3 14 6 7 6]

Обрабатывая этот массив как цифры от базового числа 15, мы получаем целое число

19238985373462115979359619336

какие цифры в базе 240 (приведенные к символам)

~g¼K&Béx¸¦­Ø

Код

26,             e# Push I := [0 ... 25].
"~g¼K&Béx¸¦­Ø"   e# Push the string from above.
240bFb          e# Convert from base 250 to base 15 to push L.
f{              e# For each J in I:
                e#   Push L.
  <             e#   Replace L with L[:J].
  1b            e#   Push the sum S of the integers in L[:J].
  2md           e#   Push (S / 2) and (S % 2).
  \1972+        e#   Add 1972 to (S / 2).
  '-@           e#   Push '-' and rotate (S % 2) on top.
  6X$4*-        e#   Compute (6 - 4 * (S % 2)).
  '-Z           e#   Push '-' and 3.
  3$            e#   Push a copy of (S % 2).
  " 23:59:60"   e#   Push that string.
  N             e#   Push a linefeed.
}

28
Это чувство, когда у вас есть встроенная программа, которая почти полностью решает проблему, и все же ручное решение в CJam короче.
Алекс А.

9
@AlexA. В Mathematica есть некоторые встроенные модули, которые я могу переопределить в меньшем количестве байтов в Mathematica .
Мартин Эндер

@ MartinBüttner: Brutal.
Алекс А.

35

R, 78 75 байтов

Вы говорите, встроенные модули? Что ж...

message(paste(as.Date(.leap.seconds)-1,"23:59:60\n"),"2015-06-30 23:59:60")

R имеет автоматическую переменную, .leap.secondsкоторая содержит дату и время каждой вставки високосной секунды, указанной в местном времени системы. Начиная с версии R 3.2.0, это не относится к сегодняшнему дню, поэтому я добавил это вручную.

Ungolfed + объяснение:

# Convert the datetime values to UTC dates. These will be a day past the
# expected output, so we can subtract 1 to get what we want.
dates <- as.Date(.leap.second) - 1

# Paste the UTC time and a newline onto the end of each date
datetimes <- paste(dates, "23:59:60\n")

# Print each time, including today, on its own line
message(datetimes, "2015-06-30 23:59:60")

Вы можете попробовать это онлайн !


если вы можете присвоить «23:59:60» переменной, вы можете сохранить некоторые символы
не то, что Чарльз

1
@NotthatCharles: я думал об этом, но метод объединения строк в R не достаточно лаконичен, чтобы сократить сегодняшнюю дату и время. Спасибо за вклад, хотя!
Алекс А.

24

HTML, 594 байта

1972-06-30 23:59:60<br>1972-12-31 23:59:60<br>1973-12-31 23:59:60<br>1974-12-31 23:59:60<br>1975-12-31 23:59:60<br>1976-12-31 23:59:60<br>1977-12-31 23:59:60<br>1978-12-31 23:59:60<br>1979-12-31 23:59:60<br>1981-06-30 23:59:60<br>1982-06-30 23:59:60<br>1983-06-30 23:59:60<br>1985-06-30 23:59:60<br>1987-12-31 23:59:60<br>1989-12-31 23:59:60<br>1990-12-31 23:59:60<br>1992-06-30 23:59:60<br>1993-06-30 23:59:60<br>1994-06-30 23:59:60<br>1995-12-31 23:59:60<br>1997-06-30 23:59:60<br>1998-12-31 23:59:60<br>2005-12-31 23:59:60<br>2008-12-31 23:59:60<br>2012-06-30 23:59:60<br>2015-06-30 23:59:60

¯ \ _ (ツ) _ / ¯


6
@ Vioz- Этот вопрос помечен колмогоровской сложностью, и поэтому это совершенно законный ответ. Хотя вряд ли победит ...
Цифровая травма

10
@mlepage Это одна из "стандартных лазеек".
Джейкоб Райл

4
@Voitcus сохранить в файл, открыть в браузере. Это workingHTML-код
edc65

9
@ AntonyD'Andrea Да, и что? Недействительность не требуется в code golfвызовах.
edc65

5
@anatolyg ТЫ не веселее для [kolmogorov-сложно]
vijrox

11

C 160 146 141 140 байт

Первый раз, не уверен, что такое "стандартные лазейки". У меня есть предупреждения printf, конечно.

160 байтов:

Первоначальная идея заключается в кодировании високосных секунд, используя два бита в год: один для июня и один для декабря. Кодирование потребляется по одному биту за счет внутреннего цикла while. Без 128-битного целого числа необходим внешний цикл while. Остальное все бухгалтерия и математика. :-)

int main(){long long X=0x2495288454AAAB,Y=1972,Z=1;while(Y<2000){while(X){if(X&1)printf("%d-%02d-%d 23:59:60\n",Y,6*(2-Z),31-Z);Y+=Z^=1;X>>=1;}X=0x104082000;}}

141 байт:

Применение предложенных советов уменьшает его до 146 байт. Затем я нашел способ упростить внешнее условие while (от Y <2000 до просто Z), уменьшив его до 141 байта. Так близко к твиту!

main(Z){long long X=0x2495288454AAAB,Y=1972;while(Z){while(X)X&1?printf("%d-%02d-%d 23:59:60\n",Y,12-6*Z,31-Z):1,Y+=Z^=1,X/=2;X=4362608640;}}

140 байт:

Я заметил, что черту в дате можно устранить, сделав день отрицательным. Не может сделать это и с месяцем из-за нуля в июне. Но, по крайней мере, это сейчас вписывается в твит!

main(Z){long long X=0x2495288454AAAB,Y=1972;while(Z){while(X)X&1?printf("%d-%02d%d 23:59:60\n",Y,12-6*Z,Z-31):1,Y+=Z^=1,X/=2;X=4362608640;}}

Красивая версия:

main(Z) {
    long long X = 0x2495288454AAAB, Y = 1972;
    while (Z) {
        while (X)
            X&1 ? printf("%d-%02d%d 23:59:60\n", Y, 12-6*Z, Z-31) : 1,
            Y += Z ^= 1,
            X /= 2;
        X = 4362608640;
    }
}

Бонусная версия:

Я исключил внешний цикл, сдвигая одно 64-битное целое число в другое, но оно составляет 150 байтов из-за довольно длинного «unsigned long long»; если бы я мог использовать что-то вроде «uint64», это было бы 138 байтов.

main(Z) {
    unsigned long long Y = 1972, X = 0x2495288454AAAB, W = 8520720;
    while (X)
        X&1 ? printf("%d-%02d-%d 23:59:60\n", Y, 12-6*Z, 31-Z) : 1,
        Y += Z^= 1,
        X = X/2 | (W>>=1)<<63;
}

4
Добро пожаловать в PPCG. «Стандартные лазейки» относятся к этому сообщению , но обычно это просто означает «используйте здравый смысл и не обманывайте». :)
Мартин Эндер

1
Я думаю, что использование forцикла сэкономит несколько байтов. Кстати, int main()-> main(). Вы можете найти это очень полезным.
Спикатрикс

Кроме того: X>>=1то же самое X/=2, 6*(2-Z)то же самое 12-6*Z, и 4362608640на один байт короче, чем 0x104082000. intВ передней части не main()является необходимым, и если вы меняете main()в main(Z)то вы можете удалить объявление Z=1.
брезгливый оссифраж

Действительно хорошее решение - еще одна вещь, о которой нужно подумать - вы можете изменить, if(X&1)printf(...);с помощью X&1?printf(...):1;чего экономит 1 байт
euanjt

и вместо того, чтобы while(X){...}использовать запятые, чтобы вы могли удалить скобки, while(X)X&1?printf("%d-%02d-%d 23:59:60\n",Y,6*(2-Z),31-Z):1,Y+=Z^=1,X>>=1;сохраняя еще 2 байта
euanjt

9

Python 3, 91

Использует кодировку и форматирование строки Sp3000 , но сохраняет значения в 3-байтовом объекте Python, а не в магическом числе.

for n in b'()+-/1357:<>BGKMPRTWZ]kqx~':print('%d-%02d-3%d 23:59:60'%(1952+n/2,n%2*6+6,n%2))

Для кодирования требуется только 86 из 256 возможных значений байтов, поэтому для удобства просмотра используется диапазон печатаемых символов.


7

Brainfuck, 806

++++++++[>++++++>+++++++>+++++++>++++++>++++++>++++++>+++++++>++++++>++++++>++++++>++++>++++++>++++++>+++++++>+++++++>+++++++>+++++++>+++++++>++++++>+<<<<<<<<<<<<<<<<<<<<-]>+>+>->++>--->>-->--->+++>>>++>+++>++>--->+>++>-->>++[<]>[.>]<[<]>>>>>>+>---->>>+[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>+>-------->>->++++>>>-[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>++[<]>[.>]<[<]>>>>++>>+>---->>>+[<]>[.>]<[<]>>>>++[<]>[.>]<[<]>>>+>---------[<]>[.>]<[<]>>>>++>>->++++>>>-[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>+>>+>---->>>+[<]>[.>]<[<]>>>>++>>->++++>>>-[<]>[.>]<[<]>>>>+>>+>---->>>+[<]>[.>]<[<]>+>--------->--------->---[<]>[.>]<[<]>>>>+++[<]>[.>]<[<]>>>+>------>>->++++>>>-[<]>[.>]<[<]>>>>+++[<]>[.>]

Вы можете запустить его на этом онлайн-переводчике.


6

Python 2, 111 104 байта

n=0x6697f252225354422533333330;y=1972
while n:print'%d-%02d-3%d 23:59:60'%(y,n%2*6+6,n%2);y+=n/2%8;n/=16

Базовое кодирование и более базовое кодирование.


5

GNU sed + дата: 112

Обычные дистрибутивы Linux также имеют встроенные дополнительные секунды. Использование GNU sed и date:

sed -n 's/^\([0-9]\+\).*/1899-12-31 \1sec/p' /usr/share/zoneinfo/leap-seconds.list|date -f- +"%Y-%m-%d 23:59:60"

GNU sed + дата: 90

Сохранение нескольких символов путем обрезания пути:

sed -n 's/^\([0-9]\+\).*/1899-12-31 \1sec/p' /u*/s*/z*/leap*|date -f- +'%Y-%m-%d 23:59:60'

GNU sed + дата настроена Тоби Спейт: 84

Глубокая игра в гольф предлагается в комментариях:

sed -nr 's/^([0-9]+).*/date -d "1899-12-31 \1sec" "+%F 23:59:60"/ep' /u*/s*/z*/leap*

Спасибо, что научили меня, где искать данные о високосных секундах. К сожалению, мой date(GNU 8.23) отображает их как первую секунду следующей минуты. Что вы используете, что понимает 60-секундную минуту?
Тоби Спейт

С GNU Coreutils, я получил его до 76, бритье байт с -rфлагом, подставив dateв с s///eмодификатором, и замена %Y-%m-%dс %Fв date: TZ = UTCsed -nr 's/^([0-9]+).*/date -d "1900-1-1 \1sec" "+%F %T"/ep' /u*/s*/z*/leap*
Toby Speight

Я знал, что что-то пропустил. Кажется, что нет способа указать это вручную, по крайней мере, не хуже, чем большинство других решений. Давайте посмотрим, придет ли кто-нибудь с какой-нибудь библиотекой дат для правильного вычисления чисел, поддерживающих эти секунды.
Йенс Эрат

Я получил там, используя 1899-12-31 \1secдля даты, и жесткое кодирование 23:59:60как время:sed -nr 's/^([0-9]+).*/date -d "1899-12-31 \1sec" "+%F 23:59:60"/ep' /u*/s*/z*/leap*
Тоби Спейт

3

JavaScript ( ES6 ) 125

Новая строка внутри `` значима и считается.

Чтобы проверить, запустите приведенный ниже фрагмент (это EcmaScript 6, только Firefox)

alert([..."09:;=DEFIX[01234567?ABGJQS"].map((c,i)=>c.charCodeAt()+1924+(i>10?'-12-31':'-06-30')+' 23:59:60').sort().join`
`)


2

PHP, 198 байт

foreach([.5,1,2,3,4,5,6,7,8,9.5,10.5,11.5,13.5,16,18,19,20.5,21.5,22.5,24,25.5,27,34,37,40.5,43.5] as$d){$h=(int)$d-ceil($d);echo date("Y-m-d 23:59:60",mktime(0,0,0,-6*$h,31+$h,(int)$d+1972))."\n";}

К сожалению, я не знаю, смогу ли я вставить \nв функцию даты. Если так, то это на 3 байта меньше из-за ."".


Вы можете раздеть оба (int)и удалить пробелы. Date выдает ошибку, если часовой пояс по умолчанию не установлен, отключите его с помощью @. 187 байт:foreach([.5,1,2,3,4,5,6,7,8,9.5,10.5,11.5,13.5,16,18,19,20.5,21.5,22.5,24,25.5,27,34,37,40.5,43.5]as$d){$h=$d-ceil($d);echo@date("Y-m-d 23:59:60",mktime(0,0,0,-6*$h,31+$h,$d+1972))."\n";}
Octfx

2

8086 машинный код + DOS, 92 байта

Hexdump кода:

BE 3A 01 B1 57 D1 E0 75 03 AD EB F9 72 09 50 BA
47 01 B4 09 CD 21 58 BB 50 01 81 77 FC 01 04 80
37 01 80 3F 31 74 10 83 EB 05 4B FE 07 80 3F 3A
75 05 C6 07 30 EB F3 E2 CC C3 AA 2A 77 B5 6A DD
DF B6 BE FF 7D BF 31 39 37 32 2D 30 36 2D 33 30
20 32 33 3A 35 39 3A 36 30 0D 0A 24

Для запуска запишите 92 байта в com-файл и запустите его под 32-битной Windows или DOSBox.

Код использует растровое изображение с 87 битами, по одному на полгода. Биты разбиты на группы по 16, начиная с MSB.

Расшифровка растрового изображения:

                 ; when the program starts, ax=0 (tested on DOSBox)
myloop:
    shl ax, 1    ; shift the MSB left into the carry flag
    jnz mywork   ; if some bits are left in the register, work normally
    lodsw        ; if all bits were shifted out, load the next 16 bits
    jmp myloop   ; and check the MSB again

Из-за структуры кода некоторые биты теряются при декодировании, поэтому мне пришлось их повторять. Это повторение не раздувает растровое изображение, потому что я все равно должен был дополнить 87 бит до 96 бит.

После распечатки (или не распечатывания) високосной секунды код увеличивает дату на полгода, используя манипуляции с кодами ASCII выходного сообщения.

Исходный код (может быть собран с tasm):

    mov si, offset mydata
    mov cl, 57h ; number of iterations

myloop:
    shl ax, 1   ; shift the MSB left into the carry flag
    jnz mywork  ; if some bits are left in the register, work normally
    lodsw       ; if all bits were shifted out, load the next 16 bits
    jmp myloop  ; and check the MSB again
mywork:
    jc myinc_date ; shifted bit 1? - skip printing the message

    push ax
    mov dx, offset mymsg
    mov ah, 9
    int 21h     ; print the message
    pop ax

myinc_date:
    mov bx, offset mymsg + 9 ; pointer to the middle of the message
    xor word ptr [bx - 4], 401h ; change month 06<->12
    xor byte ptr [bx], 1 ; change day 30<->31
    cmp byte ptr [bx], '1'
    je myloop_end ; if 31 December, no need to increase the year
    sub bx, 5 ; pointer beyond the last digit of the year

myinc_year:
    dec bx
    inc byte ptr [bx] ; increase the digit
    cmp byte ptr [bx], '0' + 10
    jne myloop_end ; if the digit was less than 9, done
    mov byte ptr [bx], '0' ; set the digit to 0
    jmp myinc_year ; continue increasing other digits

myloop_end:
    loop myloop
    ret ; terminate the program

; In the following bitmap, the spaces before some LSBs
; show that the least significant 1-bit and all
; following 0-bits are lost during decoding.
mydata:
    dw 02aaah ; 00101010101010     10
    dw 0b577h ; 101101010111011    1
    dw 0dd6ah ; 11011101011010     10
    dw 0b6dfh ; 101101101101111    1
    dw 0ffbeh ; 11111111101111     10
    dw 0bf7dh ; 101111110111110    1

mymsg:
    db '1972-06-30 23:59:60',13,10,'$'

Я хотел бы проверить это, но я не могу найти ни одного редактора, который позволил бы вам вставить hex и сохранить его в двоичный файл.
Мистер Листер

@MrLister любой обычный шестнадцатеричный редактор должен сделать это за вас.
Доктор

1

Pyth - 88 84 байта

Обращенные к полукоксу для сжатия данных и сохраняет в 06-30сравнении с 12-31данными , как двоичное число.

jbm++-2047ed?"-06-30"hd"-12-31"" 23:59:60"C,j33678243 2CM"KKJIHGFEDBA@><:9765421*'# 

(там есть место в конце)

Попробуйте здесь онлайн .


1

Python 2, 123 121 116 114 111

Мне удалось сделать его довольно коротким, но я не уверен, насколько он может быть короче. Я пытался использовать exec, но форматирование становится слишком дорогим.

Я использовал основную 16 кодировку таблицы со связанной страницы Википедии.

Изменить: Использование шестнадцатеричного кодирования короче, чем база 36 (см. Версию с меньшим количеством гольфа)

Попробуй здесь

n=0x410208002495288454aaab
for i in range(88):
    if n%2:print"%d-%02d-3%d 23:59:60"%(1972+i/2,i%2*6+6,i%2)
    n/=2

Менее гольф:

s=bin(int('WELD24ZDGIMBWWLFM',36))[2:]
for i in range(44):
    t,s=int(s[0]),s[1:]
    if t:print"%d-06-30 23:59:60"%(i+1972)
    t,s=int(s[0]),s[1:]
    if t:print"%d-12-31 23:59:60"%(i+1972)

1

C 155 149 147 байт

Вот еще один подход в C, использующий строки и кодирование длин серий. Не так кратко, как мое другое решение C, но, возможно, его можно улучшить?

155 байт:

Использование строки для хранения месяца / дня.

main(Y){Y=1972;char*M="06-3012-31",*B="#@DGCDF7D3daTdS#!",b,c;while(b=*B++-33){c=b>>1&7;while(c--)printf("%d-%.5s 23:59:60\n",Y++,M+b%2*5);Y+=(b>>4&7)-1;}}

149 байт:

Исключение строки месяца / дня.

main(Y){Y=1972;char*B="#@DGCDF7D3daTdS#!",b,c;while(b=*B++-33){c=b>>1&7;while(c--)printf("%d-%02d-%d 23:59:60\n",Y++,6+b%2*6,30+b%2);Y+=(b>>4&7)-1;}}

147 байт:

Устранение инициализации года.

main(Y){char*B="#@DGCDF7D3daTdS#!",b,c;while(b=*B++-33){c=b>>1&7;while(c--)printf("%d-%02d-%d 23:59:60\n",1971+Y++,6+b%2*6,30+b%2);Y+=(b>>4&7)-1;}}

144 байта:

Если бы я перекодировал буфер, чтобы счетчик пропусков был применен до (а не после) выполнения, я мог бы переупорядочить операторы во внешнем цикле while, использовать оператор запятой и удалить скобки, сохранив 2 байта.

Я могу сохранить еще один байт, сделав день отрицательным (как в моем другом решении).

Милая:

main(Y) {
    char *B = "#@DGCDF7D3daTdS#!", // buffer of bytes encoding runs
         b, // current byte
         c; // current count
    while (b = *B++-33) { // get byte
        c = b>>1&7; // get count
        while (c--) printf("%d-%02d-%d 23:59:60\n", 1971+Y++, 6+b%2*6, 30+b%2); // run
        Y += (b>>4&7)-1; // skip years
    }
}

Объяснение:

Прогоны кодируются в байтах. Каждый байт имеет один бит, чтобы сказать, будет ли это июнь или декабрь, 3 бита для счетчика длины, 3 бита для счетчика пропусков и 1 неиспользованный старший бит.

Число пропусков - это количество лет, которое нужно пропустить после пробега; он смещен на -1, чтобы учесть две високосные секунды в 1972 году. Длина - это сколько лет подряд; это, вероятно, может быть смещено на +1, но это не в настоящее время.

Таким образом, под байтом подразумевается: «ДЛИВАЙТЕ годы високосных лет в июне (или ДЕКАБРЕ), затем пропустите SKIP-1 года», прежде чем переходить к следующему байту.

Байты смещены на 33, чтобы сделать их читаемыми и избежать сложного кодирования.

Это означает, что хотя у нас достаточно пропущенных битов для покрытия 1998-2005 гг., Мы находимся за пределами диапазона ASCII, поэтому у нас есть дополнительный прогон нулевой длины. Кроме того, 1979 год появляется сам по себе, потому что длина 1972-1979 годов слишком велика.

В байтах достаточно битов, поэтому в конечном итоге эти проблемы могут быть исправлены.


1

q / kdb +, 95 94 93 байта

asc 1_" "0:([]raze("DEFGHIJKSUV[^eh";"DMNOQXYZ]lo"){("d"$"m"$-12*95-6h$x)-y}'1 185;`23:59:60)

объяснение

Для каждого года +1 кодируйте годы с 1905 года как символ ASCII, например:

1972 -> 1973 -> 68 -> D

6h$xвитки "D"назад к 68. Поскольку qдата начала эпохи 2000.01.01, мы вычитаем 95и выполняем преобразование целых чисел в дату "d"$"m"$-12*95-6h$x.

Причина, по которой мы + 1 выше, состоит в том, чтобы вычесть количество дней с начала следующего года, чтобы получить фактический год 31 декабря или 30 июня, а именно 1 или 185 дней. Таким образом, "DEFGHIJKSUV[^eh"представляет годы с високосной секундой в декабре, а "DMNOQXYZ]lo"для лет - в июне. Спаривание-вычитание производится с помощью (a;b){x-y}'(c;d), где aи bв годы , которые будут вычитают cи dколичество дней соответственно.

" "0:([]...)подготавливает результаты к правильному форматированию с небольшим предупреждением о том, что будет сгенерирован заголовок столбца. 1_отбрасывает этот заголовок и, наконец, применяется, ascчтобы получить правильный порядок.

редактировать : «заново» вычитать 95 лет вместо 100 (сохраняя 1 символ).

edit 2 : изменение порядка расположения операндов внутри функции преобразования целых чисел в дату.


1

Питон, 204 201

e,g,h=0,1972,0
for i in range(1,27):e,g,h={2:1,9:2,10:1,12:2,15:1,16:2,17:1,20:2,21:1,22:7,23:3,24:4,25:3}.get(i,e),g+e,(h,1-h)[i in[2,10,14,17,20,21,22,25]];print`g`+("-06-30","-12-31")[h]+" 23:59:60"

Вы можете играть с ним на repl.it .

Изменить: тщательно избили! Ответы на сжатие поразительно короткие.


Удивительно, но мой PHP-ответчик короче, используя похожий алгоритм. Я всегда ожидал, что Python будет более компактным. Может быть, вы могли бы еще немного поиграть в гольф?
Voitcus

Я взгляну. Я думаю, что лучший маршрут - это сжатие, а другие уже сделали это
sudo rm -rf slash

0

PHP, 164 байта

foreach([.5,1,2,3,4,5,6,7,8,9.5,10.5,11.5,13.5,16,18,19,20.5,21.5,22.5,24,25.5,27,34,37,40.5,43.5]as$d){echo(ceil($d)+1971).($d%2?'-12-31':'-06-30')." 23:59:60\n";}

Это всего лишь несколько модификаций идеи @ Voitcus


0

Питон, 221 217

def d(x):
 q=x%10
 if x%2==0:
  p,r=q/2,"06-30"
 else:
  p,r=(q-1)/2,"12-31"
 return"%d%d-%s 23:59:60"%(p+197,x/10,r)
for x in [20,21,31,41,51,61,71,81,91,12,22,32,52,73,93,5,24,34,44,55,74,85,57,87,28,58]:print(d(x))

Некоторые идеи

По сути, d(x)распаковывает вектор из 3 целых чисел из одного двузначного целого числа. d(x)построен как обратная функция (в течение 26 секунд високосных секунд) c(v), которая, в свою очередь, представляет собой функцию сжатия, которая превращает 3-х ряд, такой как (1998, 12, 31), в число, подобное 85. Для получения списка [20 , 21 ... 28,58] Я разработал другой алгоритм, чтобы убедиться, что функция сжатия является биективной по области. То есть я убедился, что следующая программа не производит дубликаты, и использовал ее вывод в качестве списка программы выше.

dates = [(1972,06,30),
    (1972,12,31),
    (1973,12,31),
    (1974,12,31),
    (1975,12,31),
    (1976,12,31),
    (1977,12,31),
    (1978,12,31),
    (1979,12,31),
    (1981,06,30),
    (1982,06,30),
    (1983,06,30),
    (1985,06,30),
    (1987,12,31),
    (1989,12,31),
    (1990,12,31),
    (1992,06,30),
    (1993,06,30),
    (1994,06,30),
    (1995,12,31),
    (1997,06,30),
    (1998,12,31),
    (2005,12,31),
    (2008,12,31),
    (2012,06,30),
    (2015,06,30)]

def c(v):
    x = (v[0] % 10) * 10
    x += v[2] % 30
    x += 2 * (int(v[0] / 10) - 197)
    return x

for v in dates:
    print(c(v))

Функция сжатия c(v)была разработана, чтобы быть биективной, используя очень простую схему. Давайте возьмем в качестве примера (1998,12,31).

  • Выражение (v [0]% 10) * 10 выбирает единицы года (например, 1 9 9 8 -> 8) и делает его десятой цифрой выходного значения (теперь x = 80).
  • Есть только две комбинации месяца и дня, в которых происходит високосная секунда, поэтому я решил использовать компонент дня, чтобы различать случай 06,30 и случай 12,31. Выражение v [2]% 30 равно 0, если день 30, и 1, если день 31. В нашем примере мы добавляем 1 к x (следовательно, теперь x = 81).
  • Наконец, я заметил, что эта головоломка включает только 5 десятилетий; следовательно, если я сопоставлю первое десятилетие (семидесятые) с 0, а последнее десятилетие (2010-е) с 4, я смогу делать классные вещи. Более конкретно, если вместо сопоставления с 0,1,2,3,4 я отображаю на 0,2,4,6,8, я могу добавить это значение к единицам x, что в силу предыдущего правила равно либо 0, либо 1. Итак, в конце мы имеем, что и этот последний шаг не нарушает биекцию, и мы получаем, что единицы измерения в случае 06,30 равны 0,2,4,6,8, а единицы измерения 12,31 дела - это одно из 1,3,5,7,9. Следовательно, биекция очевидна. В нашем примере 1998 год находится в третьем десятилетии (70-е годы -> 0, 80-е годы -> 1, 90-е годы -> 2), поэтому мы добавляем 2 * 2 = 4. Таким образом, мы получаем х = 85.

Я написал программу, чтобы убедиться, что это правда, а затем я определил d(x)как обратное c(v). В нашем примере c ((1998,12,31)) равно 85, а d (85) печатается правильно 1998-12-31 23:59:60.


1
Удалить q=x%10и заменить qс x%10везде. Это короче. Я также дам полезное описание некоторых дополнительных игр в гольф на вашей программе здесь . Я рекомендую просмотреть страницу Советы по игре в гольф на Python .
mbomb007

Это код-гольф , поэтому вы должны попытаться сократить длину кода любым возможным способом.
mbomb007

-1

gzip, 114 байт

HexDump:

1f8b080853f9975502006c006dd04b0a80300c84e1bde01dbc40218fa6697aff8309e2a6fa6f3f86cc10adb426a3b95ce62b6a0d398f07d59aeb8e4ed80983701026e1242cc0a9307e1aa11306615211b59710527b3961270cba9994fc7fc944829092faeedc313e7803993cfafb20020000

Создайте файл с байтами, описанными выше.

Распакуйте с помощью gunzip или другой программы распаковки, чтобы получить новый файл с именем «l». Этот файл содержит желаемый результат.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.