Um bot de saudação para um colega de trabalho

14

Eu tenho um colega de trabalho que trabalha em casa toda terça e quinta-feira. Por volta das 8:00 da manhã, ele nos envia uma mensagem com o seguinte texto:

Olá hoje eu estou trabalhando em casa

Para aliviá-lo do fardo de fazer isso todos os dias em que ele fica em casa, gostaríamos de automatizar essa tarefa para ele.

O desafio

Escreva no mínimo de bytes possível um pedaço de código que:

  • Recebe a hora atual: seu código pode receber valores para o ano atual, mês (1-12), dia do mês (1-31), hora (0-23) e minuto (0-59) e dia da semana (você pode escolher se esse número começa em 0 ou 1 e se 0/1 significa domingo, segunda ou qualquer outro dia); Alternativamente, você pode receber uma estrutura como Date, DateTime, Calendarou qualquer outra estrutura relacionados com o tempo, se a sua linguagem permite isso. Você também pode receber uma sequência com a data, yyyyMMddHHmmse desejar, ou duas sequências separadas para data e hora e, em seguida, um número inteiro com o dia da semana. Fique à vontade.
  • Devoluções dois consistentes truthy e Falsey valores, que indicam se a mensagem deve ser enviada para o bate-papo funcionar ou não.

Regras

  • Presume-se que esse trecho de código seja chamado periodicamente. A periodicidade exata é irrelevante, no entanto.
  • O valor de verdade deve ser retornado se o dia da semana for terça ou quinta-feira e o horário for 8:00, com uma margem de erro de 10 minutos (inclusive das 7:50 às 8:10).
  • O valor de verdade deve ser enviado apenas se for a primeira vez que o código for chamado entre essas horas no dia especificado. Não queremos que o bot envie a mesma mensagem várias vezes seguidas. A maneira como você gerencia essa restrição depende inteiramente de você.
  • Seu código pode ser um programa independente executado repetidamente ou pode fazer parte de um código maior que está sempre em execução. Sua escolha.
  • Você pode assumir que não haverá reinicializações entre as execuções do código.
  • Você pode assumir que a data sempre estará correta.
  • Explicações sobre seu código e especificamente sobre o método usado para obter persistência são incentivadas.

Exemplos

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

Este é o , portanto, pode ganhar o código mais curto para cada idioma!

Charlie
fonte
Isso vem da caixa de areia .
Charlie
Existe alguma restrição no formato de entrada? Posso considerar a data como um único parâmetro YYYYmmdde a hora também HHss?
Luis felipe De jesus Munoz
1
@LuisfelipeDejesusMunoz sim, se você quiser, poderá receber a data e a hora nesse formato. Atualizei a questão para deixar isso claro.
Charlie
1
@KamilDrakari o programa deve verificar a data indicada como parâmetro, você não pode tirar a data atual. Se você fizer isso, será impossível fazer o código passar por uma bateria de teste como a que proponho na pergunta.
Charlie
2
Então, você está pesquisando regularmente um script para ser útil no máximo uma vez ao dia, 2/7 dos dias? Se você automatizar todas as suas tarefas assim ...
Mast

Respostas:

15

JavaScript (ES6), 43 bytes

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

Experimente online!

Entrada

  • a data como uma sequência no yyyymmddformato
  • o tempo como uma sequência no hhmmformato
  • o dia da semana como um número inteiro indexado 0, com 0= terça-feira, 1= quarta-feira, ..., 6= segunda-feira

Resultado

Retorna 0ou 1.

Comentado

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
fonte
7
Javascript (e seu domínio disso) sempre me surpreenderão.
Charlie
1
O ES6 é divertido de jogar com golf :) O segundo formato de entrada é válido?
Arnauld
Sim, eu já especifiquei isso no texto da pergunta.
Charlie
5

Python 3 , 69 bytes

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

Experimente online!

Aceita entrada como f(day of the week, date, hours, minutes), onde a data pode estar em qualquer formato consistente.

ovs
fonte
5

APL (Dyalog Unicode) , 61 53 50 48 37 36 bytes SBCS

Infix anônimo lambda. Ligado com YYYYMMDD f hhmme depois solicita o número do dia da semana; 2 e 4 são terça e quinta-feira. Redefine o global Dpara lembrar datas.

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

Experimente online!

D←⍬ inicialize Dpara ser um conjunto vazio

{... } lambda anônima; é YYYYMMDD, é hhmm
780-⍵ diferença entre 780 (média de 0750 e 0810) e o tempo de
| valor absoluto que
30≥ é 30 maior ou igual a que?
()< E não é verdade que:
  ⍺∊D a data é membro de D
()∧ e é verdade que:
  ⎕∊2 4 o dia da semana solicitado é um membro do conjunto {2,4}
⍺/⍨ use isso para compactar a data (ou seja, dá {} se falso, {date} se true)
D,← anexa isso D
 e retorna sua contagem (ou seja, 0 ou 1, que são falsas e verdadeiras da APL)

Adão
fonte
4

Fórmula do Excel, 85 bytes

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

O dia da semana sem parâmetros é de 1 (domingo) a 7 (sábado). Os dias que queremos são 3 e 5. Dividindo todos os números de 1 a 7 para 0,648, apenas 3 e 5 dão um resultado em que a primeira casa decimal é 3 (Entendi, dividindo com rand ())

A entrada é inserida na célula A1

Moacir
fonte
Você pode usar MID(WEEKDAY(A1)/0,29;5;1)="4"e também em ;1;)vez de;TRUE)
adebunk 28/08
4

Limpo , 343 326 303 279 216 bytes

Limpar é tão inadequado para isso que é como tentar pintar uma cerca com uma serra elétrica.

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

Experimente online!

Golfing então explicação.

Furioso
fonte
1
+1 Apenas para pintar uma cerca com uma referência de motosserra! : D
Perpétuo J
4

R , 114 106 bytes

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

Experimente online!

Persistência:

A data é verificada L , a lista de datas em que o código retornou TRUE. Quando o código retorna TRUE, a data de hoje é anexada a esta lista. Caso contrário, a lista não será modificada.

Guardado 6 bytes graças a @Giuseppe!

Fez o código realmente funcionar e salvou 2 bytes graças a @digEmAll!

JayCe
fonte
Esse método leva o tempo atual em vez de recebê-lo como parâmetro, não é?
Charlie
@ Charlie parece que eu deveria ter lido o desafio com mais cuidado ... teria tornado minha vida mais fácil! Eu atualizarei.
Jayce
^tem precedência mais alta que, %any%mas *tem precedência mais baixa que %any%, portanto, usando ^você pode se livrar de alguns parênteses, e eu também joguei mais alguns! Certeza que ele funciona para 108 bytes
Giuseppe
1
Você também pode usar em :vez de ^, para se divertir, e assim seu código possui um milhão :.
Giuseppe
@ Giuseppe Tem uma tonelada de :agora!
JayCe
3

C (gcc) ,  78   50  49 bytes

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

Experimente online!

As entradas esperadas são:

  • d: a data, como um número único yyyymmdd
  • w: o dia da semana, começando com segunda-feira (0)
  • t: a hora, como um número único hhmm

Explicação

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
}

Editar% s

  • Guardado 28 bytes graças a Adám
  • Economizou mais 1 byte, pois abs()na verdade não estava ajudando na nova versão
Annyo
fonte
1
Por que não tomar YYYYMMDDe hhmmcomo números únicos?
Adám 28/08/18
@ Adám Na verdade ... Eu vou tentar isso quando eu tiver algum tempo
Annyo
Sugerir em w<4&w%2&t>749&t<811vez dew<4&&w%2&&t>749&&t<811
tetocat 22/09
2

Lote, 109 bytes

@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

Recebe entradas no formato, date time dowpor exemplo, 2018-09-04 08:10 2e saídas via código de saída. Explicação: A variável de ambiente l(ou qualquer outra letra única funcionaria) é usada para armazenar a última data bem-sucedida que passa no teste. (O formato da data em si não importa, desde que seja consistente e não contenha espaços.)

Neil
fonte
2

Perl 6 , 33 bytes

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

Experimente online!

Fortemente inspirado na solução de Arnauld. Usa o mesmo formato de entrada.

Nwellnhof
fonte
1

C # , 121 bytes

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

Mover todos os três para a mesma linha reduz o tamanho para 117bytes. hé usado como uma propriedade, basta ler o valor antes de enviar a mensagem:

if (h) SendMessage();
Perpétuo J
fonte
1

F #, 119 bytes

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 =

declarar função chamada fcom parâmetros w(dia da semana) d(data) h(hora) m(minuto)l (lista de datas em que é executada)

if not(l|>Seq.contains d) se a lista de datas não contiver a data passada

&&[3;5]|>Seq.contains w e o dia é terça-feira (3) ou quarta-feira (5)

&&(h=7&&m>49||h=8&&m<11) e o tempo é entre (exclusivo) 7:49 e 8:11

then(l@[d],true) em seguida, retorne uma tupla contendo a lista de datas com a data atual anexada e true

else(l,false) caso contrário, retorne uma tupla contendo a lista de datas sem hoje e false

usuario
fonte
0

Bash 95 87 bytes

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

Editar: salvou 8 bytes roubando uma ideia do Annyo

Ligue com aaaammdd HHMM D, com D começando em 0, para segunda-feira.

Não sei bem por que tenho a verificação de contagem de linhas definida como três, parece que deve ser dois, mas dois não funcionam e três parecem funcionar.

Além disso, não me incomodei em usar a data, mas os requisitos parecem indicar que devemos aceitar a data, por isso tomei a opção mencionada para dedicar o tempo separadamente e simplesmente ignorar o valor da data.

crystalgecko
fonte
Se você não usa a data, como verifica se não envia a mensagem duas vezes para o mesmo dia?
Charlie
Ele permanece por 20 minutos e os primeiros garante seleção que não há uma cópia existente em execução
crystalgecko