У меня была гениальная идея облегчить трудовую жизнь - обратный отсчет до определенной даты, которая насчитывает только рабочие дни.
Основная задача - создать обратный отсчет до определенной даты, которая включает в себя только рабочие дни.
В качестве рабочего дня учитываются понедельник , вторник , среда , четверг и пятница .
Входные данные должны быть определенной датой в «неофициальном» европейском стандартном формате dd.MM.yyyy
и должны быть сегодня или днем в будущем.
Выходными данными должно быть только количество оставшихся дней.
Поскольку это код-гольф, выигрывает самый короткий код.
Прецедент:
Today | Input | Output
10.12.2018 | 17.12.2018 | 5
02.10.2018 | 16.10.2018 | 10
Если я пропустил несколько вещей в вопросе, пожалуйста, прости меня - это мой первый вопрос :)
РЕДАКТИРОВАТЬ:
- Вы можете использовать в
false
качестве вывода вместо0
<- но это не красиво - Нет необходимости соблюдать DST
Ответы:
05AB1E ,
130128133131124123 байтаЯ не в своем уме..
Для языка игры в гольф 05AB1E совершенно не имеет значения, является ли ввод с помощью
.
или-
. Тем не менее, 05AB1E не имеет встроенных функций для объектов Date или вычислений. Единственная встроенная функция, касающаяся дат, это текущий год / месяц / день / часы / минуты / секунды / микросекунды.Поэтому почти весь код, который вы видите, - это ручные вычисления для перехода к следующему дню и вычисления дня недели.
+5 байт из-за части, которую я забыл в формуле Зеллера (год-1 для месяцев январь и февраль) ..
Попробуйте онлайн или Попробуйте онлайн с эмулируемой самоназначенной датой «сегодня» .
Объяснение:
Стена текста входящего.
Обычно код следует следующему псевдокоду:
1)
Date currentDate = today;
является ли эта часть программы 05AB1E:2)
Integer counter = 0;
и 3)Start an infinite loop:
прямо в программе 05AB1E:4)
If(currentDate is NOT a Saturday and currentDate is NOT a Sunday):
первая сложная часть с ручными расчетами. Поскольку 05AB1E не имеет встроенных функций Date, мы должны рассчитать день недели вручную.Общая формула для этого:
Где за месяцы с марта по декабрь:
[1, 31]
)[3, 12]
)И за месяцы январь и февраль:
[1, 31]
)[13, 14]
)В результате получается день неделиh , где 0 = суббота, 1 = воскресенье, ..., 6 = пятница.
Источник: конгруэнтность Целлера
Мы можем видеть это в этой части программы 05AB1E:
5)
Counter += 1;
снова прямо:6)
currentDate += 1; // Set currentDate to the next day in line
опять сложнее, потому что мы должны сделать это вручную. Так что это будет расширен до следующего псевдокода:Источники:
Алгоритм определения того, является ли год високосным.(РЕДАКТИРОВАТЬ: больше не актуально, так как я использую альтернативный метод для проверки високосных лет, который сэкономил 7 байт.)Алгоритм определения количества дней в месяце
6a)
Integer isLeapYear = ...;
сделано так в программе 05AB1E:Также используется в этом моем ответе 05AB1E , поэтому для иллюстрации шагов добавлено несколько примеров лет.
6б)
currentDate.month == 2 ?
и 6в)28 + isLeapYear
сделано так:6d)
:
и 6e)31 - (currentDate.month - 1) % 7 % 2;
сделано так:6f)
If(currentDate.day < daysInCurrentMonth):
сделано так:6g)
nextDate.day += 1;
сделано так:6h)
Else:
и 6i)nextDate.day = 1;
тогда делается так:6j)
If(currentDate.month < 12):
:6k)
nextDate.month += 1;
:6l)
Else:
, 6m)nextDate.month = 1;
и 6n)nextDate.year += 1;
выполняются следующим образом:И наконец на 8)
If(currentDate == parsed input-string):
и 9)Stop the infinite loop, and output the counter
:источник
Excel 24 байта
Предполагается ввод в ячейке A1
Использует встроенную функцию. К сожалению, функция включает в себя как сегодня, так и дату окончания. С тех пор ОП уточнил, что не стоит считать сегодня, поэтому я добавляю одно в СЕЙЧАС, чтобы не считать сегодня.
Для комментариев к формату номера, опять же, это стандарт Excel:
источник
10.12.2018
это строка, когда она содержится в ячейке, а не в дате. Очевидное , но Долгосрочное решение , чтобы исправить это было бы изменить ,A1
чтобыDATE(RIGHT(A1,4),MID(A1,4,2),LEFT(A1,2))
в вашем решенииHKCU\Control Panel\International\sDecimal
строки реестра. Для стандартной установки Windows в США это MM / dd / yyyy. В большинстве стран ЕС это будет по умолчанию.R , 76 байт
Пожалуйста, взгляните также на этот 72-байтовый R-ответ, который также не зависит от локали.
Попробуйте онлайн!
weekdays
дает текстовые дни недели, поэтому мы подсчитываем дни в последовательности между сегодняшним днем и входными данными, которые не содержатS
, и добавляем один к результату.источник
Java 10
233232226 байтДата всегда напоминает мне, насколько многословна Java на самом деле ..
ПРИМЕЧАНИЕ: теперь есть два более коротких ответа Java (менее 175 байт), один с умным использованием устаревших методов из более ранних версий Java от @LukeStevens , а другой с
java.time.LocalDate
новинкой с Java 8 от @ OlivierGrégoire .Попробуйте онлайн.
Объяснение:
источник
e=s.clone()
?Calendar s=Calendar.getInstance(),e=s.getInstance()
, что, к сожалению, в итоге будет точно такой же длины.C
действительно не нужна. Это было из старой части кода, где я также использовалC
где-то еще.var s=Calendar.getInstance();var e=s.getInstance();
Благодаря этому я смог сыграть в гольф 1 байт . :)java.time
.JavaScript (ES6),
116103 байтПопробуйте онлайн!
Как?
.toJSON()
YYYY-MM-DD
YYYY-MM-DD
DD.MM.YYYY
D.getDay()
источник
MATL , 24 байта
Попробуйте онлайн!
Вы наполовину преуспели :-)
объяснение
источник
16.10.2018
приведет ли сегодня (понедельник01-10-2018
) к11
завтрашнему дню10
и т. Д.Wolfram Language (Mathematica) ,
6456 байтПопробуйте онлайн!
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% времени :)источник
Perl 6 , 61 байт
Попробуйте онлайн!
источник
R, 72 символа
Вариант ответа, предоставленного @ngm, который позволяет избегать grepl для сохранения нескольких символов и работает в неанглийских локалях.
sum(strftime(seq(Sys.Date(),as.Date(scan(,""),"%d.%m.%Y"),1),'%u')<6)+1
источник
Java (OpenJDK 8) ,
174166165 байтС небольшим вдохновением от ответа Кевина и хорошим старым тралом через устаревший API даты мне удалось получить более сжатое Java-решение.
-8 байт благодаря изобретательному анализу регулярных выражений Кевина
-1 байт благодаря умной побитовой операции Невея
Попробуйте онлайн!
объяснение
источник
d=d[0].split
и устаревшим.parse
форматом по умолчаниюMM/dd/yyyy
. Одна небольшая ошибка в вашем посте, которую вы указалиimport java.text.*;
вместоimport java.util.*;
кода и// Required import for both Calendar and Date
в своем объяснении (даже если вы его не используетеCalendar
).java.text
но исправил сейчас! Благодарность!d=d[0].split
с varargs, изменив ввод на обычную строку, удаливd=d[0].split("\\.");
и изменивd[1]+"/"+d[0]+"/"+d[2]
наd.replaceAll("(..).(..).","$2/$1/")
7 байт .r+=new Date(s).getDay()%6<1?0:1,s+=864e5);
наs+=864e5)r+=new Date(s).getDay()%6<1?0:1;
. :)r-=-new Date(s).getDay()%6>>-1;
Красный , 72 байта
Попробуйте онлайн!
Принимает дату в формате дд-мм-гггг, например, 31-10-2018 (также работает с 10 октября 2018)
Строгий ввод:
Красный , 97 байт
Попробуйте онлайн!
Бонус:
Возвращает список дат / рабочих дней рабочих дней до указанной даты:
Красный , 235 байт
Попробуйте онлайн!
источник
JavaScript,
8785 байтВозвращает
false
за0
.Попробуйте онлайн или проверьте следующие 31 день
источник
Python 2 ,
163156149147 байтПопробуйте онлайн!
-7 с благодарностью @mypetlion
-7 больше благодаря @ovs
+30 из-за очень ограниченного формата ввода, который я заметил только перед тем, как опубликовать свой предыдущий код, который принимал ввод, например
(2018,11,1)
:-(источник
(0,1)[t.weekday()<5]
. Булево значение Python является подклассомint
иTrue, False
может использоваться в арифметических операциях как1,0
. Замените его,c+=t.weekday()<5
чтобы сохранить 7 байтов.Java (JDK 10) , 171 байт
Попробуйте онлайн!
кредиты
источник
(.*)\\.(.*)\\.(.*)
To(..).(..).(.*)
.replaceAll
Тем не менее, с вашей техникой его ответ может быть обработан на 7 байтов, поэтому ваш ответ еще немного длиннее. ;)JavaScript (Node.js) ,
168160139133 байтаНа 35 байт меньше благодаря Quintec и Kevin Cruijssen
Попробуйте онлайн!
источник
f=
счетчик байтов (а в TIO вы можете поместить его в заголовок), поэтому @Quintec указал, что это 139 байтов вместо 141 байта. Кроме того, вы можете изменитьif((d.getDay()+1)%7>1)n++;
кn+=-~d.getDay()%7>1;
гольфу его для того чтобы 133 байт .-~i
то же самое, что и(i+1)
Кроме того, если вы еще не видели его, советы по игре в гольф на JavaScript и советы по игре в гольф на <все языки> могут быть интересными для чтения. :)Python3 & Numpy , 96 байт
Я не мог получить меньше, чем скучное готовое решение ...
Попробуйте онлайн!
источник
PowerShell ,
10799 байт-8 байт благодаря маззи
Попробуйте онлайн!
Выполняет регулярные выражения
-split
для ввода$args
, сохраняет значения в$d
ays,$m
onths и$y
ушах соответственно. Затем входит вfor
цикл, инициализируя$a
на сегодняшнюю дату. Цикл продолжается до тех пор, пока не$a
будет-l
введенаt
наша целевая дата. Каждая итерация мы добавляем1
йаys
к$a
и проверки , является ли токD*k
(сокращенноDayOfWeek
) находится в диапазоне1..5
(то есть, с понедельника по пятницу). Этот логический результат накапливается,$o
и как только мы выходим из цикла, это значение остается в конвейере и вывод неявен.источник
$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
for(...){...}
и$o
может быть удалена, так что теперь мы ниже 100!Python 2 ,
147143141140 байтПопробуйте онлайн!
Принимает строку 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. (Еще раз спасибо Аарон!)
источник
f=
опустить здесь от лямбда-выраженийrange
а неxrange
все должно работать просто отлично.PHP, 66 байт
пустой вывод для
0
; вставить+
междуecho
и$r
исправить.Запустите как трубу с
-nr
или попробуйте онлайн .60 байтов с одинарным выводом:
источник
PHP (с углеродом ), 107 байт
источник
IBM / Lotus Notes Formula - 99 байтов
Принимает данные из поля даты / времени
i
. Формат вводаi
установлен как.
разделенный, поэтому нет необходимости преобразовывать входные данные. Заметки могут вводить дату с любым разделителем до тех пор, пока вы не скажете, каким он будет (надеюсь, это не обман!). Формула находится в вычисляемом числовом полеo
в той же форме.Интересно в сторону: с тех пор
@For
и@While
были введены в язык Формулы в (я думаю) R6 великим Дэмиеном Кацем единственное использование, которое я нашел для них, это игра в гольф кода. Я никогда не использовал их в производственном приложении.Для формулы нет доступных TIO, поэтому вот снимок экрана, сделанный 02.10.2018:
источник
Рубин , 81 байт
Попробуйте онлайн!
источник
K4 , 40 байт
Решение:
Объяснение:
Рассчитайте разницу между датами, используйте модуль 7, чтобы игнорировать выходные, подведите итоги.
Примечания:
"D"$,/|"."\:x
источник
С (лязг) ,
209208205 байтФлаги компилятора
-DU=u=localtime(&b)
-DW=tm_wday
-DY=tm_year
-DT=tm_yday
(52 байта).Попробуйте онлайн!
-1 байт благодаря @JonathanFrech
источник
?i++:0
->&&++i
.q,
5279 байтв q каждая дата имеет целочисленное значение, основанное на том, сколько дней прошло с начала тысячелетия. Применяя к этому 'mod 7', вы получаете уникальные значения для каждого дня недели (0 для субботы, 6 для пятницы). Поэтому, когда 2> x mod 7, не увеличивайте счетчик, чтобы избежать подсчета выходных.
РЕДАКТИРОВАТЬ: Пропущенный строгий формат даты, редактирование
EDIT2: включены
источник
{sum 1<mod[d+til("D"$x 10 vs 67893401)-d:.z.d]7}
для 48 байт , не прибегая к K глаголов.