Обчислювальні часові таблиці


14

Листи часу

На робочому місці вам часто доводиться заповнювати графіки роботи. Це завдання - написати код, щоб допомогти в цьому.

Вхідні дані

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

9:14 5:12 30

Це означає, що ви розпочали роботу о 9:14, закінчили роботу о 17:12 та взяли 30 хвилин на обід.

Ви можете припустити, що

  • Будь-який час у першому стовпці починається з 00:00 (опівночі) до, але не враховуючи 13:00, а будь-який час у другому стовпці - найперше до 23:59 до 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 Розбір формату введення був для мене щонайменше викликом, тому що ви не можете прийняти позиції символів, оскільки години можуть бути або одним, або двома символами ...
Ryan

Чи має код читати кілька рядків? Або достатньо, якщо він читає один рядок?
Луїс Мендо

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

Пітон 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
Дуже приємна перша відповідь, ласкаво просимо до програмування Puzzle Puzzle & Code Golf! Щоб трохи допомогти в гольфі, можливо, ви зможете скористатись інформацією STDIN, скористатись map(int,l[:-1].split(':'))декількома конверсіями та перенести їх до int, згорнути все до однолінійки, замінивши відступ ;тощо і заощадивши пару байтів. Крім того, ви можете відвідати поради щодо гри в гольф на Python для ще декількох акуратних хитрощів, які інші користувачі виявили за життя свого гольфу :).
Містер Xcoder

1
Крім того, ОП видається менш обмежувальним щодо формату виводу , тому я думаю, що це 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);}

Цілком прямо. Спробуйте його онлайн тут .

Безголівки:

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"
}

Запропонувати 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);
roofcat

4

Мова Вольфрама 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відповідний до 4:12 pm.

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

Interpreter["Time"][#] інтерпретує як раз перший параметр, в цьому випадку "9:00", повертаючи TimeObjectвідповідний до 9:00 ранку.

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


Так. Спасибі. Перший раз я бачу Mod[x, 1]використаний.
DavidC

Взяті з цього (видаленого) поради . / Насправді мод 1 поводиться інакше від дробової частини за від’ємним числом. / Можна Floorвикористовувати IntegerPart?
користувач202729

Підлога повертає мені незрозумілий результат -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, але ніхто не відповів.
ibrahim mahrir

@Jakob TIO виправлено. І я не використовую NodeJS, я використовую консоль браузера. NodeJS додано TIO.
ibrahim mahrir

Ще не впевнений, що метод введення законний (це питання, на жаль, обмежувальний), але нам може знадобитися більш досвідчений гольфіст JS, щоб передзвонити. Але також зауважте, що програмам потрібно підтримувати багатоденні вхідні дані - на жаль, це не було зроблено дуже чітко в описі.
Якоб

@Jakob Якщо більше днів повинні бути використані в якості вхідних даних я міг би просто зробити функцію бере масив і використання map: a=>a.map(...). Це додасть 5 байтів до моєї відповіді. Але я все ще чекаю відповіді ОП (чи когось) на мій коментар.
ibrahim mahrir

Оскільки чистий JavaScript не має доступу до стандартного вводу чи файлів, пропоную скористатися методом за замовчуванням, використовуючи підказку GUI: 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

Спробуйте в Інтернеті!

Повна програма, яка читає декілька рядків з текстового файлу, як вказує ОП. Функція, яка просто розбирає один рядок, збереже додавання на 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 болісне. Припиняється аномально, коли для читання немає наступного рядка введення. Спробуйте його онлайн тут .

Безголівки:

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
}


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!

Я спробував скористатись а, data.frameщоб зберегти кілька байт - поки що це не працює . Але ця проста зміна робить :)
JayCe,


Чудово! Дякую :)
digEmAll
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.