Bot powitalny dla kolegi z pracy

14

Mam w pracy kolegę, który pracuje z domu w każdy wtorek i czwartek. Około 8:00 wysyła nam wiadomość z następującym tekstem:

Witam dzisiaj Pracuję z domu

Aby uwolnić go od ciężaru wykonywania codziennych czynności w domu, chcielibyśmy zautomatyzować to zadanie.

Wyzwanie

Wpisz jak najmniej bajtów fragmentu kodu, który:

  • Odbiera bieżącą godzinę: Twój kod może odbierać wartości dla bieżącego roku, miesiąca (1-12), dnia miesiąca (1-31), godziny (0-23) i minuty (0-59) oraz dnia tygodnia (możesz wybrać, czy ten numer zaczyna się od 0 czy 1, a jeśli 0/1 oznacza niedzielę, poniedziałek lub inny dzień); alternatywnie można otrzymać struktury takie jak Date, DateTime, Calendarlub jakakolwiek inna struktura czasu powiązanymi, jeżeli język na to pozwala. Możesz również otrzymać ciąg z datą, yyyyMMddHHmmjeśli chcesz, lub dwa osobne ciągi dla daty i godziny, a następnie liczbę całkowitą z dniem tygodnia. Nie krępuj się.
  • Zwraca dwie spójne wartości true i falsey , wskazując, czy wiadomość musi zostać wysłana do czatu roboczego, czy nie.

Zasady

  • Zakłada się, że ten fragment kodu jest okresowo wywoływany. Dokładna okresowość nie ma jednak znaczenia.
  • Prawdziwa wartość musi zostać zwrócona, jeśli dniem tygodnia jest wtorek lub czwartek, a godzina 8:00 z marginesem błędu wynoszącym 10 minut (od 7:50 do 8:10 włącznie).
  • Prawdziwa wartość musi zostać wysłana tylko wtedy, gdy kod jest wywoływany po raz pierwszy między tymi godzinami dla określonego dnia. Nie chcemy, aby bot wysyłał tę samą wiadomość kilka razy z rzędu. Sposób zarządzania tym ograniczeniem zależy wyłącznie od Ciebie.
  • Twój kod może być niezależnym programem wykonywanym wielokrotnie lub może być częścią większego kodu, który zawsze działa. Twój wybór.
  • Możesz założyć, że między uruchomieniami kodu nie będzie restartów.
  • Możesz założyć, że data będzie zawsze poprawna.
  • Zalecane są objaśnienia dotyczące Twojego kodu, a zwłaszcza metody zastosowanej do uzyskania trwałości.

Przykłady

(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)

To jest , więc wygra najkrótszy kod dla każdego języka!

Charlie
źródło
To pochodzi z piaskownicy .
Charlie
Czy są jakieś ograniczenia w formacie wejściowym? Czy mogę przyjąć datę jako pojedynczy parametr, jak YYYYmmddrównież godzinę HHss?
Luis felipe De jesus Munoz
1
@LuisfelipeDejesusMunoz tak, jeśli chcesz, możesz otrzymać datę i godzinę w tym formacie. Zaktualizowałem pytanie, aby to wyjaśnić.
Charlie
1
@KamilDrakari program musi sprawdzić datę podaną jako parametr, nie można pobrać bieżącej daty. Jeśli to zrobisz, nie będzie możliwe, aby kod przeszedł testową baterię taką jak ta, którą proponuję w pytaniu.
Charlie
2
Czyli regularnie odpytujesz skrypt, aby był przydatny co najwyżej raz dziennie, 7 dni w tygodniu? Jeśli zautomatyzujesz wszystkie swoje zadania w ten sposób ...
Mast

Odpowiedzi:

15

JavaScript (ES6), 43 bajty

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

Wypróbuj online!

Wejście

  • data jako ciąg znaków w yyyymmdd formacie
  • czas jako ciąg znaków hhmm formacie
  • dzień tygodnia jako liczba całkowita o indeksie 0, z 0= wtorek, 1= środa, ..., 6= poniedziałek

Wynik

Zwraca 0lub 1.

Skomentował

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()
Arnauld
źródło
7
JavaScript (i twoje opanowanie go) zawsze mnie zadziwią.
Charlie
1
ES6 jest fajny do gry w golfa :) Czy drugi format wejściowy jest prawidłowy?
Arnauld
Tak, już to określiłem w tekście pytania.
Charlie
5

Python 3 , 69 bajtów

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

Wypróbuj online!

Pobiera dane wejściowe jako f(day of the week, date, hours, minutes), gdzie data może być w dowolnym spójnym formacie.

ovs
źródło
5

APL (Dyalog Unicode) , 61 53 50 48 37 36 bajtów SBCS

Anonimowy przyrostek lambda. Zadzwoniono z, YYYYMMDD f hhmma następnie monituje o numer dnia tygodnia; 2 i 4 to wtorek i czwartek. Na nowo definiuje globalne, Daby zapamiętać daty.

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

Wypróbuj online!

D←⍬ zainicjować D aby być pustym zestawem

{} Anonimowa lambda; jest YYYYMMDD, to hhmm
780-⍵ różnica pomiędzy 780 (średnia z 0750 i 0810), a w czasie
| wartość ta bezwzględna
30≥ jest większa lub równa 30 do?
()< I nie jest prawdą, że:
  ⍺∊D data jest członkiem D
()∧ i prawdą jest, że:
  ⎕∊2 4 monitowany o dzień tygodnia jest członkiem zestawu {2,4}
⍺/⍨ używającego tego do kompresji daty (tzn. Daje {} jeśli fałsz, {date} jeśli prawda)
D,← dołącz to D
 i zwróć jej sumę (tj. 0 lub 1, które są fałszem i prawdą APL-a)

Adám
źródło
4

Formuła Excel, 85 bajtów

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

Dzień tygodnia bez parametrów to od 1 (niedziela) do 7 (sobota). Potrzebne dni to 3 i 5. Dzieląc wszystkie liczby od 1 do 7 dla 0,648, tylko 3 i 5 daje wynik, w którym pierwsza liczba dziesiętna to 3 (Zdobądź to, dzieląc za pomocą rand ())

Dane wejściowe są wstawiane do komórki A1

Moacir
źródło
Możesz użyć, MID(WEEKDAY(A1)/0,29;5;1)="4"a także ;1;)zamiast;TRUE)
adebunk 28.08.18
4

Czysty , 343 326 303 279 216 bajtów

Clean jest do tego nieodpowiedni, to tak, jakby próbować pomalować płot piłą łańcuchową.

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

Wypróbuj online!

Gra w golfa, a następnie wyjaśnienie.

Obrzydliwe
źródło
1
+1 Tylko do malowania ogrodzenia z odniesieniem do piły łańcuchowej! : D
Emma - PerpetualJ
4

R , 114 106 bajtów

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

Wypróbuj online!

Trwałość:

Data jest porównywana z L listą dat, w których kod zwrócił wartość PRAWDA. Gdy kod zwraca wartość PRAWDA, dzisiejsza data jest dołączana do tej listy. W przeciwnym razie lista nie zostanie zmodyfikowana.

Zaoszczędź 6 bajtów dzięki @Giuseppe!

Sprawił, że kod faktycznie działał i zaoszczędził 2 bajty dzięki @digEmAll!

JayCe
źródło
Ta metoda zajmuje aktualny czas zamiast odbierania go jako parametru, prawda?
Charlie
@Charlie wygląda II powinien był uważniej przeczytać wyzwanie ... ułatwiłoby mi to życie! Zaktualizuję.
JayCe
^ma wyższy priorytet niż, %any%ale *ma niższy priorytet %any%, więc używając ^możesz pozbyć się nawiasów, a ja też grałem w golfa jeszcze trochę! Całkiem pewne, że działa dla 108 bajtów
Giuseppe
1
Możesz również użyć :zamiast ^, dla zabawy, a więc twój kod zawiera milion :.
Giuseppe
@Giuseppe To ma :teraz mnóstwo !
JayCe
3

C (gcc) ,  78   50  49 bajtów

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

Wypróbuj online!

Oczekiwane dane wejściowe to:

  • d: data, jako pojedynczy numer yyyymmdd
  • w: dzień tygodnia, począwszy od poniedziałku (0)
  • t: czas jako pojedynczy numer hhmm

Wyjaśnienie

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
}

Edycje

  • Zaoszczędzono 28 bajtów dzięki Adámowi
  • Zapisano jeszcze 1 bajt, ponieważ abs()tak naprawdę nie pomagał w nowej wersji
Annyo
źródło
1
Dlaczego nie wziąć YYYYMMDDi hhmmjako pojedyncze liczby?
Adám
@ Adám Rzeczywiście ... Spróbuję tego, kiedy będę miał trochę czasu
Annyo
Zaproponuj w<4&w%2&t>749&t<811zamiastw<4&&w%2&&t>749&&t<811
ceilingcat
2

Partia, 109 bajtów

@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

Pobiera dane wejściowe w postaci date time downp. 2018-09-04 08:10 2I dane wyjściowe za pomocą kodu wyjścia. Objaśnienie: Zmienna środowiskowa l(lub dowolna inna pojedyncza litera będzie działać) służy do przechowywania ostatniej pomyślnej daty, która pozytywnie przejdzie test. (Sam format daty nie ma znaczenia, dopóki jest spójny i nie zawiera spacji.)

Neil
źródło
2

Perl 6 , 33 bajtów

{811>$^t>749>5+>$^w%2>(%){$^d}++}

Wypróbuj online!

Mocno zainspirowany rozwiązaniem Arnaulda. Używa tego samego formatu wejściowego.

nwellnhof
źródło
1

C # , 121 bajtów

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

Przeniesienie wszystkich trzech do tej samej linii zmniejsza rozmiar do 117bajtów. hjest używany jako właściwość, po prostu przeczytaj wartość przed wysłaniem wiadomości:

if (h) SendMessage();
Emma - PerpetualJ
źródło
1

F #, 119 bajtów

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 =

deklaruj wywołaną funkcję fz parametrami w(dzień tygodnia) d(data) h(godzina) m(minuta) l(lista dat, w których jest uruchamiana)

if not(l|>Seq.contains d) jeśli lista dat nie zawiera daty minionej

&&[3;5]|>Seq.contains w a dzień to wtorek (3) lub środa (5)

&&(h=7&&m>49||h=8&&m<11) a czas jest pomiędzy (wyłączny) 7:49 a 8:11

then(l@[d],true) następnie zwróć krotkę zawierającą listę dat z dołączoną bieżącą datą i true

else(l,false) w przeciwnym razie zwróć krotkę zawierającą listę dat bez dzisiaj i fałsz

nacięcie
źródło
0

Bash 95 87 bajtów

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

Edycja: zapisano 8 bajtów poprzez kradzież pomysłu od Annyo

Zadzwoń do HYMM D rrrrmmdd, z D rozpoczynającym się od 0, w poniedziałek.

Nie jestem do końca pewien, dlaczego ustawiłem sprawdzanie liczby wierszy na trzy, wydaje się, że powinny być dwa, ale dwa nie działają, a trzy działają.

Poza tym nie zawracałem sobie głowy użyciem daty, ale wymagania wydają się wskazywać, że powinniśmy zaakceptować datę, więc wybrałem wspomnianą opcję, aby wziąć czas osobno i po prostu zignorować wartość daty.

crystalgecko
źródło
Jeśli nie użyjesz daty, jak sprawdzisz, czy nie wysłałeś wiadomości dwukrotnie tego samego dnia?
Charlie,
Trzyma się przez 20 minut, a pierwsza kontrola upewnia się, że nie ma uruchomionej kopii
crystalgecko