Таблицы вычислений

14

Таблицы времени

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

вход

Два раза в слегка нестандартных 12-часовых часах, обозначающих начало и конец дня, разделенных пробелом. Третье число представляет количество минут, затраченных на обед. Например

9:14 5:12 30

Это означает, что вы начали работу в 9:14, закончили работу в 5:12 и заняли 30 минут на обед.

Вы можете предположить, что

  • Любое время в первом столбце - с 00:00 (полночь) до 13:00, но не включая 13:00, а любое время во втором столбце - не позднее 13:00 до 23:59.
  • Перерыв на обед не дольше рабочего дня!

Формат ввода должен быть таким, как в приведенных примерах.

задача

Ваш код должен прочитать в файл (или стандартный ввод) этих троек, и для каждого из них вывести, как долго вы работали. Этот вывод должен указывать количество часов. Для приведенного выше примера это:

7 часов и 58 минут минус 30 минут, что составляет 7 часов 28 минут.

Выход

Ваш вывод должен указывать (целое) количество часов и минут и не должен содержать более 59 минут. То есть вы не можете вывести 2 часа 123 минуты. Кроме того, ваш код может выводиться в любом удобном для вас формате, удобном для вас.

Примеры

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
Я не вижу, как строгий формат ввода ( :разграничение времени на 12-часовых часах) добавляет что-то к этому вызову.
Лохматый
3
@Shaggy Парсинг формата ввода был для меня самой сложной задачей, по крайней мере, потому что вы не можете предполагать положение символов, поскольку часы могут состоять из одного или двух символов ...
Райан
Код должен читать несколько строк? Или этого достаточно, если он читает одну строку?
Луис Мендо
1
Да, код должен принимать несколько строк.
Ануш
5
@ mbomb007 Вы можете понизить голос, но неприятие формата ввода не является причиной для VTC.
Okx

Ответы:

7

MATL , 28 байт

`jYb0&)YOd.5+wgU13L/- 15XODT

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

Луис Мендо
источник
1
Это очень впечатляет!
Ануш
Разве вывод не должен быть в этом формате "XXhr YYmin"?
Ибрагим Махрир
@ibrahimmahrir В задании говорится, что ваш код может выводиться в любом удобном для вас формате, удобном для вас
Луис Мендо,
1
Ах я вижу! Я собираюсь изменить свой ответ, чтобы сократить его. Благодарность!
Ибрагим Махрир
5

Сетчатка 0.8.2 , 83 байта

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

Попробуйте онлайн! Ссылка включает в себя тестовые случаи. Объяснение:

\d+
$*

Преобразовать ввод в унарный.

 (1+:)
 12$*1$1

Добавьте 12 часов к времени остановки.

+`1:
:60$*

Умножьте часы на 60 и прибавьте к минутам.

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

Вычтите время начала и время перерыва из времени остановки.

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

Divmod на 60. (Сохраните 5 байтов для более скучного формата вывода.)

Нил
источник
4

Python 3, 161 байт

Я знаю, что это даже не будет близко к наименьшему, но это читает в файле:

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

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

Python 2,7, 133 байта

Спасибо за предложения в комментариях! Переход на python 2.7 экономит еще несколько байтов, потому что по умолчанию используется целочисленное деление:

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

Тот же самый подход с python3 составляет 135 байтов из-за оператора print и значения по умолчанию для деления с плавающей точкой:

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
Вы можете сэкономить 4 байта, поместив i=intв начале и изменив третью строку наm=-i(l[0])*60+i(l[1][:2])+(i(l[1][3:])*60+720+i(l[2][:2])-i(l[2][2:]))
Джеймс
@DJMcMayhem Спасибо! Я пытался придумать способ упростить это ...
Райан
2
Очень хороший первый ответ, добро пожаловать в Программирование Пазлов и Код Гольф! Чтобы немного помочь в игре в гольф, вы можете получить входные данные из STDIN, использовать map(int,l[:-1].split(':'))и отбрасывать множественные преобразования в int, сворачивать все в одну строку, заменяя отступы ;и т. Д., Чтобы сэкономить пару байтов. Кроме того, вы можете посетить Советы по игре в гольф на Python , чтобы узнать о некоторых хитрых уловках, обнаруженных другими пользователями за время их игры в гольф :).
мистер Xcoder
1
Кроме того, OP, кажется, менее ограничивает формат вывода , поэтому я думаю, что print(m,m%60)будет достаточно. (Также обратите внимание на использование m%60вместо m-(m//60*60))
Мистер Xcoder
@ Mr.Xcoder Спасибо!
Райан
4

C 105 байт

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);}

Совершенно просто. Попробуйте это онлайн здесь .

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"
}
OOBalance
источник
Предлагаю a,b,c,d;f(e)вместо a,b,c,d,e;f()и ;printf("%d:%d ",a/60,a%60))a=(12+c-a)*60+d-b-e;}вместо;)a=(12+c-a)*60+d-b-e,printf("%d:%d ",a/60,a%60);
потолок кошка
4

Wolfram Language 125 119 111 байт

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

8 байтов сохранено благодаря пользователю 202729

пример

Сокращения здесь не используются, чтобы было легче следовать логике.

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

6ч 51мин

Interpreter["Time"][#2 <> "pm"] интерпретирует как время второй параметр, за которым следует «pm», а именно, в данном случае «4:12 pm», возвращая TimeObject соответствующий 16:12.

-Interpreter["Time"][# <> "am"])[[1]] - #3/60], #3это третий параметр, а именно 20мин. Знак минус вычитает интервал обеденного часа из времени окончания смены. Он возвращает скорректированное время окончания смены, то есть конец смены, который был бы применим, если бы человек не взял обеденный перерыв.

Interpreter["Time"][#] интерпретирует как время первый параметр, в данном случае «9:00», возвращая TimeObject соответствующий 9:00 утра.

Вычитая начало смены из скорректированного времени окончания смены, получаем tвременной интервал, выраженный в часах. IntegerPart[t]возвращает количество полных отработанных часов. IntegerPart[60 Mod[t,1]], "min"}]возвращает дополнительные отработанные минуты.

DavidC
источник
Да. Благодарю. Первый раз я вижу Mod[x, 1]крест.
DavidC
Взятые из этого (удаленные) советы . / На самом деле мод 1 ведет себя иначе, чем дробная часть для отрицательного числа. / Может Floorбыть использован для IntegerPart?
user202729
Пол возвращает мне необъяснимый результат -6hr 52minдля значений выборки, которые я использовал. Мне нужно изучить это, чтобы понять, почему было получено отрицательное значение для часов (и, очевидно, минут).
DavidC
3

JavaScript, 83 байта 76 байтов

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

Просто избавился от внутренней функции снизу раствора (о чем я думал?). Также изменился формат вывода.

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


СТАРЫЙ: JavaScript, 112 байт, 111 байт, 110 байт.

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

Объяснение:

Внутри основной функции мы начнем с определения другой, которая поможет нам вычислить минуты заданного времени, добавив 12 часов к параметру часов, если третий параметр верен:

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

Далее, мы разделить строку либо ' 'или':' совпадаем с числами внутри строки, в результате чего получается массив всех чисел в строке.

Затем мы рассчитываем разницу между временем окончания и временем начала и вычитаем время обеда, используя ранее определенную функцию (при необходимости преобразуя строки в числа).

Наконец, мы создаем строку результата: часы являются целой частью, r/60а минуты - r%60.

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

Ибрагим Махрир
источник
@Jakob Я новый пользователь Codegolf. Я до сих пор не знаю, как здесь все работает, включая TIO. Также я спросил в этом комментарии, как бы я подошел к этому, используя JavaScript, но никто не ответил.
Ибрагим Махрир
@Jakob TIO исправлено. И я не использую NodeJS, я использую консоль браузера. NodeJS был добавлен TIO.
Ибрагим Махрир
До сих пор не уверен, что метод ввода допустим (этот вопрос, к сожалению, ограничительный), но нам может понадобиться более опытный игрок в гольф JS, чтобы вмешаться. Но также обратите внимание, что программы должны поддерживать ввод данных в течение нескольких дней - к сожалению, это не было сделано очень ясно в описании.
Якоб
@Jakob Если больше дней должны быть использованы в качестве входных данных я мог бы просто сделать функцию принимает массив и использование map: a=>a.map(...). Это добавит 5 байтов к моему ответу. Но я все еще жду ответа OP (или любого другого) на мой комментарий.
Ибрагим Махрир
Поскольку чистый JavaScript не имеет доступа к стандартному вводу или файлам, я предлагаю вам использовать метод по умолчанию, использующий приглашение с графическим интерфейсом: codegolf.meta.stackexchange.com/a/2459/79343
OOBalance
3

Python 2 , 100 байт

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

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

Полная программа, которая читает несколько строк из текстового файла, как указано OP. Функция, которая просто анализирует одну строку, сохранит дополнительные 10 байтов.

Час Браун
источник
1
Это также более разборчиво, чем моя попытка!
Райан
3

Java 10, 194 191 байт

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

Ввод / вывод болезнен в Java. Завершает ненормально, когда нет следующей строки ввода для чтения. Попробуйте это онлайн здесь .

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
}
OOBalance
источник
2

Красный , 35 байт

func[s e l][e + 12:0 - s -(l * 60)]

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

Примечание: вывод в формате hh:mm:ss

Гален Иванов
источник
Вот это да! Это очень удивительно :)
Anush
@Anush Да, у Red (и, конечно, Rebol) хороший тип данных времени.
Гален Иванов
2

R , 97 байт

s=matrix(strtoi(unlist(strsplit(scan(,""),':'))),5,,T)%*%c(-60,-1,60,1,-1);paste(12+s%/%60,s%%60)

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

Для каждой строки возвращается "hours minutes"

  • -16 байт благодаря JayCe!
digEmAll
источник
Я попытался с помощью a data.frameсохранить некоторые байты - пока не работает . Но это простое изменение делает :)
JayCe
Большой! Спасибо :)
digEmAll