Приветственный бот для коллеги с работы


14

У меня есть коллега на работе, который работает дома каждый вторник и четверг. Около 8:00 утра он отправляет нам сообщение со следующим текстом:

Привет сегодня работаю из дома

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

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

Запишите как можно меньше байт кода, который:

  • Получает текущее время: ваш код может получать значения для текущего года, месяца (1-12), дня месяца (1-31), часа (0-23) и минуты (0-59) и дня недели. (вы можете выбрать, будет ли этот номер начинаться с 0 или 1, и если 0/1 означает воскресенье, понедельник или любой другой день); в качестве альтернативы вы можете получить структуру , такую как Date, DateTime, Calendarили в любое другое время , связанной структурой, если ваш язык позволяет. Вы также можете получить строку с датой в, yyyyMMddHHmmесли хотите, или две отдельные строки для даты и времени, а затем целое число с днем ​​недели. Не стесняйтесь.
  • Возвращает два непротиворечивых значения true и falsey , указывающие, нужно ли отправлять сообщение в рабочий чат или нет.

правила

  • Предполагается, что этот фрагмент кода вызывается периодически. Тем не менее точная периодичность не имеет значения.
  • Истинное значение должно быть возвращено, если днем ​​недели является вторник или четверг, а время - 8:00 с погрешностью 10 минут (с 7:50 до 8:10 включительно).
  • Значение truey должно быть отправлено только в том случае, если код впервые вызывается между этими часами для указанного дня. Мы не хотим, чтобы бот отправлял одно и то же сообщение несколько раз подряд. То, как вы справитесь с этим ограничением, будет зависеть только от вас.
  • Ваш код может быть независимой программой, выполняемой повторно, или он может быть частью большого кода, который всегда выполняется. Твой выбор.
  • Вы можете предположить, что между выполнениями кода перезагрузок не будет.
  • Вы можете предположить, что дата всегда будет правильной.
  • Пояснения о вашем коде и особенно о методе, используемом для достижения постоянства, приветствуются.

Примеры

(Week starts on Monday: 1, the following invokations will be made in succession)
2018,08,27,08,00,1 = falsey (not Tuesday or Thursday)
2018,08,28,07,45,2 = falsey (out of hours)
2018,08,28,07,55,2 = truthy (first time invoked this day at the proper hours)
2018,08,28,08,05,2 = falsey (second time invoked this day at the proper hours)
2018,08,28,08,15,2 = falsey (out of hours)
2018,08,29,08,00,3 = falsey (not Tuesday or Thursday)
2018,08,29,18,00,3 = falsey (not Tuesday or Thursday)
2018,08,30,07,49,4 = falsey (out of hours)
2018,08,30,07,50,4 = truthy (first time invoked this day at the proper hours)
2018,08,30,07,50,4 = falsey (second time invoked this day at the proper hours)
2018,08,30,08,10,4 = falsey (third time invoked this day at the proper hours)
2018,08,30,08,11,4 = falsey (out of hours)
2018,09,04,08,10,2 = truthy (first time invoked this day at the proper hours)

Это , поэтому может выиграть самый короткий код для каждого языка!


Это происходит из песочницы .
Чарли

Есть ли ограничения в формате ввода? Могу ли я взять дату как один параметр, например, YYYYmmddи время HHss?
Луис Фелипе Де Иисус Муньос

1
@LuisfelipeDejesusMunoz да, если вы хотите, вы можете получить дату и время в этом формате. Я обновил вопрос, чтобы прояснить это.
Чарли

1
@KamilDrakari программа должна проверить дату, указанную в качестве параметра, вы не можете взять текущую дату. Если вы сделаете это, код не сможет пройти тестовую батарею, подобную той, которую я предлагаю в этом вопросе.
Чарли

2
Итак, вы регулярно опрашиваете сценарий, чтобы он был полезен не чаще одного раза в день, 2/7 дня? Если вы автоматизируете все свои задачи, как это ...
Mast

Ответы:


15

JavaScript (ES6), 43 байта

f=(D,t,d)=>5>>d&t>749&t<811&&!f[D]*(f[D]=1)

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

вход

  • дата в виде строки в yyyymmdd формате
  • время в виде строки в hhmm формате
  • день недели в виде целого числа с 0 индексами, со 0= вторник, 1= среда, ...,6 = понедельник

Выход

Возвращает 0или1 .

комментарии

f = (            // named function, as the underlying object will be used as storage
  D,             // D = date (string)
  t,             // t = time (string)
  d              // d = day of week (integer)
) =>             //
  5              // 5 is 0000101 in binary, where 1's are set for Tuesday and Thursday
  >> d &         // test the relevant bit for the requested day of week
  t > 749 &      // test whether we are in the correct time slot
  t < 811        //
  && !f[D] *     // make sure that this date was not already invoked at a correct time
  (f[D] = 1)     // and store it in the underlying object of f()

7
Javascript (и твое мастерство) всегда будут меня удивлять.
Чарли

1
С ES6 интересно играть в гольф :) 2-й формат ввода действителен?
Арно

Да, я уже указал это в тексте вопроса.
Чарли

5

Python 3 , 69 байт

f=lambda w,r,*t,l={0}:r not in l!=w in(2,4)<(7,49)<t<(8,11)!=l.add(r)

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

Принимает данные как f(day of the week, date, hours, minutes), где дата может быть в любом согласованном формате.


5

APL (Dyalog Unicode) , 61 53 50 48 37 36 байт SBCS

Анонимный инфикс лямбда. Вызывается YYYYMMDD f hhmmи затем запрашивает номер дня недели; 2 и 4 вторник и четверг. Переопределяет глобальные, Dчтобы запомнить даты.

D←⍬
{≢D,←⍺/⍨(⎕∊2 4)∧(⍺∊D)<30≥|780-⍵}

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

D←⍬ инициализировать, Dчтобы быть пустым набором

{... } анонимная лямбда; это YYYYMMDD, это hhmm
780-⍵ разница между 780 (среднее значение из 0750 и 0810) , а время
| абсолютное значение , что
30≥ является 30 больше или равно , что?
(... )< и это не так:
  ⍺∊D дата является членом D
(... )∧ и это правда, что:
  ⎕∊2 4 запрос дня недели является членом набора {2,4}, который
⍺/⍨ используется для сжатия даты (т. Е. Дает {}, если ложно, {date}, если true)
D,← добавить это D
 и вернуть его счет (то есть 0 или 1, которые являются ложными и истинными для APL)


4

Формула Excel, 85 байт

=IF(AND(MID(WEEKDAY(A1)/0,684;3;1)="3";A1-INT(A1)>=0,32638;A1-INT(A1)<=0,34028);TRUE)

День недели без параметров: от 1 (воскресенье) до 7 (суббота). Дни, которые мы хотим, - это 3 и 5. Разделив все числа от 1 до 7 на 0 648, только 3 и 5 дают результат, где первое десятичное число равно 3 (Получилось делением с помощью rand ())

Вход вставлен в ячейку A1


Вы можете использовать, MID(WEEKDAY(A1)/0,29;5;1)="4"а также ;1;)вместо;TRUE)
adebunk

4

Чистый , 343 326 303 279 216 байт

Чистота настолько плохо подходит для этого, что это все равно что пытаться нарисовать забор бензопилой.

import StdEnv,System.Environment,System._Unsafe
?(y,x,z)=y*480+x*40+z
$y h m d=(d-3)^2==1&&((h-8)*60+m)^2<121&&appUnsafe(setEnvironmentVariable"l"(fromInt(?y)))(maybe 0toInt(accUnsafe(getEnvironmentVariable"l")))< ?y

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

Гольф тогда объяснение.


1
+1 Просто за покраску забора со ссылкой на бензопилу! : D
Вечный J

4

R , 114 106 байт

function(D,y=D:"%D",u=D$h==7&D$mi>49|D$h==8&D$mi<11&D$w%in%2^4&!y%in%L,`:`=format,`^`=c){L<<-L^y[u];u}
L=F

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

Упорство:

Дата сверяется с L списком дат, где код вернул TRUE. Когда код возвращает TRUE, сегодняшняя дата добавляется в этот список. В противном случае список не изменяется.

Сохранено 6 байтов благодаря @Giuseppe!

Сделал код на самом деле работать и сэкономил 2 байта благодаря @digEmAll!


Этот метод берет текущее время вместо получения его в качестве параметра, не так ли?
Чарли

@Charlie выглядит, я должен был прочитать задачу более внимательно ... сделал бы мою жизнь проще! Я буду обновлять.
JayCe

^имеет более высокий приоритет, чем, %any%но *имеет более низкий приоритет, чем %any%, поэтому с помощью ^вы можете избавиться от некоторых круглых скобок, и я также проиграл несколько больше! Уверен, что он работает на 108 байтов
Джузеппе

1
Вы можете также использовать :вместо этого ^, для удовольствия, и поэтому ваш код содержит миллион :.
Джузеппе

@Giuseppe У него есть тонна :сейчас!
JayCe

3

C (gcc) ,  78   50  49 байтов

D;f(d,w,t){w=d-D&&w<4&&w%2&&t>749&&t<811&&(D=d);}

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

Ожидаемые входные данные:

  • d: дата, как одно число yyyymmdd
  • w: день недели, начиная с понедельника (0)
  • t: время, как одно число hhmm

объяснение

D;                                      // the date we last said hello.
f(d,                                    // date
    w,                                  // day of the week
      t)                                // time
{
  w=                                    // replaces return
    d-D                                 // if we did not say hello today
       &&w<4&&w%2                       // and we are Tuesday(1) or Thursday(3)
                 &&t>749&&t<811         // and time is between 7:50 and 8:10, inclusive
                               &&(D=d); // then we say hello (evaluated to true) and update D
}

Правки

  • Сохранено 28 байтов благодаря Адаму
  • Сохранено еще 1 байт, так abs()как фактически не помогло с новой версией

1
Почему бы не взять YYYYMMDDи hhmmкак отдельные цифры?
Адам

@ Adám Действительно ... я попробую это, когда у меня будет немного времени
Annyo

Предлагать w<4&w%2&t>749&t<811 вместоw<4&&w%2&&t>749&&t<811
floorcat

2

Пакетный, 109 байтов

@if %3 neq 2 if %3 neq 4 exit/b1
@if %2 geq 07:50 if %2 leq 08:10 if .%1 neq .%l% set l=%1&exit/b0
@exit/b1

Принимает ввод в форме, date time dowнапример, 2018-09-04 08:10 2и выводит через код выхода. Объяснение: Переменная среды l(или любая другая отдельная буква будет работать) используется для хранения последней успешной даты, прошедшей тест. (Сам формат даты не имеет значения, если он согласован и не содержит пробелов.)



1

C # , 121 байт

int[] d=new int[]{2,4};
double s=>Now.TimeOfDay.TotalSeconds;
bool h=>d.Contains((int)Now.DayOfWeek)&&s>=470&&s<=490;

Перемещение всех трех строк в одну строку уменьшает размер до 117байтов. hиспользуется как свойство, просто прочитайте значение перед отправкой сообщения:

if (h) SendMessage();

1

F #, 119 байт

let f w d h m l = if not(l|>Seq.contains d)&&[3;5]|>Seq.contains w&&(h=7&&m>49||h=8&&m<11)then(l@[d],true)else(l,false)

let f w d h m l =

объявить функцию, вызываемую fс параметрами w(день недели) d(дата) h(час) m(минута) l(список дат, в которые она запускается)

if not(l|>Seq.contains d) если список дат не содержит пройденную дату

&&[3;5]|>Seq.contains w а вторник (3) или среда (5)

&&(h=7&&m>49||h=8&&m<11) и время между (эксклюзивно) 7:49 и 8:11

then(l@[d],true) затем вернуть кортеж, содержащий список дат с добавленной текущей датой, и true

else(l,false) иначе вернуть кортеж, содержащий список дат без сегодняшнего дня и false


0

Bash 95 87 байт

[ $(ps -ef|grep $0|wc -l) -gt 3 -o $2 -lt 750 -o $2 -gt 810 ]||((10>>$3&1))&&sleep 20m

Редактировать: сэкономил 8 байт, украдя идею от Annyo

Звоните с ггггммдд ЧЧММ D, с D, начиная с 0, на понедельник.

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

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


Если вы не используете дату, как вы проверяете, что не отправляете сообщение дважды за один и тот же день?
Чарли

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