Fogli di calcolo


14

Fogli presenze

In un luogo di lavoro spesso è necessario compilare i fogli presenze. Questa attività è scrivere codice per aiutare questo.

Ingresso

Due volte in un orologio di 12 ore leggermente non standard che indica l'inizio e la fine della giornata separati da uno spazio. Un terzo numero rappresenta il numero di minuti necessari per il pranzo. Per esempio

9:14 5:12 30

Ciò significa che hai iniziato a lavorare alle 9:14, finito alle 17:12 e hai impiegato 30 minuti a pranzo.

Puoi presumere che

  • Ogni ora nella prima colonna è dalle 00:00 (mezzanotte) fino alle 13:00, tranne 13 e ogni volta nella seconda colonna è dalle 13:00 fino alle 23:59.
  • La pausa pranzo non è più lunga della giornata lavorativa!

Il formato di input deve essere come negli esempi forniti.

Compito

Il tuo codice dovrebbe essere letto in un file (o input standard) di queste triple, e per ognuna di esse per quanto tempo hai lavorato. Questo output dovrebbe indicare il numero di ore. Per l'esempio sopra questo è:

7 ore e 58 minuti meno 30 minuti, ovvero 7 ore e 28 minuti.

Produzione

L'output deve specificare il numero (intero) di ore e minuti e non deve elencare più di 59 minuti. Cioè non è possibile emettere 2 ore 123 minuti. A parte questo, il tuo codice può essere emesso in qualsiasi formato di lettura facilmente comprensibile per te.

Esempi

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
Non vedo come il rigoroso formato di input ( :tempi delimitati sull'orologio a 12 ore) aggiunga qualcosa a questa sfida.
Shaggy,

3
@Shaggy L'analisi del formato di input è stata la maggior parte della sfida almeno per me, perché non puoi assumere le posizioni dei personaggi poiché le ore potrebbero essere uno o due personaggi ...
Ryan,

Il codice deve leggere più righe? O è sufficiente se legge una riga?
Luis Mendo,

1
Sì, il codice deve accettare più righe.
Anush,

5
@ mbomb007 È possibile effettuare il downgrade, ma non apprezzare il formato di input non è un motivo per VTC.
Okx,

Risposte:



5

Retina 0.8.2 , 83 byte

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

Provalo online! Il link include casi di test. Spiegazione:

\d+
$*

Converti l'input in unario.

 (1+:)
 12$*1$1

Aggiungi 12 ore all'ora di fine.

+`1:
:60$*

Moltiplica le ore per 60 e aggiungi i minuti.

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

Sottrai l'ora di inizio e l'ora di interruzione dall'ora di fine.

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

Divmod per 60. (Salva 5 byte per un formato di output più noioso.)



4

Python 3, 161 byte

So che questo non sarà nemmeno vicino al più piccolo, ma legge in un file:

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

Sento l'ironia di mettere in pausa la mia scheda attività per farlo ...

Python 2.7, 133 byte

Grazie per i suggerimenti nei commenti! Il passaggio a Python 2.7 consente di risparmiare qualche byte in più perché per impostazione predefinita è la divisione intera:

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

Lo stesso approccio con python3 è di 135 byte a causa dell'istruzione print e del default alla divisione 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
È possibile salvare 4 byte inserendo i=intall'inizio e modificando la terza riga inm=-i(l[0])*60+i(l[1][:2])+(i(l[1][3:])*60+720+i(l[2][:2])-i(l[2][2:]))
James

@DJMcMayhem Grazie! Stavo cercando di pensare a un modo per semplificare quelli ...
Ryan,

2
Molto bella la prima risposta, benvenuto in Puzzle di programmazione e Code Golf! Per aiutare un po 'a giocare a golf, potresti essere in grado di ricevere input da STDIN, utilizzaremap(int,l[:-1].split(':')) e rilasciare le conversioni multiple in int, comprimere tutto in una riga sostituendo il rientro con ;ecc. Per salvare un paio di byte. Inoltre, puoi visitare Suggerimenti per giocare a golf in Python per alcuni trucchi più accurati che altri utenti hanno scoperto durante la loro vita da golfista :).
Mr. Xcoder,

1
Inoltre, l'OP sembra essere meno restrittivo riguardo al formato di output , quindi penso che print(m,m%60)sarebbe sufficiente. (Nota anche l'uso di m%60al posto di m-(m//60*60))
Mr. Xcoder

@ Mr.Xcoder Grazie!
Ryan,

4

C, 105 byte

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 semplice. Provalo online qui .

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

Suggerisci a,b,c,d;f(e)invece a,b,c,d,e;f()e ;printf("%d:%d ",a/60,a%60))a=(12+c-a)*60+d-b-e;}invece di;)a=(12+c-a)*60+d-b-e,printf("%d:%d ",a/60,a%60);
ceilingcat il

4

Lingua Wolfram 125 119 111 byte

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

8 byte salvati grazie all'utente 202729

Esempio

Le abbreviazioni non vengono utilizzate qui, per rendere più semplice seguire la logica.

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 ore 51min

Interpreter["Time"][#2 <> "pm"] interpreta come tempo il secondo parametro seguito da "pm", vale a dire, in questo caso, "16:12", restituendo un TimeObject corrispondente a 16:12.

-Interpreter["Time"][# <> "am"])[[1]] - #3/60]. #3è il terzo parametro, ovvero 20min. Il segno meno sottrae l'intervallo dell'ora di pranzo dalla fine del turno. Restituisce la fine regolata del tempo di turno, ovvero la fine del turno che si applicherebbe se la persona non prendesse una pausa pranzo.

Interpreter["Time"][#] interpreta come orario il primo parametro, in questo caso "9:00", restituendo un TimeObjectcorrispondente alle 9:00.

Sottraendo l'inizio del turno dalla resa regolata dei rendimenti tdel tempo del turno , l'intervallo di tempo espresso in ore. IntegerPart[t]restituisce il numero di ore complete lavorate. IntegerPart[60 Mod[t,1]], "min"}]restituisce i minuti aggiuntivi lavorati.


Sì. Grazie. La prima volta che vedo Mod[x, 1]usato.
DavidC,

Tratto da questi suggerimenti (eliminati) . / In realtà la mod 1 si comporta diversamente dalla parte frazionaria per il numero negativo. / Può Flooressere utilizzato per IntegerPart?
user202729

Floor restituisce un risultato inspiegabile -6hr 52minper i valori del campione che ho usato. Devo esaminare questo per capire perché è stato prodotto un valore negativo per ore (e apparentemente minuti).
DavidC

3

JavaScript, 83 byte 76 byte

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

Mi sono appena liberato della funzione interiore dalla soluzione di seguito (cosa stavo pensando?). Modificato anche il formato di output.

Provalo online!


VECCHIO: JavaScript, 112 byte 111 byte 110 byte

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

Spiegazione:

All'interno della funzione principale, iniziamo definendone un altro che ci aiuterà a calcolare i minuti di un tempo dato, aggiungendo 12 ore al parametro ore se il terzo parametro è vero:

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

Quindi, dividiamo la stringa per uno ' 'o':' abbiniamo i numeri all'interno della stringa risultando in una matrice di tutti i numeri nella stringa.

Quindi calcoliamo la differenza tra l'ora di fine e l'ora di inizio e sottraendo l'ora di pranzo utilizzando la funzione definita in precedenza (convertendo le stringhe in numeri quando necessario).

Alla fine produciamo la stringa di risultato: le ore sono la parte intera di r/60e i minuti lo sono r%60.

Provalo online!


@Jakob Sono un nuovo utente di codegolf. Ancora non so come funzionano le cose qui intorno, incluso il TIO. Inoltre ho chiesto in questo commento come avrei affrontato questo problema usando JavaScript ma nessuno ha risposto.
Ibrahim Mahrir,

@Jakob TIO risolto. E non sto usando NodeJS, sto usando la console del browser. NodeJS è stato aggiunto da TIO.
Ibrahim Mahrir,

Non sono ancora sicuro che il metodo di input sia legale (questa domanda è purtroppo restrittiva), ma potremmo aver bisogno di un golfista JS più esperto per intervenire. Ma nota anche che i programmi devono supportare più giorni di dati di input - purtroppo non è stato fatto molto chiaro nella descrizione.
Jakob,

@Jakob Se più giorni devono essere utilizzati come input ho potuto solo fare la funzione accetta un array e l'uso map: a=>a.map(...). Aggiungerà 5 byte alla mia risposta. Ma sto ancora aspettando la risposta di OP (o chiunque) al mio commento.
Ibrahim Mahrir,

Poiché JavaScript puro non ha accesso a input o file standard , ti suggerisco di utilizzare il metodo predefinito di utilizzo di un prompt della GUI: codegolf.meta.stackexchange.com/a/2459/79343
OOBalance,

3

Python 2 , 100 byte

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

Provalo online!

Programma completo che legge più righe da un file di testo, come indicato da OP. Una funzione che analizza solo una singola riga salverebbe un'aggiunta di 10 byte.


1
Questo è anche molto più leggibile del mio tentativo!
Ryan,

3

Java 10, 194 191 byte

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

L'I / O è doloroso in Java. Termina in modo anomalo quando non vi è alcuna riga successiva di input da leggere. Provalo online qui .

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
}


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.