Стрибок за стрибкові секунди!


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

Правила

Оскільки я сумніваюся, що існує багато вбудованих програм, які дозволяють виконувати високосні секунди, я дозволю їх.

Стандартні лазівки заборонені.

Найкоротший код виграє.

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

EDIT: Так, як і передбачалося, це стало проблемою кодування. Якби тільки кодування могло вирішити проблему другого стрибка, ... тоді весь наш код був би набагато практичнішим. Може, нам потрібні кілька ідей для більш веселих викликів із практичним використанням?


Чи потрібен вихід для того, щоб мати точний розподіл, або він може мати будь-який розподіл до тих пір, поки є 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: Жорстокий.
Олексій А.

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, це сьогодні не включає, тому я додав це вручну.

Недоліки + пояснення:

# 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- Це питання позначено як колгогоров-складність, і це ідеально правова відповідь. Мабуть, не виграєш хоч ...
Digital Trauma

10
@mlepage Це одна із "стандартних лазівки".
Яків Райхле

4
@Voitcus зберегти у файлі, відкрити у браузері. Це workingкод html
edc65

9
@ AntonyD'Andrea Так, і що? Дійсність не вимагається у code golfвикликах.
edc65

5
@anatolyg ВИ не веселі для [колгомогоров-складності]
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 байт. Тоді я знайшов спосіб спростити зовнішній стан при цьому (від 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 байт, через досить довге "неподписане довге довге"; якби я міг використати щось на зразок "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(). Ви могли б знайти це дуже корисно.
Spikatrix

Також: 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

Пітон 3, 91

Використовує кодування та форматування рядків Sp3000 , але зберігає значення в об'єкті Python 3 байт, а не магічне число.

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 теж є вбудовані високосні секунди. Використання sed і дати GNU:

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 + дата настроєна Toby Speight: 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-секундну хвилину?
Toby Speight

З 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*
Toby Speight

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)і видалити пробіл. Дата видає помилку, якщо часовий пояс за замовчуванням не встановлений, замовкніть його @. 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 байти

Шестнадцятковий код:

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

Я хотів би перевірити це, але я не можу ніде знайти жодного редактора, який дозволяє вставити шістнадцятковий файл і зберегти його у бінарний файл.
Містер Лістер

@MrLister будь-який звичайний шестигранний редактор повинен зробити це за вас.
TheDoctor

1

Pyth - 88 84 байт

Перетворює в char для стиснення даних і зберігає 06-30порівняно з 12-31даними у вигляді двійкового числа.

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

(в кінці є пробіл)

Спробуйте це онлайн .


1

Пітон 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 символу).

редагування 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) і робить його десятою цифрою результату (зараз х = 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. Таким чином отримуємо x = 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.