Conversione decimale dell'ora del giorno


15

introduzione

Il tempo è confuso. Sessanta secondi a un minuto, sessanta minuti a un'ora, ventiquattro ore al giorno (e per non parlare di quel fastidioso am / pm!).

Oggigiorno non c'è spazio per una tale stupidità, quindi abbiamo deciso di adottare l'unica alternativa sensata: i giorni decimali! Vale a dire, ogni giorno è considerato 1 intera unità e qualsiasi cosa più breve viene scritta come una frazione decimale di quel giorno. Ad esempio, "12:00:00" verrebbe scritto come "0,5" e "01:23:45" potrebbe essere scritto come "0,058159".

Poiché ci vorrà del tempo per abituarsi al nuovo sistema, si ha il compito di scrivere un programma in grado di convertire tra di loro in entrambe le direzioni.

Sfida

Scrivi un programma nella lingua che preferisci, che dato un tempo moderno nel formato ISO-8601 di "hh: mm: ss", restituirà la frazione decimale equivalente. Allo stesso modo, data una frazione decimale, il programma dovrebbe restituire l'ora nel formato moderno inizialmente specificato.

È possibile formulare le seguenti ipotesi:

  • L'ingresso e l'uscita moderni possono variare da "00:00:00" a "24:00:00"
  • L'ingresso e l'uscita del tempo decimale possono variare da "0" a "1" e dovrebbero essere in grado di accettare / emettere fino ad almeno 5 cifre decimali (come "0.12345"). Più precisione è accettabile
  • Il programma dovrebbe essere in grado di sapere quale direzione di conversione eseguire in base all'input
  • Non è possibile utilizzare le funzioni / librerie relative al tempo

Il vincitore sarà determinato dal codice più breve che soddisfa i criteri. Saranno selezionati in almeno 7 unità decimali di giorno o se / quando ci sono stati abbastanza invii.

Esempi

Ecco un (n intenzionalmente) pezzo di codice JavaScript mal scritto da usare come esempio:

function decimalDay(hms) {
    var x, h, m, s;
    if (typeof hms === 'string' && hms.indexOf(':') > -1) {
        x = hms.split(':');
        return (x[0] * 3600 + x[1] * 60 + x[2] * 1) / 86400;
    }
    h = Math.floor(hms * 24) % 24;
    m = Math.floor(hms * 1440) % 60;
    s = Math.floor(hms * 86400) % 60;
    return (h > 9 ? '' : '0') + h + ':' + (m > 9 ? '' : '0') + m + ':' + (s > 9 ? '' : '0') + s;
}
decimalDay('02:57:46'); // 0.12344907407407407
decimalDay('23:42:12'); // 0.9876388888888888
decimalDay(0.5); // 12:00:00
decimalDay(0.05816); // 01:23:45

Hmm ... 60 è quasi 64. Mi chiedo come sarebbe il tempo se ci fossero 64 secondi in un minuto e 64 minuti in un'ora (e 16 o 32 ore in un giorno).

1
Dobbiamo gestire i secondi bisestili? quindi 23:59:60 è 1 secondo dalla fine di un secondo giorno 86401?
Sparr,

1
@Sparr Non c'è bisogno di preoccuparsi dei secondi saltati. Questo è il futuro, dove abbiamo deciso che per un secondo è sciocco essere considerato un valore assoluto, legandolo anche alla velocità relativa della rotazione della terra;)
Mwr247,

1
@MichaelT Sarebbe un mondo da sogno per programmatori = P
Mwr247,

1
@ Mwr247 sì. DNS TTL ha (aveva?) Un campo che è ndove nè 2 ^ n secondi. Quindi un valore di '6' aveva un TTL di circa 1 minuto. Un valore di '12' aveva un TTL di circa 1 ora. '15' erano circa 8 ore e così via. Permetteva a un byte di definire il timeout e offrirti un controllo sufficiente per tempi brevi o lunghi.

Risposte:


6

CJam, 58 56 42 byte

Sono sicuro che questo è troppo lungo e può essere giocato molto a golf. Ma qui va per cominciare:

86400q':/:d_,({60bd\/}{~*i60b{s2Ue[}%':*}?

Provalo online qui


Heh, abbiamo idee simili
aditsu,

@aditsu Oh !. Non ho visto il tuo prima di aggiornare il mio e poi ho avuto fretta di fare il pendolare.
Ottimizzatore

Sai cosa .. sentiti libero di usare il mio codice 86400q':/:d_,({60bd\/}{~*mo60bAfmd2/':*}?:, sto eliminando la mia risposta. Il moè così che 0,058,159 mila convertiti a 01:23:45
aditsu

3

Python 2, 159 150 141 + 2 = 143 byte

Soluzione semplice, probabilmente può essere molto più breve. Ci lavorerà sopra.

Aggiunti due byte per tenere conto dell'input che deve essere racchiuso tra "s. Inoltre, Sp3000 ha sottolineato un problema con eval () interpretando gli ottali, e ha mostrato un modo per abbreviare la formattazione, usare map () e rimuovere una stampa.

n=input();i=float;d=864e2
if':'in n:a,b,c=map(i,n.split(':'));o=a/24+b/1440+c/d
else:n=i(n);o=(':%02d'*3%(n*24,n*1440%60,n*d%60))[1:]
print o

Dai un'occhiata su ideone qui.


2

Javascript ( ES6 ), 116 110 byte

f=x=>x[0]?([h,m,s]=x.split(':'),+s+m*60+h*3600)/86400:[24,60,60].map(y=>('0'+~~(x*=y)%60).slice(-2)).join(':')


// for snippet demo:
i=prompt();
i=i==+i?+i:i; // convert decimal string to number type
alert(f(i))

ha commentato:

f=x=>
    x[0] ? // if x is a string (has a defined property at '0')
        ([h, m, s] = x.split(':'), // split into hours, minutes, seconds
        +s + m*60 + h*3600) // calculate number of seconds
        / 86400 // divide by seconds in a day
    : // else
        [24, 60, 60]. // array of hours, minutes, seconds
        map(y=> // map each with function
            ('0' + // prepend with string zero
                ~~(x *= y) // multiply x by y and floor it
                % 60 // get remainder
            ).slice(-2) // get last 2 digits
        ).join(':') // join resulting array with colons

24:00:00produce 1ma l'inverso non è vero
rink.attendant.6

@ rink.attendant.6 fixed
nderscore

2

Python 3: 143 byte

i,k,l,m=input(),60,86400,float
if'.'in i:i=m(i)*l;m=(3*':%02d'%(i/k/k,i/k%k,i%k))[1:]
else:a,b,c=map(m,i.split(':'));m=(a*k*k+b*k+c)/l
print(m)

Stesso numero di byte della soluzione python 2 ma sembra che abbiamo adottato approcci diversi in matematica.


2

Julia, 152 143 142 byte

Bene, ho aggiornato il mio approccio per essere meno "giuliano", come si suol dire, per il bene del golf. Per un approccio migliore (sebbene meno conciso), consultare la cronologia delle revisioni.

x->(t=[3600,60,1];d=86400;typeof(x)<:String?dot(int(split(x,":")),t)/d:(x*=d;o="";for i=t q,x=x÷i,x%i;o*=lpad(int(q),2,0)*":"end;o[1:end-1]))

Ciò crea una funzione senza nome che accetta una stringa o un numero in virgola mobile a 64 bit e restituisce rispettivamente un numero in virgola mobile o una stringa a 64 bit. Per chiamarlo, dagli un nome, ad es f=x->....

Ungolfed + spiegazione:

function f(x)
    # Construct a vector of the number of seconds in an hour,
    # minute, and second
    t = [3600, 60, 1]

    # Store the number of seconds in 24 hours
    d = 86400

    # Does the type of x inherit from the type String?
    if typeof(x) <: String
        # Compute the total number of observed seconds as the
        # dot product of the time split into a vector with the
        # number of seconds in an hour, minute, and second
        s = dot(int(split(x, ":")), t)

        # Get the proportion of the day by dividing this by
        # the number of seconds in 24 hours
        s / d
    else
        # Convert x to the number of observed seconds
        x *= d

        # Initialize an output string
        o = ""

        # Loop over the number of seconds in each time unit
        for i in t
            # Set q to be the quotient and x to be the remainder
            # from x divided by i
            q, x = divrem(x, i)

            # Append q to o, padded with zeroes as necessary
            o *= lpad(int(q), 2, 0) * ":"
        end

        # o has a trailing :, so return everything up to that
        o[1:end-1]
    end
end

Esempi:

julia> f("23:42:12")
0.9876388888888888

julia> f(0.9876388888888888)
"23:42:12"

julia> f(f("23:42:12"))
"23:42:12"

2

C, 137 byte

Programma C completo. Accetta input su stdin e output su stdout.

main(c){float a,b;scanf("%f:%f:%d",&a,&b,&c)<3?c=a*86400,printf("%02d:%02d:%02d",c/3600,c/60%60,c%60):printf("%f",a/24+b/1440+c/86400.);}

Ungolf e commentato:

int main() {
    // b is float to save a . on 1440
    float a,b;
    // c is int to implicitly cast floats
    int c;

    // If the input is hh:mm:ss it gets splitted into a, b, c
    // Three arguments are filled, so ret = 3
    // If the input is a float, it gets stored in a
    // scanf stops at the first semicolon and only fills a, so ret = 1
    int ret = scanf("%f:%f:%d", &a, &b, &c);

    if(ret < 3) {
        // Got a float, convert to time
        // c = number of seconds from 00:00:00
        c = a * 86400;
        printf("%02d:%02d:%02d", c/3600, c/60 % 60, c%60);
    }
    else {
        // a = hh, b = mm, c = ss
        // In one day there are:
        // 24 hours
        // 1440 minutes
        // 86400 seconds
        printf("%f", a/24 + b/1440 + c/86400.);
    }
}

Uso molto chiaro di scanf e% f
alcuni utenti l'

D'oh! Intendevo "intelligente".
alcuni utenti il

2

J, 85 byte

risultati:

T '12: 00: 00'
0,5

T 0,5
12 0 0

T '12: 34: 56 '
0,524259

T 0,524259
12 34 56

T=:3 :'a=.86400 if.1=#y do.>.(24 60 60#:y*a)else.a%~+/3600 60 1*".y#~#:192 24 3 end.'

Totale 85


Benvenuti nel sito! Ho modificato il tuo post in modo che il codice venga visualizzato come codice. Per quanto riguarda un collegamento online, il migliore che conosco è TIO . Ti darei un link, ma non ho esperienza con J, quindi non conosco il modo giusto per invocarlo. Inoltre, questo sembra essere 91 byte quando si includono la prima e l'ultima riga. È corretto?
DJMcMayhem

Grazie per l'aiuto! Il programma [a = ... to end.] È 77. Il titolo è 10. Il terminatore è 1, quindi fa 88. Con tre feed di riga che fa 91! Ci lavorerò su: o)
Richard Donovan l'

Ora fino a un byte da 85 byte!
Richard Donovan,

1

Javascript, 194 192 190 188 byte

function(z){if(isNaN(z)){x=z.split(':');return x[0]/24+x[1]/1440+x[2]/86400}h=(z*24)|0;h%=24;m=(z*1440)|0;m%=60;s=(z*86400)|0;s%=60;return""+(h>9?'':0)+h+':'+(m>9?'':0)+m+':'+(s>9?'':0)+s}

1

JavaScript ES6, 98 130 byte

s=>s==+s?'246060'.replace(/../g,l=>':'+('0'+~~(s*=+l)%60).slice(-2)).slice(1):s.split`:`.reduce((a,b)=>+b+(+a)*60)*1/864e2;f(0.5);

Sfortunatamente, le funzioni legate al tempo (come "Date" e "toTimeString") non sono consentite in questa sfida. Altrimenti, è un modo molto più conciso di farlo =)
Mwr247

@ Mwr247 oh non l'ho visto, lo
aggiusterò

1

C, 156 152 byte

Ho pensato che sarebbe stato facile per C. Ma alla fine è rimasto abbastanza grande. :(

n,m=60;d(char*s){strchr(s,58)?printf("%f",(float)(atoi(s)*m*m+atoi(s+3)*m+atoi(s+6))/m/m/24):printf("%02d:%02d:%02d",(n=atof(s)*m*m*24)/m/m,n/m%m,n%m);}

Programma di test:

#include <stdio.h>
#include <stdlib.h>

int n,m=60;
d(char*s)
{
    strchr(s,':') ? 
        printf("%f",(float)(atoi(s)*m*m+atoi(s+3)*m+atoi(s+6))/m/m/24):
        printf("%02d:%02d:%02d",(n=atof(s)*m*m*24)/m/m,n/m%m,n%m);
}

int main()
{
    d("01:23:45");
    printf("\n");
    d("02:57:46");
    printf("\n");
    d("23:42:12");
    printf("\n");
    d("12:00:00");
    printf("\n");
    d("0.5");
    printf("\n");
    d("0.05816");
    printf("\n");
    d("0");
    printf("\n");
    d("1");
    printf("\n");
    return 0;
}

Produzione:

0.058160
0.123449
0.987639
0.500000
12:00:00
01:23:45
00:00:00
24:00:00

1

PHP, 70 69 byte

<?=strpos($t=$argv[1],58)?strtotime($t)/86400:date("H:i:s",$t*86400);

accetta input dall'argomento della riga di comando, stampa su STDOUT:

Se l'input contiene due punti, converti in tempo unix e dividi per (secondi al giorno),
altrimenti moltiplica il valore numerico con (secondi al giorno) e formatta il tempo unix in hh:mm:ss.


1

Perl, 109 108 101 + 6 ( -plaF:bandiera) = 107 byte

$_=$#F?($F[0]*60+$F[1]+$F[2]/60)/1440:sprintf"%02d:%02d:%02d",$h=$_*24,$m=($h-int$h)*60,($m-int$m)*60

usando:

perl -plaF: -e '$_=$#F?($F[0]*60+$F[1]+$F[2]/60)/1440:sprintf"%02d:%02d:%02d",$h=$_*24,$m=($h-int$h)*60,($m-int$m)*60' <<< 01:23:45

Provalo su Ideone.


0

Excel, 178 byte

=IF(LEFT(A1,2)="0.",TEXT(FLOOR(A1*24,1),"00")&":"&TEXT(MOD(FLOOR(A1*1440,1),60),"00")&":"&TEXT(MOD(FLOOR(A1*86400,1),60),"00"),((LEFT(A1,2)*60+MID(A1,4,2))*60+RIGHT(A1,2))/86400)
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.