Conversion décimale de l'heure

15

introduction

Le temps est déroutant. Soixante secondes à une minute, soixante minutes à une heure, vingt-quatre heures à un jour (et sans parler de ce satané am / pm!).

Il n'y a pas de place pour une telle bêtise de nos jours, nous avons donc décidé d'adopter la seule alternative sensée: les jours décimaux! C'est-à-dire que chaque jour est considéré comme 1 unité entière, et tout ce qui est plus court est écrit comme une fraction décimale de ce jour. Ainsi, par exemple: «12:00:00» serait écrit comme «0,5» et «01:23:45» pourrait être écrit comme «0,058159».

Parce qu'il faudra du temps pour s'habituer au nouveau système, vous êtes chargé d'écrire un programme qui peut convertir entre eux dans les deux directions.

Défi

Écrivez un programme dans la langue de votre choix, qui, étant donné une heure moderne au format ISO-8601 de "hh: mm: ss", renverra l'unité de fraction décimale équivalente. De même, étant donné une fraction décimale, le programme doit renvoyer l'heure au format moderne initialement spécifié.

Vous pouvez faire les hypothèses suivantes:

  • L'entrée et la sortie de l'heure moderne peuvent aller de "00:00:00" à "24:00:00"
  • L'entrée et la sortie du temps décimal peuvent aller de "0" à "1" et doivent pouvoir accepter / sortir jusqu'à au moins 5 décimales (telles que "0,122345"). Plus de précision est acceptable
  • Le programme doit être capable de savoir quelle direction de conversion effectuer en fonction de l'entrée
  • Vous ne pouvez pas utiliser les fonctions / bibliothèques liées au temps

Le gagnant sera déterminé par le code le plus court qui remplit les critères. Ils seront sélectionnés en au moins 7 unités de jour décimal, ou si / quand il y a eu suffisamment de soumissions.

Exemples

Voici un morceau de code JavaScript (n intentionnellement) mal écrit à utiliser comme exemple:

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
Mwr247
la source
Hmm ... 60 est presque 64. Je me demande à quoi ressemblerait l'heure s'il y avait 64 secondes en une minute et 64 minutes en une heure (et 16 ou 32 heures par jour).
1
Faut-il gérer les secondes intercalaires? donc 23:59:60 est à 1 seconde de la fin d'un deuxième jour 86401?
Sparr
1
@Sparr Pas besoin de s'inquiéter des secondes intercalaires. C'est l'avenir, où nous avons décidé qu'il est stupide qu'une seconde soit considérée comme une valeur absolue tout en la liant à la vitesse relative de la rotation de la terre;)
Mwr247
1
@MichaelT Ce serait un monde de rêve pour les programmeurs = P
Mwr247
1
@ Mwr247 yep. DNS TTL a (eu?) Un champ noù se ntrouve 2 ^ n secondes. Ainsi, une valeur de «6» avait un TTL d'environ 1 minute. Une valeur de «12» avait un TTL d'environ 1 heure. «15» était d'environ 8 heures et ainsi de suite. Il a permis à un octet de définir le délai d'expiration et de vous donner suffisamment de contrôle pour des temps courts ou longs.

Réponses:

6

CJam, 58 56 42 octets

Je suis sûr que c'est trop long et qu'on peut beaucoup jouer au golf. Mais voici pour commencer:

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

Essayez-le en ligne ici

Optimiseur
la source
Hé, nous avons des idées similaires
aditsu
@aditsu Oh !. Je n'ai pas vu le vôtre avant de mettre à jour le mien et j'étais pressé de faire la navette.
Optimizer
Vous savez quoi .. n'hésitez pas à utiliser mon code 86400q':/:d_,({60bd\/}{~*mo60bAfmd2/':*}?:, je supprime ma réponse. Il en moest ainsi que 0.058159 se convertit en 01:23:45
aditsu
3

Python 2, 159 150 141 + 2 = 143 octets

Une solution simple, peut probablement être beaucoup plus courte. Va y travailler.

Ajout de deux octets pour tenir compte de l'entrée devant être placée entre "s. De plus, Sp3000 a signalé un problème d'interprétation des octaux par eval () et a montré un moyen de raccourcir le formatage, d'utiliser map () et de supprimer une impression.

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

Découvrez-le sur ideone ici.

Kade
la source
2

Javascript ( ES6 ), 116 110 bytes

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

Commenté:

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
nderscore
la source
24:00:00produit 1mais l'inverse n'est pas vrai
rink.attendant.6
@ rink.attendant.6 fixed
nderscore
2

Python 3: 143 octets

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)

Même nombre d'octets que la solution python 2, mais il semble que nous ayons adopté des approches mathématiques différentes.

Serdalis
la source
2

Julia, 152 143 142 octets

Eh bien, j'ai mis à jour mon approche pour être moins "Julian", comme on dit, pour le golf. Pour une meilleure approche (quoique moins concise), consultez l'historique des révisions.

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

Cela crée une fonction sans nom qui accepte une chaîne ou un nombre à virgule flottante 64 bits et renvoie un nombre ou une chaîne à virgule flottante 64 bits, respectivement. Pour l'appeler, donnez-lui un nom, par exemple f=x->....

Non golfé + explication:

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

Exemples:

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

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

julia> f(f("23:42:12"))
"23:42:12"
Alex A.
la source
2

C, 137 octets

Programme C complet. Prend des entrées sur stdin et des sorties sur 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.);}

Non golfé et commenté:

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.);
    }
}
Andrea Biondo
la source
Utilisation très claire de scanf et% f
certains utilisateurs
Oh! Je voulais dire "intelligent".
un utilisateur
2

J, 85 octets

Résultats:

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

Total 85

Richard Donovan
la source
Bienvenue sur le site! J'ai modifié votre message afin que le code s'affiche comme code. Quant à un lien en ligne, le meilleur que je connaisse est TIO . Je vous donnerais un lien, mais je n'ai pas d'expérience avec J, donc je ne connais pas la bonne façon de l'invoquer. En outre, cela semble être de 91 octets lorsque vous incluez les première et dernière lignes. Est-ce correct?
DJMcMayhem
Merci de votre aide! Le programme [a = ... pour terminer.] Est 77. Le titre est 10. Le terminateur est 1, ce qui fait 88. Avec trois sauts de ligne cela fait 91! Je vais y travailler: o)
Richard Donovan
Maintenant, descendons à une ligne de 85 octets!
Richard Donovan
1

Javascript, 194 192 190 190 188 octets

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}
SuperJedi224
la source
1

JavaScript ES6, 98 130 octets

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);
Downgoat
la source
Malheureusement, les fonctions liées à l'heure (telles que "Date" et "toTimeString") ne sont pas autorisées dans ce défi. Sinon, c'est une façon beaucoup plus concise de le faire =)
Mwr247
@ Mwr247 oh n'a pas vu ça, je vais
arranger
1

C, 156 152 octets

Je pensais que ça allait être facile pour C. Mais j'ai quand même fini assez gros. :(

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

Programme de 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;
}

Production:

0.058160
0.123449
0.987639
0.500000
12:00:00
01:23:45
00:00:00
24:00:00
un utilisateur
la source
1

PHP, 70 69 octets

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

prend l'entrée de l'argument de ligne de commande, imprime dans STDOUT:

Si l'entrée contient deux points, convertissez en heure unix et divisez par (secondes par jour),
sinon valeur numérique à plusieurs chiffres avec (secondes par jour) et formatez l'heure unix en hh:mm:ss.

Titus
la source
1

Perl, 109 108 101 + 6 ( -plaF:drapeau) = 107 octets

$_=$#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

En utilisant:

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

Essayez-le sur Ideone.

Denis Ibaev
la source
0

Excel, 178 octets

=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)
Wernisch
la source