Вітальний бот для колеги з роботи


14

У мене є колега по роботі, який працює вдома кожен вівторок і четвер. Близько 8:00 ранку він надсилає нам повідомлення з таким текстом:

Привіт сьогодні я працюю з дому

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

Змагання

Напишіть якомога менше байтів фрагмент коду, який:

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

Правила

  • Передбачається, що цей фрагмент коду періодично викликається. Точна періодичність, тим не менш, не має значення.
  • Справжнє значення потрібно повернути, якщо день тижня - вівторок або четвер, а час - 8:00 ранку з похибкою 10 хвилин (від 7:50 до 8:10 включно).
  • Значення "truthy" має бути надіслане, лише якщо воно вперше викликається між цими годинами протягом зазначеного дня. Ми не хочемо, щоб бот надсилав одне і те ж повідомлення кілька разів поспіль. Як ви керуєте цим обмеженням, буде повністю залежати від вас.
  • Ваш код може бути незалежною програмою, що виконується повторно, або може бути частиною більшого коду, який завжди працює. Твій вибір.
  • Ви можете припустити, що не буде перезавантажень між виконанням коду.
  • Ви можете припустити, що дата завжди буде правильною.
  • Заохочуються пояснення вашого коду та конкретно про метод, який використовується для досягнення наполегливості.

Приклади

(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?
Luis felipe De jesus Munoz

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 - це весело для гри в гольф :) Чи дійсний другий формат вводу?
Арнольд

Так, я вже вказав це в тексті запитання.
Чарлі


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}, якщо є істинним),
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 ())

Введення вставляється в комірок А1


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

4

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

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

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
Емма - PerpetualJ

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, сьогоднішня дата додається до цього списку. Інакше список не змінюється.

Збережено 6 байт завдяки @Giuseppe!

Завдяки @digEmAll код дійсно працював і врятував 2 байти!


Цей метод приймає поточний час замість того, щоб отримувати його як параметр, чи не так?
Чарлі

@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 байт завдяки Adám
  • Збережено ще 1 байт, оскільки abs()насправді не допомагає нова версія

1
Чому б не взяти YYYYMMDDі hhmmяк одиничні числа?
Adám

@ Adám Дійсно ... Я спробую це, коли в мене з’явиться певний час
Annyo

Запропонувати w<4&w%2&t>749&t<811замістьw<4&&w%2&&t>749&&t<811
roofcat

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


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

Телефонуйте з yyyymmdd HHMM D, D починаючи з 0, у понеділок.

Я не зовсім впевнений, чому у мене встановлено перевірку кількості ліній на три, здається, це повинно бути два, але два не вдається працювати і три, здається, працюють.

Крім того, я не переймався датою, але, схоже, вимоги вказують на те, що ми повинні прийняти дату, тому я взяв вказаний варіант взяти час окремо і просто ігнорувати значення дати.


Якщо ви не використовуєте дату, як перевірити, чи не надсилаєте повідомлення двічі за один і той же день?
Чарлі

Він тримається протягом 20 хвилин, і перша перевірка гарантує, що не існує існуючої копії
crystalgecko
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.