Obliczanie kart czasu pracy

14

Arkusze czasu pracy

W miejscu pracy często musisz wypełniać karty pracy. To zadanie polega na napisaniu kodu, który w tym pomoże.

Wejście

Dwa razy w nieco niestandardowym 12-godzinnym zegarze oznaczającym początek i koniec dnia oddzielone spacją. Trzecia liczba reprezentuje liczbę minut zajętych na lunch. Na przykład

9:14 5:12 30

Oznacza to, że zacząłeś pracę o 9:14, skończyłeś o 17:12 i zająłeś 30 minut na lunch.

Możesz to założyć

  • Każda pora w pierwszej kolumnie trwa od 00:00 (do północy), ale nie obejmuje 13:00, a każda godzina w drugiej kolumnie to najwcześniej 13:00, aż do 23:59.
  • Przerwa na lunch nie trwa dłużej niż dzień roboczy!

Format wejściowy musi być zgodny z podanymi przykładami.

Zadanie

Twój kod powinien czytać w pliku (lub standardowym wejściu) tych potrójnych danych i dla każdego wyjścia, jak długo pracowałeś. Ten wynik powinien wskazywać liczbę godzin. W powyższym przykładzie jest to:

7 godzin i 58 minut minus 30 minut, czyli 7 godzin 28 minut.

Wynik

Dane wyjściowe muszą określać (całkowitą) liczbę godzin i minut i nie mogą zawierać więcej niż 59 minut. Oznacza to, że nie można wyprowadzić 2 godz. 123 min. Poza tym twój kod może generować w dowolnym wygodnym dla ciebie formacie, który jest łatwy do odczytania przez człowieka.

Przykłady

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 
Anush
źródło
3
Nie rozumiem, jak ścisły format wejściowy ( :ograniczenia czasowe na zegarze 12-godzinnym) dodaje coś do tego wyzwania.
Kudłaty
3
@Shaggy Parsowanie formatu wejściowego było dla mnie największym wyzwaniem, ponieważ nie możesz przyjąć pozycji postaci, ponieważ godziny mogą być jedną lub dwiema postaciami ...
Ryan
Czy kod musi czytać kilka wierszy? A może wystarczy, jeśli czyta jedną linię?
Luis Mendo
1
Tak, kod musi akceptować wiele linii.
Anush
5
@ mbomb007 Możesz przegłosować, ale nie lubienie formatu wejściowego nie jest powodem do VTC.
Okx,

Odpowiedzi:

7

MATL , 28 bajtów

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

Wypróbuj online!

Luis Mendo
źródło
1
To bardzo imponujące!
Anush
Czy dane wyjściowe nie powinny być w tym formacie "XXhr YYmin"?
ibrahim mahrir
@ibrahimmahrir Wyzwanie mówi, że Twój kod może być generowany w dowolnym, łatwym dla człowieka formacie, który jest dla Ciebie wygodny
Luis Mendo
1
O, rozumiem! Zmienię swoją odpowiedź, aby ją skrócić. Dzięki!
ibrahim mahrir
5

Retina 0.8.2 , 83 bajty

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

Wypróbuj online! Link zawiera przypadki testowe. Wyjaśnienie:

\d+
$*

Przekształć dane wejściowe w jednoargumentowe.

 (1+:)
 12$*1$1

Dodaj 12 godzin do czasu zatrzymania.

+`1:
:60$*

Pomnóż godziny przez 60 i dodaj do minut.

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

Odejmij czas rozpoczęcia i czas przerwy od czasu zakończenia.

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

Divmod przez 60. (Zaoszczędź 5 bajtów, aby uzyskać bardziej nudny format wyjściowy.)

Neil
źródło
5

Perl 5 -pl, 80 74 71 bajtów

/:(\d+) (\d+):(\d+) /;$m=720+($2-$`)*60+$3-$1-$';$_=($m/60|0).":".$m%60

Wypróbuj online!

sundar - Przywróć Monikę
źródło
4

Python 3, 161 bajtów

Wiem, że nie będzie to nawet najmniejsze, ale czyta się w pliku:

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

Czuję ironię, jak pauzuje mój grafik, żeby to zrobić ...

Python 2.7, 133 bajty

Dzięki za sugestie w komentarzach! Przejście na Python 2.7 oszczędza kilka dodatkowych bajtów, ponieważ domyślnie jest dzielone na liczby całkowite:

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

To samo podejście z python3 ma 135 bajtów z powodu instrukcji print i domyślnego podziału na zmiennoprzecinkowe:

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)
Ryan
źródło
1
Możesz zapisać 4 bajty, umieszczając i=intna początku i zmieniając trzecią linię nam=-i(l[0])*60+i(l[1][:2])+(i(l[1][3:])*60+720+i(l[2][:2])-i(l[2][2:]))
James
@DJMcMayhem Dziękujemy! Próbowałem wymyślić sposób, aby je uprościć ...
Ryan
2
Bardzo miła pierwsza odpowiedź, witamy w Programowaniu Puzzle i Code Golf! Aby trochę pomóc w grze w golfa, możesz być w stanie pobrać dane ze STDIN, użyć map(int,l[:-1].split(':'))i upuścić wiele konwersji do int, zwinąć wszystko do jednowierszowego, zastępując wcięcie ;itp., Aby zaoszczędzić kilka bajtów. Dodatkowo możesz odwiedzić Porady dotyczące gry w golfa w Pythonie, aby uzyskać więcej ciekawych sztuczek, które inni użytkownicy odkryli podczas swojego życia golfisty :).
Pan Xcoder
1
Ponadto OP wydaje się być mniej restrykcyjny co do formatu wyjściowego , więc myślę, print(m,m%60)że wystarczy. (Zwróć również uwagę na użycie m%60zamiast m-(m//60*60))
Pan Xcoder
@ Mr.Xcoder Thanks!
Ryan
4

C, 105 bajtów

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

Całkowicie proste. Wypróbuj online tutaj .

Nie golfowany:

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
źródło
Zaproponuj a,b,c,d;f(e)zamiast a,b,c,d,e;f()i ;printf("%d:%d ",a/60,a%60))a=(12+c-a)*60+d-b-e;}zamiast;)a=(12+c-a)*60+d-b-e,printf("%d:%d ",a/60,a%60);
ceilingcat
4

Wolfram Language 125 119 111 bajtów

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

8 bajtów zapisanych dzięki użytkownikowi 202729

Przykład

Skróty nie są tutaj używane, aby ułatwić przestrzeganie logiki.

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 godz. 51 min

Interpreter["Time"][#2 <> "pm"] interpretuje jako czas drugi parametr, po którym następuje „pm”, a mianowicie w tym przypadku „16:12”, zwracając wartość TimeObjectodpowiadającą 16:12.

-Interpreter["Time"][# <> "am"])[[1]] - #3/60]. #3to trzeci parametr, a mianowicie 20 min. Znak minus odejmuje przedział godzinny od końca czasu zmiany. Zwraca skorygowany czas zakończenia zmiany, to znaczy koniec zmiany, który obowiązywałby, gdyby osoba nie zrobiła przerwy na lunch.

Interpreter["Time"][#] interpretuje jako czas pierwszy parametr, w tym przypadku „9:00”, zwracając wartość TimeObjectodpowiadającą 9:00 rano.

Odejmując początek zmiany od skorygowanego końca czasu zmiany, uzyskuje tsię przedział czasu wyrażony w godzinach. IntegerPart[t]zwraca liczbę pełnych przepracowanych godzin. IntegerPart[60 Mod[t,1]], "min"}]zwraca dodatkowe minuty przepracowane.

DavidC
źródło
Tak. Dzięki. Pierwszy raz widzę Mod[x, 1]używane.
DavidC
Czerpane z (usuniętych) wskazówek . / W rzeczywistości mod 1 zachowuje się inaczej niż część ułamkowa dla liczby ujemnej. / Może Floorbyć używany do IntegerPart?
user202729,
Floor zwraca mi, dla mnie, niewytłumaczalny wynik -6hr 52mindla zastosowanych wartości próbek. Muszę się temu przyjrzeć, aby zrozumieć, dlaczego wytworzono ujemną wartość godzin (i najwyraźniej minut).
DavidC
3

JavaScript, 83 bajty 76 bajtów

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

Właśnie pozbyłem się wewnętrznej funkcji z rozwiązania poniżej (o czym myślałem?). Zmieniono również format wyjściowy.

Wypróbuj online!


STARY: JavaScript, 112 bajtów 111 bajtów 110 bajtów

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

Wyjaśnienie:

Wewnątrz głównej funkcji zaczynamy od zdefiniowania innej, która pomoże nam obliczyć minuty podanego czasu, dodając 12 godzin do parametru godzin, jeśli trzeci parametr jest prawdziwy:

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

Następnie dzielimy ciąg znaków na dowolny z nich ' 'lub':' dopasowujemy liczby w ciągu, co daje tablicę wszystkich liczb w ciągu.

Następnie obliczamy różnicę czasu zakończenia i czasu rozpoczęcia oraz odejmowania czasu na lunch za pomocą wcześniej zdefiniowanej funkcji (w razie potrzeby przekształcając ciągi na liczby).

Na koniec tworzymy wynikowy ciąg: godziny są liczbą całkowitą, r/60a minuty są r%60.

Wypróbuj online!

ibrahim mahrir
źródło
@Jakob Jestem nowym użytkownikiem codegolf. Nadal nie wiem, jak tu działają, w tym TIO. Także ja zapytałem w tym komentarzu , jak bym podejść do tego przy użyciu javascript, ale nikt nie odpowiedział.
ibrahim mahrir
@Jakob TIO naprawiony. I nie używam NodeJS, używam konsoli przeglądarki. NodeJS został dodany przez TIO.
ibrahim mahrir
Wciąż nie jestem pewien, czy metoda wprowadzania jest legalna (to pytanie jest niestety restrykcyjne), ale możemy potrzebować bardziej doświadczonego golfisty JS, aby się w nią wdrożyć. Pamiętaj jednak, że programy muszą obsługiwać wiele dni danych wejściowych - niestety nie zostało to zrobione bardzo jasne w opisie.
Jakob
@Jakob Jeśli więcej dni powinny być wykorzystywane jako wsad może po prostu sprawiają, że funkcja zaakceptować tablicę i stosowanie map: a=>a.map(...). Dodanie 5 bajtów do mojej odpowiedzi. Ale wciąż czekam na odpowiedź OP (lub kogokolwiek innego) na mój komentarz.
ibrahim mahrir
Ponieważ czysty JavaScript nie ma dostępu do standardowych danych wejściowych ani plików, sugeruję skorzystanie z domyślnej metody korzystania z monitu GUI: codegolf.meta.stackexchange.com/a/2459/79343
OOBalance
3

Python 2 , 100 bajtów

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

Wypróbuj online!

Pełny program, który odczytuje wiele wierszy z pliku tekstowego, zgodnie z zaleceniami OP. Funkcja, która po prostu analizuje pojedynczy wiersz, zaoszczędziłaby dodatkowe 10 bajtów.

Chas Brown
źródło
1
Jest to również o wiele bardziej czytelne niż moja próba!
Ryan
3

Java 10, 194 191 bajtów

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

We / wy jest bolesne w Javie. Kończy się nieprawidłowo, gdy nie ma następnego wiersza wejścia do odczytu. Wypróbuj online tutaj .

Nie golfowany:

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
źródło
2

Czerwony , 35 bajtów

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

Wypróbuj online!

Uwaga: Dane wyjściowe mają format hh:mm:ss

Galen Iwanow
źródło
Łał! To bardzo zaskakujące :)
Anush
@Anush Tak, Red (i oczywiście Rebol) ma fajny typ danych.
Galen Iwanow