Рассчитать номер дня года

13

Похоже, у нас этого еще нет, так что мы идем:

Соревнование

Напишите программу или функцию, которая принимает в качестве даты дату и выводит номер дня года. Вы не можете использовать любые встроенные функции для этого!

правила

  • Как обычно, вы можете написать полную программу или функцию.
  • Формат ввода зависит от вас, но он должен содержать год, месяц и день. Уточните, какое решение использует ваше решение!
  • Постройки, связанные с датой, запрещены! Вы должны сделать работу самостоятельно. Встроенные функции, которые не связаны с операциями с датами, в порядке.
  • Основой для исчисления является григорианский календарь.
  • Вы должны учитывать високосные годы.
  • Вам нужно обрабатывать только годы в диапазоне [1, 9999]
  • Стандартные лазейки запрещены.
  • Побеждает меньшее количество байтов!

Testcases

Формат ввода здесь - ГГГГ / ММ / ДД

2016/07/05 -> 187
2000/03/28 -> 88
0666/06/06 -> 157
6789/10/11 -> 284
0004/04/04 -> 95
1337/07/13 -> 194

Удачного кодирования!

Denker
источник
Можем ли мы использовать встроенные функции в течение нескольких дней с определенной даты? Как насчет того, является ли год високосным?
lirtosiast
@Thomas Нет встроенных постов, связанных с датой. Уточню, что в конкурсе, спасибо за комментарий! :)
Денкер
@DenkerAffe Почему вы запретили все встроенные модули?
aloisdg переходит на codidact.com

Ответы:

2

Pyth, 31 байт

+s<X1+L28jC"3Ȕ"4!%|F_jQ*TT4tEE

Спасибо @Dennis и @Jakube за часть високосного года . Ввод YYYY, MM, DD в отдельных строках.

+                          add [day] to
  s <                      sum of first [month]-1 values in the list
      X                    add 1 to
        1                  the second element (January)...
        +L                 \
           28              |
           j               }   lengths of all the months
             C "3Ȕ"       | 
             4             /
        ! %                ... if the year is a leap year; that is, 4 divides...
            |F _ j         fold logical OR over reversed
                   Q       the year
                   *TT     converted to base 100
            4
      t E                 [month]-1
  E                       [day]

Тестовый пакет .

lirtosiast
источник
8

JavaScript ES6, 81 69 байт

(y,m,d)=>d+parseInt("03479cehkmpr"[--m],36)+m*28-(y%(y%25?4:16)&&m>1)

Предположим, месяцы основаны на 1, иначе я мог бы сэкономить 2 байта.

Редактировать: Сохранено 12 байт с помощью подсказки @ user81655.

Нил
источник
3

C 96 102 89 61 байт

g(y,m,d){printf("%d",m/2*31+--m/2*30-(y%(y%25?4:16)?2:1)+d);}
o79y
источник
2

Python 3, 152 148 150 байт

m,d,y=map(int,input().split());n=[0,31,(59,60)[(y%4==0 and y%100!=0)or y%400==0]]
for i in range(m):n+=[n[-1]+(31,30)[i in[1,3,6,8]]]
print(n[-4]+d)

Снимает даты в формате "МД ГГГГ".

Стив Экерт
источник
1
Вы должны использовать Python 2, если вам не нужны особые функции из Python 3. Потому что тогда вам не нужны скобки в ваших отпечатках, что позволяет вам сохранить один байт, записав ваш отпечаток какprint n[m-1]+d
Denker
В первой строке вы можете написать y% 4 == 0 и y% 100! = 0, я думаю
Mega Man
2

Python 2, 100 82 байта

Порт Python от ответа @ Neil :

lambda d,m,y:d+int("03479cehkmpr"[m-1],36)+(m-1)*28-(y%(4if y%25 else 16)and m>2)

Как и в предыдущем ответе, добавление 17 байт (всего 99 байт) даст полную программу:

print(lambda d,m,y:d+int("03479cehkmpr"[m-1],36)+(m-1)*28-(y%(4if y%25 else 16)and m>2))(*input())

Предыдущий ответ:

Как анонимная лямбда:

lambda d,m,y:d+sum(31-(n in(3,5,8,10))for n in range(m-1))-(3if y%4 or(y%400!=0and y%100==0)else 2)

Может быть преобразован в именованную лямбду за 2 байта штрафа. В качестве альтернативы, полная программа (с учетом ввода в формате D,M,Y) может быть достигнута для 117 байтов:

print(lambda d,m,y:d+sum(31-(n in(3,5,8,10))for n in range(m-1))-(3if y%4 or(y%400!=0and y%100==0)else 2))(*input())
макинтош
источник
Несколько маленьких гольфов получают 76 байтов
восстановите Монику
0

Python 3, 125 байт

print((lambda d,m,y:sum([3,not(y%400 and not y%100 or y%4),3,2,3,2,3,3,2,3,2,3][:m-1])+m*28-28+d)(*map(int,input().split())))

Еще один подход к этой проблеме. Код использует преимущества приоритетов выполнения булевой алгебры Python, и, поскольку notэто последняя операция, преобразование в булево выполняется автоматически. Когда суммирование выполнено, логическое значение обрабатывается как 1 или 0. Формат ввода - строка «YY MM DDDD». Система ввода вдохновлена аналогичной @ SteveEckert .

Другая форма как функция, 91 байт

def f(d,m,y):return sum([3,not(y%400 and not y%100 or y%4),3,2,3,2,3,3,2,3,2,3][:m])+m*28+d

В этом случае входными данными являются три целых числа, месяц между 0-11. Это будет работать в Python 2 также.

SydB
источник
0

Excel, 106 байт

=AND(C1>2,OR(MOD(A1,400)=0,AND(MOD(A1,4)=0,MOD(A1,100))))+30*B1-31+CHOOSE(B1,1,2,0,1,1,2,2,3,4,4,5,5,6)+C1

Вводит в три ячейки A1= Год, B1= Месяц, C1= День.


AND(C1>2,OR(MOD(A1,400)=0,AND(MOD(A1,4)=0,MOD(A1,100))))

1 если LeapYear, еще 0

30*B1-31+CHOOSE(B1,1,2,0,1,1,2,2,3,4,4,5,5,6)+C1

Несколько 30, ВЫБЕРИТЕ на дополнительные дни, плюс дни в месяце


Эволюция:

=IF(AND(C1>2,OR(MOD(A1,400)=0,AND(MOD(A1,4)=0,MOD(A1,100)))),1,0)+CHOOSE(B1,0,31,59,90,120,151,181,212,243,273,304,334,365)+C1
=IF(AND(C1>2,OR(MOD(A1,400)=0,AND(MOD(A1,4)=0,MOD(A1,100)))),1,0)+CHOOSE(B1-1,31,59,90,120,151,181,212,243,273,304,334,365)+C1
=IF(AND(C1>2,OR(MOD(A1,400)=0,AND(MOD(A1,4)=0,MOD(A1,100)))),1,0)+30*(B1-1)+CHOOSE(B1,0,1,-1,0,0,1,1,2,3,3,4,4,5)+C1
=IF(AND(C1>2,OR(MOD(A1,400)=0,AND(MOD(A1,4)=0,MOD(A1,100)))),1,0)+30*B1-30+CHOOSE(B1,0,1,-1,0,0,1,1,2,3,3,4,4,5)+C1
=IF(AND(C1>2,OR(MOD(A1,400)=0,AND(MOD(A1,4)=0,MOD(A1,100)))),1,0)+30*B1-31+CHOOSE(B1,1,2,0,1,1,2,2,3,4,4,5,5,6)+C1
=AND(C1>2,OR(MOD(A1,400)=0,AND(MOD(A1,4)=0,MOD(A1,100))))+30*B1-31+CHOOSE(B1,1,2,0,1,1,2,2,3,4,4,5,5,6)+C1
Wernisch
источник