Computação de folhas de ponto


14

Folhas de ponto

Em um local de trabalho, você geralmente precisa preencher folhas de ponto. Esta tarefa é escrever código para ajudar nisso.

Entrada

Duas vezes em um relógio de 12 horas ligeiramente fora do padrão, significando o início e o fim do dia separados por um espaço. Um terceiro número representa o número de minutos necessários para o almoço. Por exemplo

9:14 5:12 30

Isso significa que você começou a trabalhar às 9h14, terminou o trabalho às 17h12 e levou 30 minutos para o almoço.

Você pode assumir que

  • Qualquer horário na primeira coluna é das 00:00 (meia-noite) até às 13:00, mas não inclui, e qualquer horário na segunda coluna é 13:00 no mínimo, até 23:59.
  • O intervalo para o almoço não é mais do que o dia útil!

O formato de entrada deve ser como nos exemplos fornecidos.

Tarefa

Seu código deve ler um arquivo (ou entrada padrão) desses triplos e, para cada um, gerar quanto tempo você trabalhou. Esta saída deve indicar o número de horas. Para o exemplo acima, isso é:

7hr e 58min menos 30 minutos, que é 7hr 28min.

Resultado

Sua saída deve especificar o número (inteiro) de horas e minutos e não deve listar mais de 59 minutos. Ou seja, você não pode emitir 2 horas e 123 minutos. Além disso, seu código pode ser produzido em qualquer formato de leitura facilmente humano que seja conveniente para você.

Exemplos

10:00 1:00 30    --> 2hr 30min
12:59 1:00 0     --> 0hr 1min
00:00 11:59 0    --> 23hr 59min
10:00 2:03 123   --> 2hr 0min 

3
Não vejo como o formato de entrada estrito ( :horários delimitados no relógio de 12 horas) adiciona algo a esse desafio.
Shaggy

3
@Shaggy analisar o formato de entrada foi a maior parte do desafio para mim, pelo menos, porque você não pode assumir posições de caracteres desde horas poderia ser um ou dois personagens ...
Ryan

O código precisa ler várias linhas? Ou é suficiente se ler uma linha?
Luis Mendo

1
Sim, o código precisa aceitar várias linhas.
Anush

5
@ mbomb007 Você pode fazer voto negativo, mas não gostar do formato de entrada não é um motivo para o VTC.
Okx 28/07/19

Respostas:



5

Retina 0.8.2 , 83 bytes

\d+
$*
 (1+:)
 12$*1$1
+`1:
:60$*
(1*) :\1(1*)(1*) \2
$3
:(1{60})*(1*)
$#1hr $.2min

Experimente online! O link inclui casos de teste. Explicação:

\d+
$*

Converta a entrada para unário.

 (1+:)
 12$*1$1

Adicione 12 horas ao tempo de parada.

+`1:
:60$*

Multiplique as horas por 60 e adicione aos minutos.

(1*) :\1(1*)(1*) \2
$3

Subtraia a hora de início e a pausa do tempo de parada.

:(1{60})*(1*)
$#1hr $.2min

Divmod por 60. (Economize 5 bytes para um formato de saída mais chato.)



4

Python 3, 161 bytes

Eu sei que isso nem será o menor, mas ele será lido em um arquivo:

for l in open('t'):
    l=l[:-1].split(':')
    m=-int(l[0])*60+int(l[1][:2])+(int(l[1][3:])*60+720+int(l[2][:2])-int(l[2][2:]))
    print(f'{m//60}hr {m-(m//60*60)}min')

Estou sentindo a ironia de pausar meu quadro de horários para fazer isso ...

Python 2.7, 133 bytes

Obrigado pelas sugestões nos comentários! Mudar para o python 2.7 economiza mais alguns bytes porque o padrão é a divisão inteira:

for l in open('t'):i,h,l=int,60,l[:-1].split(':');m=-i(l[0])*h+i(l[1][:2])+(i(l[1][3:])*h+720+i(l[2][:2])-i(l[2][2:]));print m/h,m%60

A mesma abordagem com python3 é de 135 bytes por causa da instrução print e por padrão na divisão float:

for l in open('t'):i,h,l=int,60,l[:-1].split(':');m=-i(l[0])*h+i(l[1][:2])+(i(l[1][3:])*h+720+i(l[2][:2])-i(l[2][2:]));print(m//h,m%60)

1
Você pode salvar 4 bytes colocando i=intno início e alterando a terceira linha param=-i(l[0])*60+i(l[1][:2])+(i(l[1][3:])*60+720+i(l[2][:2])-i(l[2][2:]))
DJMcMayhem

@DJMcMayhem Thank you! Eu estava tentando pensar em uma maneira de simplificar os ...
Ryan

2
Primeira resposta muito boa, bem-vindo ao Programming Puzzles & Code Golf! Para ajudar a jogar um pouco de golfe, você pode receber informações do STDIN, usar map(int,l[:-1].split(':'))e soltar as várias conversões para int, recolher tudo em uma linha, substituindo o recuo por ;etc. para economizar alguns bytes. Além disso, você pode visitar Dicas para jogar golfe em Python, para mais truques interessantes que outros usuários descobriram durante a vida de golfistas :).
Mr. Xcoder

1
Além disso, o OP parece ser menos restritivo sobre o formato de saída , então acho que print(m,m%60)seria suficiente. (Observe também o uso de m%60no lugar de m-(m//60*60))
Mr. Xcoder

@ Mr.Xcoder Obrigado!
21718 Ryan

4

C, 105 bytes

a,b,c,d,e;f(){for(;scanf("%d:%d%d:%d%d",&a,&b,&c,&d,&e);)a=(12+c-a)*60+d-b-e,printf("%d:%d ",a/60,a%60);}

Completamente simples. Experimente online aqui .

Ungolfed:

a, b, c, d, e; // start hours, minutes; end hours, minutes; break - all implicitly int
f() { // function - return type is implicitly int (unused)
    for(; scanf("%d:%d%d:%d%d", &a, &b, &c, &d, &e) ;) // until EOF is hit, read line by line
        a = (12 + c - a) * 60 + d - b - e, printf("%d:%d,", a / 60, a % 60); // calculate the minutes and store, then output separated: "h m"
}

Sugerir em a,b,c,d;f(e)vez de a,b,c,d,e;f()e em ;printf("%d:%d ",a/60,a%60))a=(12+c-a)*60+d-b-e;}vez de;)a=(12+c-a)*60+d-b-e,printf("%d:%d ",a/60,a%60);
tetocat 25/10

4

Wolfram Language 125 119 111 bytes

i=Interpreter;j=IntegerPart;Row@{j[t=(i["Time"][#2<>"pm"]-i["Time"][#])[[1]]-#3/60],"hr ",j[60Mod[t,1]],"min"}&

8 bytes salvos graças ao usuário 202729

Exemplo

Abreviações não são usadas aqui, para facilitar o acompanhamento da lógica.

Row[{IntegerPart[
 t = (Interpreter["Time"][#2 <> "pm"] - 
      Interpreter["Time"][#])[[1]] - #3/60], "hr ",
IntegerPart[60 Mod[t,1]], "min"}] &["9:00", "4:12", 20]

6h 51min

Interpreter["Time"][#2 <> "pm"] interpreta como uma hora o segundo parâmetro seguido por "pm", ou seja, neste caso, "16:12", retornando um TimeObjectcorrespondente a 16:12.

-Interpreter["Time"][# <> "am"])[[1]] - #3/60]. #3é o terceiro parâmetro, ou seja, 20min. O sinal de menos subtrai o intervalo da hora do almoço do final do horário do turno. Ele retorna o horário de fim de turno ajustado, ou seja, o final do turno que seria aplicado se a pessoa não tivesse feito uma pausa para o almoço.

Interpreter["Time"][#] interpreta como um horário o primeiro parâmetro, neste caso, "9:00", retornando um TimeObjectcorrespondente às 9:00.

Subtraindo o início do turno do rendimento ajustado no final do turno t, o intervalo de tempo expresso em horas. IntegerPart[t]retorna o número de horas completas trabalhadas. IntegerPart[60 Mod[t,1]], "min"}]retorna os minutos adicionais trabalhados.


Sim. Obrigado. Primeira vez que vejo Mod[x, 1]usado.
28918

Retirado deste dicas (excluídas) . / Na verdade, o mod 1 se comporta de maneira diferente da parte fracionária para o número negativo. / Pode Floorser usado para IntegerPart?
user202729

Floor retorna um resultado inexplicável de -6hr 52min para os valores de amostra que usei. Eu preciso analisar isso para entender por que um valor negativo por horas (e aparentemente minutos) foi produzido.
30818

3

JavaScript, 83 bytes 76 bytes

s=>(r=s.match(/\d+/g),r=(r[2]-r[0]+12)*60-r[4]-r[1]+ +r[3],(r/60|0)+':'+r%60)

Acabei de me livrar da função interna da solução abaixo (O que eu estava pensando?). Alterou o formato de saída também.

Experimente online!


ANTIGO: JavaScript, 112 bytes 111 bytes 110 bytes

s=>(t=(h,m,a)=>(a?12+h:h)*60+m,r=s.match(/\d+/g),r=t(+r[2],r[3]-r[4],1)-t(r[0],+r[1]),`${r/60|0}hr ${r%60}min`)

Explicação:

Dentro da função principal, começamos definindo outra que nos ajudará a calcular os minutos de um tempo determinado, adicionando 12 horas ao parâmetro horas se o terceiro parâmetro for verdadeiro:

(hours, minutes, addTwelve) =>
    (addTwelve? hours + 12: hours) * 60 + minutes

Em seguida, dividimos a sequência por ' 'ou':' combinamos os números dentro da sequência, resultando em uma matriz de todos os números da sequência.

Em seguida, calculamos a diferença de horário final e de início e de subtrair a hora do almoço usando a função definida anteriormente (convertendo as strings em números quando necessário).

Finalmente, produzimos a sequência de resultados: horas são a parte inteira de r/60 e minutos r%60.

Experimente online!


@ Jakob Eu sou um novo usuário de codegolf. Ainda não sei como as coisas funcionam por aqui, incluindo o TIO. Também perguntei neste comentário como eu abordaria isso usando javascript, mas ninguém respondeu.
ibrahim mahrir

@Jakob TIO corrigido. E não estou usando o NodeJS, estou usando o console do navegador. O NodeJS foi adicionado pelo TIO.
ibrahim mahrir

Ainda não temos certeza de que o método de entrada é legal (esta pergunta infelizmente é restritiva), mas podemos precisar de um jogador de JS mais experiente para participar. Mas observe também que os programas precisam oferecer suporte a vários dias de dados de entrada - infelizmente isso não foi feito muito claro na descrição.
Jakob

@Jakob Se mais dias deve ser usado como entrada eu poderia apenas fazer a função de aceitar uma matriz e uso map: a=>a.map(...). Ele adicionará 5 bytes à minha resposta. Mas ainda estou aguardando a resposta do OP (ou de alguém) ao meu comentário.
ibrahim mahrir

Desde puro JavaScript não tem acesso a entrada padrão ou arquivos, eu sugiro que você vá com o método padrão de usar um GUI prompt: codegolf.meta.stackexchange.com/a/2459/79343
OOBalance

3

Python 2 , 100 bytes

for I in open('x'):x,y,z,w,l=map(int,I.replace(':',' ').split());d=60*(12+z-x)+w-y-l;print d/60,d%60

Experimente online!

Programa completo que lê várias linhas de um arquivo de texto, conforme indicado pelo OP. Uma função que apenas analisa uma única linha salvaria uma adição em todos os 10 bytes.


1
Isso também é muito mais legível do que minha tentativa!
21918 Ryan

3

Java 10, 194 191 bytes

u->{var s=new java.util.Scanner(System.in).useDelimiter("\\D");for(int i,a[]=new int[5];;i=(12+a[2]-a[0])*60+a[3]-a[1]-a[4],System.out.println(i/60+":"+i%60))for(i=0;i<5;)a[i++]=s.nextInt();}

A E / S é dolorosa em Java. Termina de forma anormal quando não há próxima linha de entrada para ler. Experimente online aqui .

Ungolfed:

u -> { // lambda taking a dummy input – we're not using it, but it saves a byte
var s = new java.util.Scanner(System.in).useDelimiter("\\D"); // we use this to read integers from standard input; the delimiter is any character that is not part of an integer
for(int i, a[] = new int[5]; ; // infinite loop; i will be used to loop through each line and to store the result in minutes between lines; a will hold the inputs
    i = (12 + a[2] - a[0]) * 60 + a[3] - a[1] - a[4], // after each line, calculate the result in minutes ...
    System.out.println(i / 60 + ":" + i % 60)) // ... and output the result in hours:minutes, followed by a newline
    for(i = 0; i < 5; ) // read the five integers on the current line ...
        a[i++] = s.nextInt(); // ... into the array
}


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.