Обратный отсчет рабочего дня


17

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


Основная задача - создать обратный отсчет до определенной даты, которая включает в себя только рабочие дни.

В качестве рабочего дня учитываются понедельник , вторник , среда , четверг и пятница .

Входные данные должны быть определенной датой в «неофициальном» европейском стандартном формате dd.MM.yyyyи должны быть сегодня или днем ​​в будущем.

Выходными данными должно быть только количество оставшихся дней.

Поскольку это выигрывает самый короткий код.


Прецедент:

  Today    |   Input    | Output
10.12.2018 | 17.12.2018 |    5
02.10.2018 | 16.10.2018 |   10

Если я пропустил несколько вещей в вопросе, пожалуйста, прости меня - это мой первый вопрос :)

РЕДАКТИРОВАТЬ:

  • Вы можете использовать в falseкачестве вывода вместо 0 <- но это не красиво
  • Нет необходимости соблюдать DST

9
Есть ли какая-то конкретная причина этого "неофициального" европейского формата ввода? Наш консенсус заключается в том, чтобы обеспечить гибкий ввод по мере возможности.
Арно

6
Есть ли смысл добавлять «дополнительную задачу» в трудно обрабатываемый формат даты? Это просто кажется несправедливым по отношению к языкам, которые имеют гибкий формат даты ...
Quintec

3
@ Хилл, я не сказал, что это «тяжело», это просто ненужные хлопоты, особенно в код-гольфе ... обратите внимание на ссылку, которую Арнаулд разместил выше ... обычно гибкий ввод - это норма ...
Quintec

6
Кстати, вы заметили, что это ваш первый вызов; Я предлагаю вам использовать Песочницу для доработки, прежде чем отправлять вызов на главную! В противном случае, хорошая работа, и я буду рад видеть вас еще!
Джузеппе

7
Не очень впечатлен строгим форматом ввода, но кроме этого это хороший вызов.
ElPedro

Ответы:


18

05AB1E , 130 128 133 131 124 123 байта

žežfžg)V0[Y`UÐ3‹12*+>13*5÷s3‹Xα©т%D4÷®т÷©4÷®·()ćsO7%2@+Y`т‰0Kθ4ÖUD2Qi\28X+ë<7%É31α}‹iY¬>0ëY1¾ǝDÅsD12‹i>1ë\1Dǝ¤>2}}ǝVYI'.¡Q#

Я не в своем уме..

Для языка игры в гольф 05AB1E совершенно не имеет значения, является ли ввод с помощью .или -. Тем не менее, 05AB1E не имеет встроенных функций для объектов Date или вычислений. Единственная встроенная функция, касающаяся дат, это текущий год / месяц / день / часы / минуты / секунды / микросекунды.

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

+5 байт из-за части, которую я забыл в формуле Зеллера (год-1 для месяцев январь и февраль) ..

Попробуйте онлайн или Попробуйте онлайн с эмулируемой самоназначенной датой «сегодня» .

Объяснение:

Стена текста входящего.

Обычно код следует следующему псевдокоду:

1   Date currentDate = today;
2   Integer counter = 0;
3   Start an infinite loop:
4*    If(currentDate is NOT a Saturday and currentDate is NOT a Sunday):
5       Counter += 1;
6*    currentDate += 1; // Set currentDate to the next day in line
7     If(currentDate == parsed input-string):
8       Stop the infinite loop, and output the counter

1) Date currentDate = today;является ли эта часть программы 05AB1E:

že          # Push today's day
  žf        # Push today's month
    žg      # Push today's year
      )     # Wrap them into a single list
       V    # Pop and store this list in variable `Y`

2) Integer counter = 0;и 3) Start an infinite loop:прямо в программе 05AB1E:

0     # Push 0 to the stack
 [    # Start an infinite loop

4) If(currentDate is NOT a Saturday and currentDate is NOT a Sunday):первая сложная часть с ручными расчетами. Поскольку 05AB1E не имеет встроенных функций Date, мы должны рассчитать день недели вручную.

Общая формула для этого:

h=(q+13(m+1)5+K+K4+J42J)mod7,

Где за месяцы с марта по декабрь:

  • q являетсяday месяца ([1, 31])
  • m является 1-индексированныйmonth ([3, 12])
  • K является годом столетия (yearmod100 )
  • J - индексированный век (year100)

И за месяцы январь и февраль:

  • q являетсяday месяца ([1, 31])
  • m является индексированным 1month+12 ([13, 14])
  • K - год столетия за предыдущий год ((year1)mod100 )
  • J - индексированное столетие за предыдущий год (year1100)

В результате получается день недели h , где 0 = суббота, 1 = воскресенье, ..., 6 = пятница.
Источник: конгруэнтность Целлера

Мы можем видеть это в этой части программы 05AB1E:

Y             # Push variable `Y`
 `            # Push the day, month, and year to the stack
  U           # Pop and save the year in variable `X`
   Ð          # Triplicate the month
    3        # Check if the month is below 3 (Jan. / Feb.),
              # resulting in 1 or 0 for truthy/falsey respectively
      12*     # Multiply this by 12 (either 0 or 12)
         +    # And add it to the month
              # This first part was to make Jan. / Feb. 13 and 14

>             # Month + 1
 13*          # Multiplied by 13
    5÷        # Integer-divided by 5
s3           # Check if the month is below 3 again (resulting in 1 / 0)
   Xα         # Take the absolute difference with the year
     ©        # Store this potentially modified year in the register
      т%      # mYear modulo-100
D4÷           # mYear modulo-100, integer-divided by 4
®т÷©4÷        # mYear integer-divided by 100, and then integer-divided by 4
®·(           # mYear integer-divided by 100, doubled, and then made negative
)             # Wrap the entire stack into a list
 ć            # Extract the head (the counter variable that was also on the stack)
  s           # Swap so the calculated values above are as list at the top
   O          # Take the sum of this entire list
    7%        # And then take modulo-7 to complete the formula,
              # resulting in 0 for Saturday, 1 for Sunday, and [2, 6] for [Monday, Friday]

2@            # Check if the day is greater than or equal to 2 (so a working day)

5) Counter += 1;снова прямо:

     # The >=2 check with `2@` results in either 1 for truthy and 0 for falsey
+    # So just adding it to the counter variable is enough

6) currentDate += 1; // Set currentDate to the next day in lineопять сложнее, потому что мы должны сделать это вручную. Так что это будет расширен до следующего псевдокода:

a   Integer isLeapYear = ...;
b   Integer daysInCurrentMonth = currentDate.month == 2 ?
c                                 28 + isLeapYear
d                                :
e                                 31 - (currentDate.month - 1) % 7 % 2;
f   If(currentDate.day < daysInCurrentMonth):
g     nextDate.day += 1;
h   Else:
i     nextDate.day = 1;
j     If(currentDate.month < 12):
k       nextDate.month += 1;
l     Else:
m       nextDate.month = 1;
n       nextDate.year += 1;

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

6a) Integer isLeapYear = ...;сделано так в программе 05AB1E:

Y             # Push variable `Y`
 `            # Push the days, month and year to the stack
  т‰          # Divmod the year by 100
    0K        # Remove all items "00" (or 0 when the year is below 100)
      θ       # Pop the list, and leave the last item
       4Ö     # Check if this number is visible by 4
         U    # Pop and save the result in variable `X`

Также используется в этом моем ответе 05AB1E , поэтому для иллюстрации шагов добавлено несколько примеров лет.

6б) currentDate.month == 2 ?и 6в) 28 + isLeapYearсделано так:

D            # Duplicate the month that is now the top of the stack
 2Q          # Check if it's equal to 2
   i         # And if it is:
    \        #  Remove the duplicated month from the top of the stack
     28X+    #  Add 28 and variable `X` (the isLeapYear) together

6d) :и 6e) 31 - (currentDate.month - 1) % 7 % 2;сделано так:

ë           # Else:
 <          #  Month - 1
  7%        #  Modulo-7
    É       #  Is odd (shortcut for %2)
     31     #  Push 31
       α    #  Absolute difference between both
}           # Close the if-else

6f) If(currentDate.day < daysInCurrentMonth):сделано так:

     # Check if the day that is still on the stack is smaller than the value calculated
 i    # And if it is:

6g) nextDate.day += 1;сделано так:

Y       # Push variable `Y`
 ¬      # Push its head, the days (without popping the list `Y`)
  >     # Day + 1
   0    # Push index 0

        # (This part is done after the if-else clauses to save bytes)
}}      # Close the if-else clauses
  ǝ     # Insert the day + 1 at index 0 in the list `Y`
   V    # Pop and store the updated list in variable `Y` again

6h) Else:и 6i) nextDate.day = 1;тогда делается так:

ë        # Else:
 Y       #  Push variable `Y`
  1      #  Push a 1
   ¾     #  Push index 0
    ǝ    #  Insert 1 at index 0 (days part) in the list `Y`

6j) If(currentDate.month < 12)::

D           # Duplicate the list `Y`
 Ås         # Pop and push its middle (the month)
   D12     # Check if the month is below 12
       i    # And if it is:

6k) nextDate.month += 1;:

>       # Month + 1
 1      # Push index 1

        # (This part is done after the if-else clauses to save bytes)
}}      # Close the if-else clauses
  ǝ     # Insert the month + 1 at index 1 in the list `Y`
   V    # Pop and store the updated list in variable `Y` again

6l) Else:, 6m) nextDate.month = 1;и 6n) nextDate.year += 1;выполняются следующим образом:

ë        # Else:
 \       #  Delete the top item on the stack (the duplicated month)
  1      #  Push 1
   D     #  Push index 1 (with a Duplicate)
    ǝ    #  Insert 1 at index 1 (month part) in the list `Y`

 ¤       #  Push its tail, the year (without popping the list `Y`)
  >      #  Year + 1
   2     #  Index 2

         # (This part is done after the if-else clauses to save bytes)
}}       # Close the if-else clauses
  ǝ      # Insert the year + 1 at index 2 in the list `Y`
   V     # Pop and store the updated list in variable `Y` again

И наконец на 8) If(currentDate == parsed input-string):и 9) Stop the infinite loop, and output the counter:

Y          # Push variable `Y`
 I         # Push the input
  '.¡     '# Split it on dots
     Q     # Check if the two lists are equal
      #    # And if they are equal: stop the infinite loop
           # (And output the top of the stack (the counter) implicitly)

5
Ты сумасшедший ... есть возражение.
AdmBorkBork

1
Самая длинная программа 05AB1E?
Луис Мендо

2
@LuisMendo Близко, но я боюсь, что у меня есть один ответ 05AB1E, который еще длиннее , и тот, который подходит слишком близко ... ;) Уверен, я смогу сыграть несколько байтов здесь и упростить части реализации псевдокода следующего дня. Посмотрю завтра утром, но только что вернулся из спорта и скоро лягу спать.
Кевин Круйссен,

11

Excel 24 байта

Предполагается ввод в ячейке A1

=NETWORKDAYS(NOW()+1,A1)

Использует встроенную функцию. К сожалению, функция включает в себя как сегодня, так и дату окончания. С тех пор ОП уточнил, что не стоит считать сегодня, поэтому я добавляю одно в СЕЙЧАС, чтобы не считать сегодня.

Для комментариев к формату номера, опять же, это стандарт Excel: введите описание изображения здесь


Хотя это работает со значениями даты, оно не может принимать данные, как указано. То есть (по крайней мере, в версии для США) 10.12.2018это строка, когда она содержится в ячейке, а не в дате. Очевидное , но Долгосрочное решение , чтобы исправить это было бы изменить , A1чтобы DATE(RIGHT(A1,4),MID(A1,4,2),LEFT(A1,2))в вашем решении
Тейлор Скотт

к сожалению, сообщество решило, что языки должны работать в соответствии с их настройками по умолчанию, чтобы быть действительными (единственное исключение, которое я видел в этом, - это язык - IE, если ваш язык поддерживает английский и испанский языки, вы можете легко использовать любой из них, но это должно быть отмечено.) Кроме того, OP (@hille) не заявил, что формат является гибким, и фактически заявил совершенно противоположное (см. второй комментарий по этому вопросу)
Тейлор Скотт,

2
Формат не стандартный, он основан на локали. Excel читает формат из HKCU\Control Panel\International\sDecimalстроки реестра. Для стандартной установки Windows в США это MM / dd / yyyy. В большинстве стран ЕС это будет по умолчанию.
Эрик

@luisMendo Да, это работает. Я не видел никаких разъяснений. Если бы вместо этого не было счета в прошлый день, я мог бы иметь = NETWORKDAYS (NOW (), A1-1). Я знал, что это будет всегда один и тот же счетчик байтов, независимо от того, какое уточнение.
Keeta - восстановить Монику

Рад, что работает. Я снял понижающий голос
Луис Мендо

11

R , 76 байт

Пожалуйста, взгляните также на этот 72-байтовый R-ответ, который также не зависит от локали.

sum(!grepl("S",weekdays(seq(Sys.Date(),as.Date(scan(,""),"%d.%m.%Y"),1))))+1

Попробуйте онлайн!

weekdaysдает текстовые дни недели, поэтому мы подсчитываем дни в последовательности между сегодняшним днем ​​и входными данными, которые не содержат S, и добавляем один к результату.


8

Java 10 233 232 226 байт

import java.util.*;d->{int r=0;var s=Calendar.getInstance();s.setTime(new Date());var e=s.getInstance();for(e.setTime(new java.text.SimpleDateFormat("dd.MM.yyyy").parse(d));!s.after(e);s.add(5,1))if(s.get(7)%7>1)r++;return r;}

Дата всегда напоминает мне, насколько многословна Java на самом деле ..

ПРИМЕЧАНИЕ: теперь есть два более коротких ответа Java (менее 175 байт), один с умным использованием устаревших методов из более ранних версий Java от @LukeStevens , а другой с java.time.LocalDateновинкой с Java 8 от @ OlivierGrégoire .

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

Объяснение:

import java.util.*;            // Required import for both Calendar and Date
d->{                           // Method with String parameter and integer return-type
  int r=0;                     //  Result-integer, starting at 0
  var s=Calendar.getInstance();//  Create a Calendar instance for the start-date
  s.setTime(new Date());       //  Set the start date to today
  var e=s.getInstance();       //  Create a Calendar instance for the end-date
  for(e.setTime(               //  Set the end date to:
        new java.text.SimpleDateFormat("dd.MM.yyyy")
                               //   Create a formatter for the "dd.MM.yyyy" format
         .parse(d));           //   And parse the input-String to a Date
      !s.after(e)              //  Loop as long as we haven't reached the end date yet
      ;                        //    After every iteration:
       s.add(5,1))             //     Increase the start-date by 1 day
    if(s.get(7)%7>1)           //   If the day of the week is NOT a Saturday or Sunday:
                               //   (SUNDAY = 1, MONDAY = 2, ..., SATURDAY = 7)
      r++;                     //    Increase the result-sum by 1
  return r;}                   //  Return the result-sum

Не могли бы вы сделать e=s.clone()?
Quintec

1
Мы также можем (я полагаю) сделать Calendar s=Calendar.getInstance(),e=s.getInstance(), что, к сожалению, в итоге будет точно такой же длины.
Миша Лавров

1
@MishaLavrov Ах, статика Cдействительно не нужна. Это было из старой части кода, где я также использовал Cгде-то еще. var s=Calendar.getInstance();var e=s.getInstance();Благодаря этому я смог сыграть в гольф 1 байт . :)
Кевин Круйссен,

1
150 байт , используя java.time.
Оливье Грегуар

1
Выполнено! Это очень близко в байтах к другому ответу, но еще не побеждает его.
Оливье Грегуар

7

JavaScript (ES6), 116 103 байт

f=(d,n=+new Date)=>(D=new Date(n)).toJSON()<d.split`.`.reverse().join`-`&&(D.getDay()%6>0)+f(d,n+864e5)

Попробуйте онлайн!

Как?

N

ND.toJSON()

ГГГГ - ММ - ДД Т чч : мм : сс.ссс Z

YYYY-MM-DDdYYYY-MM-DDDD.MM.YYYY

d.split`.`.reverse().join`-`

D.getDay()0606

(D.getDay() % 6 > 0) + f(d, n + 864e5)

86,400,000N


6

MATL , 24 байта

46tQZt24&YO:Z':X-9XO83-z

Попробуйте онлайн!

Я не хочу, чтобы у меня был какой-либо формат ввода, чтобы особые языки программирования кода получили большое преимущество

Вы наполовину преуспели :-)

объяснение

46      % Push 46 (ASCII for '.')
tQ      % Duplicate, add 1: gives 47 (ASCII for '/')
Zt      % Implicit input. Replace '.' by '/' in the input string
24&YO   % Convert string with date format 24 ('dd/mm/yyyy') to serial date number.
        % This is an integer representing day starting at Jan-1-0000
:       % Inclusive range from 1 to that
Z'      % Push current date and time as a serial number. Integer part is day;
        % decimal part represents time of the day
:       % Inclusive range from 1 to that
X-      % Set difference. Gives serial numbers of days after today, up to input
9XO     % Convert each number to date format 9, which is a letter for each day
        % of the week: 'M', 'T', 'W', 'T', ' F', 'S', 'S'
83-     % Subtract 83 (ASCII for 'S')
z       % Number of nonzeros. Implicit display

Если я правильно понял задачу, вы берете только одну дату и сравниваете ее с сегодняшней датой. Например, 16.10.2018приведет ли сегодня (понедельник 01-10-2018) к 11завтрашнему дню 10и т. Д.
Кевин Круйссен,

@KevinCruijssen Упс. Благодарность! Исправлено сейчас
Луис Мендо

1
И с тем же количеством байтов. :) Здорово, +1 от меня.
Кевин Круйссен

6

Wolfram Language (Mathematica) , 64 56 байт

DayCount[Today,""<>#~StringTake~{{4,6},3,-4},"Weekday"]&

Попробуйте онлайн!

DayCount[x,y,"Weekday"]подсчитывает количество рабочих дней между xи y.

Входы xиy могут быть многими вещами, включая причудливые, DateObjectтакие как возвращаемые Today, или строку в формате (к сожалению) mm.dd.yyyy.

Моя предыдущая попытка пыталась повернуть dd.mm.yyyy входные данные в DateObjectсообщение Mathematica, как его анализировать; новое решение просто переставляет строку, чтобы поставить день и месяц в том порядке, в котором их ожидает Mathematica.

Стоит отметить, что 28-байтовое решение DayCount[Today,#,"Weekday"]&не только отлично работает для формата ввода месяц-день-год, но также правильно обрабатывает однозначные данные день-месяц-год, такие как 31.12.2018, что не может означать «12-й день 31-го числа». месяц". Так что это правильно более 60% времени :)



5

R, 72 символа

Вариант ответа, предоставленного @ngm, который позволяет избегать grepl для сохранения нескольких символов и работает в неанглийских локалях.

sum(strftime(seq(Sys.Date(),as.Date(scan(,""),"%d.%m.%Y"),1),'%u')<6)+1


1
Короче и более общий тоже. Хороший ответ и добро пожаловать в убежище.
НГМ

1
Добро пожаловать в PPCG! Вы можете добавить ссылку TIO - это просто и форматирует ответ для вас :)
JayCe

5

Java (OpenJDK 8) , 174 166 165 байт

С небольшим вдохновением от ответа Кевина и хорошим старым тралом через устаревший API даты мне удалось получить более сжатое Java-решение.

-8 байт благодаря изобретательному анализу регулярных выражений Кевина

-1 байт благодаря умной побитовой операции Невея

import java.util.*;d->{long r=0,s=new Date().getTime(),e=Date.parse(d.replaceAll("(..).(..).","$2/$1/"));for(;s<=e;s+=864e5)r-=-new Date(s).getDay()%6>>-1;return r;}

Попробуйте онлайн!

объяснение

import java.util.*;                         // Required import for Date 
long r=0,                                   // Initialise result variable
     s=new Date().getTime(),                // Current date in millis
     e=Date.parse(
         d.replaceAll("(..).(..).","$2/$1/")// Use regex to convert to MM/dd/yyyy
     );                                     // Parse date arg using deprecated API
for(;s<=e;                                  // Loop while current millis are less than date arg (e.g. date is before)       
    s+=864e5)                               // Add 86400000 ms to current date (equiv of 1 day)
    r-=-new Date(s).getDay()%6>>-1;        // If day is Sunday (0) or Saturday (6) don't increment, else add 1
return r;                                   // When loop finished return result

1
Хороший ответ! Умное использование varargs с d=d[0].splitи устаревшим .parseформатом по умолчанию MM/dd/yyyy. Одна небольшая ошибка в вашем посте, которую вы указали import java.text.*;вместо import java.util.*;кода и // Required import for both Calendar and Dateв своем объяснении (даже если вы его не используете Calendar).
Кевин Круйссен

@KevinCruijssen Не знаю, почему я это сделал, java.textно исправил сейчас! Благодарность!
Люк Стивенс

1
Хотя мне понравилось d=d[0].splitс varargs, изменив ввод на обычную строку, удалив d=d[0].split("\\.");и изменив d[1]+"/"+d[0]+"/"+d[2]на d.replaceAll("(..).(..).","$2/$1/") 7 байт .
Кевин Круйссен

1
И еще 1 байт , изменив r+=new Date(s).getDay()%6<1?0:1,s+=864e5);на s+=864e5)r+=new Date(s).getDay()%6<1?0:1;. :)
Кевин Круйссен

1
-1 байт:r-=-new Date(s).getDay()%6>>-1;
Невай

4

Красный , 72 байта

func[a][b: now/date s: 0 until[if b/weekday < 6[s: s + 1]a < b: b + 1]s]

Попробуйте онлайн!

Принимает дату в формате дд-мм-гггг, например, 31-10-2018 (также работает с 10 октября 2018)

Строгий ввод:

Красный , 97 байт

func[a][a: do replace/all a".""-"b: now/date s: 0 until[if b/weekday < 6[s: s + 1]a < b: b + 1]s]

Попробуйте онлайн!

Бонус:

Возвращает список дат / рабочих дней рабочих дней до указанной даты:

Красный , 235 байт

f: func [ a ] [
    b: now/date
    d: system/locale/days
    collect [ 
        until [ 
            if b/weekday < 6 [ 
                keep/only reduce [ b ":" d/(b/weekday) ]
            ]
            a < b: b + 1
        ]
    ]
]

Попробуйте онлайн!


О, несправедливо, в Python мне нужно потратить около 72 байтов на обработку этого формата ввода-вывода ...: P
Quintec

1
Обычно мои решения Red одни из самых длинных, но, к счастью, Red отлично справляется с датами :)
Гален Иванов

1
90 байтов для обработки Python ... я готов, я ухожу, пока не появится более гибкий формат ввода: P
Quintec


3

Python 2 , 163 156 149 147 байт

lambda s:sum((date.today()+timedelta(x)).weekday()<5for x in range((date(*map(int,(s.split(".")[::-1])))-date.today()).days))
from datetime import*

Попробуйте онлайн!

-7 с благодарностью @mypetlion

-7 больше благодаря @ovs

+30 из-за очень ограниченного формата ввода, который я заметил только перед тем, как опубликовать свой предыдущий код, который принимал ввод, например (2018,11,1):-(


2
Не нужно для этого (0,1)[t.weekday()<5]. Булево значение Python является подклассом intи True, Falseможет использоваться в арифметических операциях как 1,0. Замените его, c+=t.weekday()<5чтобы сохранить 7 байтов.
mypetlion

1
149 байт как лямбда.
овс

Спасибо @mypetlion. Я не должен был пропустить это.
ElPedro

Спасибо @ovs. Второй раз ты недавно помог. В прошлый раз было очень впечатляюще -30. Пытался решить, как получить это в лямбду.
ElPedro

3

Java (JDK 10) , 171 байт

s->{int c=0;for(var t=java.time.LocalDate.now();!t.parse(s.replaceAll("(..).(..).(.*)","$3-$2-$1")).equals(t);t=t.plusDays(1))c-=t.getDayOfWeek().getValue()/6-1;return c;}

Попробуйте онлайн!

кредиты


1
Вы можете изменить (.*)\\.(.*)\\.(.*)To (..).(..).(.*).
Кевин Круйссен,

replaceAllТем не менее, с вашей техникой его ответ может быть обработан на 7 байтов, поэтому ваш ответ еще немного длиннее. ;)
Кевин Круйссен,

@KevinCruijssen Спасибо за регулярное выражение! И не беспокойтесь: я не против получить более длинный ответ;)
Оливье Грегуар,

3

JavaScript (Node.js) , 168 160 139 133 байта

На 35 байт меньше благодаря Quintec и Kevin Cruijssen

D=>{var i=D.split('.'),n=0;for(var d=new Date();d<=new Date(i[2],i[1]-1,i[0]);d.setDate(d.getDate()+1))n+=-~d.getDay()%7>1;return n;}

Попробуйте онлайн!

D=>{
  var i=D.split('.'),                 // Splits the date string by .
      n=0;                            // Counter variable
  for(var d=new Date();               // For the actual date
      d<=new Date(i[2],i[1]-1,i[0]);      // As long as the date is less or equal the requested date
      d.setDate(d.getDate()+1))           // Count the date one up
    n+=-~d.getDay()%7>1;                // If the date is not a Sunday or Saturday
  return n;                           // Return the counter variable
}


1
139 байт с улучшенным условием if
Quintec

1
Поскольку ваш метод не является рекурсивным, вам не нужно добавлять f=счетчик байтов (а в TIO вы можете поместить его в заголовок), поэтому @Quintec указал, что это 139 байтов вместо 141 байта. Кроме того, вы можете изменить if((d.getDay()+1)%7>1)n++;к n+=-~d.getDay()%7>1;гольфу его для того чтобы 133 байт .
Кевин Круйссен


1
Еще несколько советов для дальнейшего использования.
Лохматый

3

Python3 & Numpy , 96 байт

Я не мог получить меньше, чем скучное готовое решение ...

from numpy import*
d=datetime64
lambda s:busday_count(d('today'),d(f'{s[6:]}-{s[3:5]}-{s[:2]}'))

Попробуйте онлайн!


Должен попасть в Python 3;)
ElPedro

Исходя из вашего импорта, вы используете не Python 3 , а Python 3 с numpy .
Джонатан Фрех

@JonathanFrech это должно быть в названии? другие, использующие python, также использовали библиотеку, так как python не имеет встроенного типа данных для дат или времени.
Аарон

1
Это зависит от вашего определения встроенных модулей, таких как datetime, которые являются стандартными библиотечными модулями, и поэтому я бы посчитал их частью основного языка. Однако, когда кто-то использует сторонние модули, такие как numpy , он расширяет возможности языка, и поэтому я вижу его как другой язык.
Джонатан Фрех

2

PowerShell , 107 99 байт

-8 байт благодаря маззи

$d,$m,$y=$args-split'\.';for($a=date;$a-lt(date "$y-$m-$d");$a=$a|% *ys 1){$o+=($a|% D*k)-in1..5}$o

Попробуйте онлайн!

Выполняет регулярные выражения -splitдля ввода $args, сохраняет значения в $days, $months и $yушах соответственно. Затем входит в forцикл, инициализируя$a на сегодняшнюю дату. Цикл продолжается до тех пор, пока не $aбудет -lвведена tнаша целевая дата. Каждая итерация мы добавляем 1йа ysк $aи проверки , является ли ток D*k(сокращенно DayOfWeek) находится в диапазоне 1..5(то есть, с понедельника по пятницу). Этот логический результат накапливается, $oи как только мы выходим из цикла, это значение остается в конвейере и вывод неявен.


100 байт? $d,$m,$y=$args-split'\.';for($a=date;$a-lt(date "$y-$m-$d");$a=$a|% *ys 1){$o+=($a|% D*k)-in1..5};$o
Маззи

1
@ Mazzy Действительно. Кроме того, точка с запятой между for(...){...}и $oможет быть удалена, так что теперь мы ниже 100!
AdmBorkBork

2

Python 2 , 147 143 141 140 байт

from datetime import*
lambda e,s=date.today():sum((s+timedelta(x+1)).weekday()<5for x in range((date(*map(int,e.split(".")[::-1]))-s).days))

Попробуйте онлайн!

Принимает строку e, которая представляет дату окончания в формате «дд.ММ.ГГГГ». При желании также принимает дату начала, но ожидается, что это будет datetime.date.

Дата начала, s, по умолчанию установлена ​​на текущую дату как объект datetime.date, чтобы игнорировать время. Время окончания анализируется в объект datetime.datetime, а затем преобразуется в дату, так как объекты datetime.date не имеют метода разбора и datetime нельзя добавлять / вычитать из дат. Повторяет каждый день в (начало, конец] и добавляет 1 к итогу, если его номер дня недели <5. ([0-4] - [пн-пт], [5-6] - [сб-вс]).

Парсинг даты и времени - худший, ребята.

РЕДАКТИРОВАТЬ: украл ElPedro карты (Int, вещь), чтобы сохранить 4 байта.

РЕДАКТИРОВАТЬ 2: ЭЛЕКТРИЧЕСКИЙ BOOGALOO: Сохранить 2 байта, сделав его анонимной функцией. (Спасибо, Аарон!)

РЕДАКТИРОВАТЬ 3: xrange -> range. (Еще раз спасибо Аарон!)


1
Пожалуйста! Хороший ответ :)
ElPedro

1
Это соглашение, которое вы можете f=опустить здесь от лямбда-выражений
Аарон

1
«Разбор даты и времени - худший, ребята». Хахахаха, чувствую мою боль, вы преуспели там, где я потерпел неудачу: P
Quintec

@ Аарон Я никогда не уверен, что это нормально с несколькими функциями или с операторами импорта, спасибо!
Триггернометрия

1
Вы также можете использовать, rangeа не xrangeвсе должно работать просто отлично.
Аарон

2

PHP, 66 байт

for($t=time();$t<strtotime($argn);)$r+=date(N,$t+=86400)<6;echo$r;

пустой вывод для 0; вставить +между echoи$r исправить.

Запустите как трубу с -nrили попробуйте онлайн .


60 байтов с одинарным выводом:

for($t=time();$t<strtotime($argn);)echo date(N,$t+=86400)<6;


1

IBM / Lotus Notes Formula - 99 байтов

d:=i;c:=0;@While(d>@Today;@Set("c";c+@If(@Weekday(d)=1:7;0;1));@Set("d";@Adjust(d;0;0;-1;0;0;0)));c

Принимает данные из поля даты / времени i. Формат ввода iустановлен как .разделенный, поэтому нет необходимости преобразовывать входные данные. Заметки могут вводить дату с любым разделителем до тех пор, пока вы не скажете, каким он будет (надеюсь, это не обман!). Формула находится в вычисляемом числовом полеo в той же форме.

Интересно в сторону: с тех пор @For и @Whileбыли введены в язык Формулы в (я думаю) R6 великим Дэмиеном Кацем единственное использование, которое я нашел для них, это игра в гольф кода. Я никогда не использовал их в производственном приложении.

Для формулы нет доступных TIO, поэтому вот снимок экрана, сделанный 02.10.2018:

введите описание изображения здесь



1

K4 , 40 байт

Решение:

{+/1<.q.mod[d+!(."."/:|"."\:x)-d:.z.d]7}

Объяснение:

Рассчитайте разницу между датами, используйте модуль 7, чтобы игнорировать выходные, подведите итоги.

{+/1<.q.mod[d+!(."."/:|"."\:x)-d:.z.d]7} / the solution
     .q.mod[                         ]7  / modulo with 7
                                 .z.d    / UTC date
                               d:        / save as d
                              -          / subtract from
               (             )           / do this together
                       "."\:x            / split input on "."
                      |                  / reverse
                 "."/:                   / join back with "."
                .                        / take the value
              !                          / range 0..the difference
            d+                           / add today's date to range
   1<                                    / is 1 less than the modulo (ie is this mon-fri)?
 +/                                      / sum up

Примечания:

  • та же байтовая альтернатива разбору даты: "D"$,/|"."\:x


0

q, 52 79 байт

{x:"D"$"."sv reverse"."vs x;i:0;while[x-.z.d;$[2>x mod 7;x-:1;[i+:1;x-:1]]];:i}

в q каждая дата имеет целочисленное значение, основанное на том, сколько дней прошло с начала тысячелетия. Применяя к этому 'mod 7', вы получаете уникальные значения для каждого дня недели (0 для субботы, 6 для пятницы). Поэтому, когда 2> x mod 7, не увеличивайте счетчик, чтобы избежать подсчета выходных.

РЕДАКТИРОВАТЬ: Пропущенный строгий формат даты, редактирование

EDIT2: включены


1
Лучше я придумал это {sum 1<mod[d+til("D"$x 10 vs 67893401)-d:.z.d]7}для 48 байт , не прибегая к K глаголов.
Стритстер

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