Mettre en place un chronomètre simple

25

Défi

Votre tâche consiste à écrire un programme qui, une fois par seconde (y compris immédiatement au démarrage de votre programme), imprime le temps écoulé depuis le démarrage de votre programme.

Règles

  • L'heure doit être imprimée au hh:mm:ssformat. (zéros non significatifs pour les valeurs à un chiffre)
  • Les horodatages doivent être séparés par CR, LF ou CRLF. (pas d'espace blanc de tête)
  • Une nouvelle heure doit apparaître chaque seconde. (stdout ne peut pas être mis en mémoire tampon pendant une seconde)
  • Le comportement du programme s'il est exécuté après 23:59:59 n'est pas défini.
  • Vous pouvez utiliser sleep(1)même si une seconde spécifique peut être ignorée chaque fois que la surcharge pour imprimer, calculer, boucler, etc. s'accumule en une seconde.

Exemple de sortie:

00:00:00
00:00:01
00:00:02
00:00:04
00:00:05
⋮

Notez qu'il 00:00:03manque ici en raison de la surcharge de traitement. Les valeurs ignorées réelles (le cas échéant) dépendent bien sûr de l'implémentation et / ou du système.

Implémentation de référence en C: (systèmes compatibles POSIX uniquement)

#include <unistd.h> // sleep()
#include <tgmath.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

#ifndef __STDC_IEC_559__
#error "unsupported double"
#endif
static_assert(sizeof(double) == 8, "double must have double precision");
#define MAX_PRECISE_DOUBLE ((double)(1ULL << 52))

int main(void) {
    time_t start = time(NULL);
    if (start == (time_t)-1) return EXIT_FAILURE;
    while (1) {
        time_t now = time(NULL);
        if (now == (time_t)-1) return EXIT_FAILURE;

        double diff = difftime(now, start);
        if (isnan(diff) || diff < 0) return EXIT_FAILURE;
        if (diff > MAX_PRECISE_DOUBLE) return EXIT_FAILURE;

        unsigned long long seconds = diff;
        unsigned long long h = seconds / 3600;
        seconds %= 3600;
        unsigned long long m = seconds / 60;
        seconds %= 60;
        unsigned long long s = seconds;

        (void)printf("\r%02llu:%02llu:%02llu", h, m, s);
        (void)fflush(stdout);

        (void)sleep(1);
    }
}

Critères gagnants

C'est le , le code le plus court en octets gagne!

MarkWeston
la source
Remarque pour les défis ultérieurs, une clarification dans les commentaires est une mauvaise chose à faire. référence
user202729

Réponses:

9

MATL , 17 16 octets

`Z`12L/13XOD1Y.T

Essayez-le sur MATL Online!

Comment ça marche

`         % Do...while loop
  Z`      %   Push seconds elapsed since start of program
  12L     %   Push 86400 (predefined literal)
  /       %   Divide. This transforms seconds into days
  13XO    %   Convert to date string with format 13, which is 'HH:MM:SS'
  D       %   Display
  1Y.     %   Pause for 1 second
  T       %   True. Used as loop condition for infinite loop
          % End loop (implicit)
Luis Mendo
la source
4
Comment diable avez-vous répondu à ces 37 minutes après sa fermeture? o_O blâme la mise en cache
M. Xcoder
9
@ Mr.Xcoder J'ai récemment appris à utiliser la Force
Luis Mendo
29

Langage de script Operation Flashpoint ,  174  171 octets

s=""
#l
t=_time
t=t-t%1
a=t%60
c=(t-a)/60
b=c%60
c=(c-b)/60
d=""
e=d
f=d
?a<10:d=0
?b<10:e=0
?c<10:f=0
s=s+format["%1%2:%3%4:%5%6\n",f,c,e,b,d,a]
hint s
@t+1<_time
goto"l"

En action:

158 octets, si l'heure précédente est remplacée par l'heure suivante:

#l
t=_time
t=t-t%1
a=t%60
c=(t-a)/60
b=c%60
c=(c-b)/60
d=""
e=d
f=d
?a<10:d=0
?b<10:e=0
?c<10:f=0
hint format["%1%2:%3%4:%5%6",f,c,e,b,d,a]
@t+1<_time
goto"l"

Techniquement, aucun retour chariot n'est utilisé, donc je ne sais pas si cette version se limite aux règles.

Steadybox
la source
5
Je ne m'attendais pas à un point d'éclair de fonctionnement.
Polyducks
10
@Polyducks personne ne s'attend à ce que le point d'éclair de l'opération
Pureferret
Depuis sous Unix, un CR écrasera la ligne, je pense que la deuxième réponse est validée par «CR, LF ou CRLF sont autorisés»
Stan Strum
1
@StanStrum Au moins sur mon Ubuntu CRne remplacera pas la ligne. En fait, CRLF, LFCRet LFsont tous sémantiquement équivalent.
13

Bash + coreutils, 28 26 octets

date -s0|yes date +c%T|sh

Le caractère non imprimable entre +et %est un octet ESC .

Cela définit l'heure système à 00:00:00 et nécessite donc des privilèges root. Il suppose également que le fuseau horaire est UTC et qu'aucun autre processus n'interférera avec l'horloge système.

Chaque nouveau timing réinitialise le terminal, écrasant ainsi le précédent.


Bash + coreutils, 38 29 octets

date -s0|yes date +%T|sh|uniq

Les mêmes restrictions que précédemment s'appliquent. Chaque nouveau chronométrage est affiché sur une nouvelle ligne.

Dennis
la source
Comme cela ne change pas le bytecount, je séparerais le premier datedu reste avec un joli petit saut de ligne. Mais cela pourrait être trop agréable pour quelqu'un capable de trouver quelque chose comme votre deuxième solution> :-(
Aaron
date -s0imprime la nouvelle heure sur STDOUT; J'utilise le tuyau pour couper cette sortie.
Dennis
Oh oui, merci pour l'explication!
Aaron
5

APL (Dyalog Unicode) , 51 octets

Corps de programme complet.

s←⎕AI
1↓∊':'@1∘⍕¨100+30 60 60 1E33⊃⎕AI-s
DL 1
2

Essayez-le en ligne! (Appuyez sur Ctrl + Entrée pour démarrer et à nouveau pour arrêter.)

⎕AIA ccount I nformation (ID utilisateur, temps de calcul, temps de connexion, temps de saisie)

s← affecter à s(pour s temps tarte)
⎕AI-s soustraient sde⎕AI

3⊃ choisissez le troisième élément (temps de connexion en millisecondes)
0 60 60 1E3⊤convertissez en ce mélange-radix
3↑ prenez les 3 premiers (supprime les millisecondes)
100+ cent ajoutés à chacun (pour ajouter des zéros)
':'@1∘⍕¨ modifiez avec deux points au premier caractère de la représentation de chaîne de chaque
ϵ nlist (flatten)
1↓ supprime le premier deux-points (et l'imprime implicitement sur stdout)

⎕DL 1D e l ay une seconde

→2 aller à la ligne numéro deux

Adam
la source
5

R , 59 44 octets

Fdans R par défaut FALSE, mais c'est une variable régulière et peut être redéfinie. Lorsqu'il est utilisé en arithmétique, FALSEest contraint 0. Demander F+1revient donc 1. Nous assignons Fà être F+1, formatez-le bien, imprimez et attendez une seconde. Continue indéfiniment.

repeat{print(hms::hms(F<-F+1))
Sys.sleep(1)}

Ne fonctionne pas sur TIO (en raison du manque de hmspackage), mais voici un exemple de sortie de ma machine:

00:00:00
00:00:01
00:00:02
00:00:03
00:00:04
00:00:05
00:00:06
00:00:07
00:00:08
00:00:09
00:00:10
00:00:11
00:00:12
00:00:13
rturnbull
la source
5

bash + sleep + date, également 50 49 47 46 45 41 octets

while date -ud@$[s++] +%T;do sleep 1;done

Pour prendre un temps au tour, appuyez rapidement sur ^ C, exécutez-le puis réexécutez ce qui précède:

laps=("${laps[@]}" $s) ; echo ${laps[-1]}

Réinitialiser:

s=0; unset laps

La syntaxe $ [s ++] semble toujours fonctionner, mais n'est plus (AFAICS) documentée dans la bashpage de manuel. Et c'est toujours un octet plus court que d'utiliser la boucle for ((...)), une fois que j'ai supprimé les guillemets qui l'entourent.

Will Crawford
la source
AFAICT, $[]est une forme obsolète / non documentée mais toujours prise en charge$(()) . Je ne sais pas s'il est couramment utilisé dans les réponses de code-golf, mais la règle générale est que votre code ne doit fonctionner que sur au moins une version de l'interpréteur pour votre langue. OMI ça va.
Peter Cordes
s=0n'est pas requis, car la substitution arithmétique traitera une variable non définie comme 0 . -un'est également pas nécessaire si vous supposez simplement le fuseau horaire par défaut (UTC).
Dennis
-u est nécessaire sur ma machine :)
Will Crawford
4

Swift , 144 octets

import Foundation
let s=Date()
while 1>0{let d=Int(-s.timeIntervalSinceNow)
print(String(format:"%02d:%02d:%02d",d/3600,d/60%60,d%60))
sleep(1)}

Explication

import Foundation                       // Import `Date` and `sleep()`
let s = Date()                          // Get the time at the start of the program
while 1 > 0 {                           // While 1 > 0 (forever):
  let d = Int(-s.timeIntervalSinceNow)  //   Calculate time difference
  print(String(format:"%02d:%02d:%02d", //   Print the time
      d/3600,d/60%60,d%60))
  sleep(1)                              //   Sleep one second
}
Herman L
la source
4

JavaScript (ES6), 99 octets

f=_=>console.log(new Date(new Date-d).toUTCString().slice(17,25))
f(d=Date.now(setInterval(f,1e3)))

darrylyeo
la source
2
Les heures ne commencent pas à 0 pour moi. Le décalage change en fonction du fuseau horaire de l'horloge système. (Win10)
LukeS
@LukeS Whoops, corrigé!
darrylyeo
4

Matlab (R2016b), 50 octets

t=now;while 1,disp(datestr(now-t,13)),pause(1),end

Explication:

t=now; % Stores the current time
while 1 % Loops forever
    disp(datestr(now-t,13)) % Computes the difference since the program started
    % And prints with format 13 ('HH:MM:SS') - this may change between versions
    pause(1) % Waits one second
end

Version alternative (50 octets aussi: P):

now;while 1,disp(datestr(now-ans,13)),pause(1),end
Thiago Oleinik
la source
Bienvenue sur le site! :)
DJMcMayhem
Thanks mate:)
Thiago Oleinik
@LuisMendo Merci pour la suggestion, mais je n'ai pas compris ... Dans votre exemple, quelle est la variable t? De plus, l'entrée à datestrest en jours, donc je devrais diviser par 86400, ce qui augmenterait le nombre d'octets de deux ...
Thiago Oleinik
3

Julia 0,6 , 75 68 octets

for h=0:23,m=0:59,s=0:59;@printf "%02i:%02i:%02i
" h m s;sleep(1)end

Essayez-le en ligne!

Avec sleep (1) autorisé, les boucles for imbriquées simples sont plus courtes que l'utilisation des méthodes de gestion du temps intégrées de Julias.

Ancienne solution sans sommeil (1) utilisant DateTime

t=now()-DateTime(0);Timer(x->println(Dates.format(now()-t,"HH:MM:SS")),0,1)

test le temps écoulé entre le «jour 0» et le démarrage du programme. now()-test un moment dans le temps , qui est ensuite formaté en utilisant Dates.format().

t0=now(); ...; now()-t0donnerait une différence de temps , qui ne peut pas être utilisée avec Dates.format().

Le timing lui-même est trivial avec le build-in Timer.

LukeS
la source
3

Python 2 , 85 octets

import time
t=0
while 1:print(":%02d"*3)[1:]%(t/3600,t/60%60,t%60);time.sleep(1);t+=1

Crédits

Neil
la source
Vous pouvez enregistrer un octet en le remplaçant "%02d:%02d:%02d"par(":%02d"*3)[1:]
wnnmaw
1
Vous n'avez pas besoin %24, le comportement n'est pas défini après 23:59:59.
Erik the Outgolfer
@EriktheOutgolfer Bon point, mis à jour.
Neil
3

JavaScript (ES6), 88 octets

f=_=>console.log(new Date(i++*1e3).toUTCString().slice(17,25))
f(i=0,setInterval(f,1e3))

Essentiellement la même approche que la réponse de @ darrylyeo , mais fonctionne pour tous les fuseaux horaires et utilise une manière légèrement différente pour arriver à 0.

[Modifier] La réponse de Darryl a été corrigée. C'est encore plus court, cependant.

Birjolaxew
la source
3

> <> , 82 + 7 = 89 octets

0\!
:/+1oan~?=3ln?$0(a:o":"n~?=4ln?$0(a:ro":"n~?=5ln?$0(a:,*a6-}:%*a6:,*a6-}:%*a6:

Essayez-le en ligne!

+7 octets pour utiliser l'indicateur -t.0125pour que chaque instruction prenne 1 / 80e de seconde. Chaque boucle contient 80 instructions, ce qui fait que chaque boucle dure une seconde. En raison du temps de calcul, cela est en fait plus long en pratique.

En fait, j'ai dû tamponner cela jusqu'à 100 jusqu'à ce que je voie la réponse de @Not A Tree qui avait 7 octets de meilleure façon que la mienne pour générer les heures et les minutes, en la coupant en dessous de 80. Ils ont également inspiré l'utilisation de ceux-ci \/qui sont exécutés deux fois par boucle.

Comment ça marche

0\...
./...
Initialises the stack with a 0 to represent the time

0\!
:/....................................................,*a6-}:%*a6:,*a6-}:%*a6:
Puts the hours, minutes and seconds in the stack

0\!
:/....n~?=3ln?$0(a:o":"n~?=4ln?$0(a:ro":"n~?=5ln?$0(a:...
Print out the hours, minutes, seconds separated by colons. 
If the number is below 0, print a leading 0. 
If the number is not, then there is an extra 0 on the stack, which is popped.

0\!
./+1oa...
Print a newline and increment the counter
And restart the loop

Prime:

Une version une ligne de la même taille, 80 + 9 octets:

0::6a*%:}-6a*,:6a*%:}-6a*,:a(0$?nl5=?~n":"or:a(0$?nl4=?~n":"o:a(0$?nl3=?~nao1+>!

Cela utilise l' -aindicateur pour ajouter des graduations pour les instructions ignorées.

Jo King
la source
3

PHP 4+, 70 64 octets

$x=time();while(1){sleep(1);echo date('H:i:s',time()-$x)."\n";}

PHP 5.3+, 69 63 octets

$x=time();a:sleep(1);echo date('H:i:s',time()-$x)."\n";goto a;
Darren H
la source
Les balises ouvertes PHP peuvent être omises dans la réponse, vous économisant 6 octets.
Daniel W.
2

Python 3 , 112 octets

En supposant que l'utilisation de délais d'une seconde est acceptable, même si elle (rarement) peut sauter une seconde.

from time import*;a=0
while 1:d=divmod;m,s=d(a,60);print(":".join(f"{k:02d}"for k in(*d(m,60),s)));a+=1;sleep(1)
Hannes Karppila
la source
2

VBA, 90

t=0:while(1):?format(t,"hh:mm:ss"):t=t+timeserial(0,0,1):q=timer:while q-timer<1:wend:wend

exécuter dans la fenêtre immédiate: point de défaillance prévu quelque part autour de 23 millions d'années (la résolution en virgule flottante échoue ~ 8,5 e9 jours)

SeanC
la source
2

Gelée , 23 octets

:⁽½c,60;%60d⁵j”:ṄœS1ṛ‘ß

Essayez-le en ligne!

Erik le Outgolfer
la source
Cela fonctionne-t-il avec des temps supérieurs à 1 minute?
H.PWiz
@ H.PWiz Il devrait, en exécutant quelques tests. EDIT: On dirait qu'un dividende est erroné pour les heures ... fixé pour une petite économie!
Erik the Outgolfer
2

AWK , 110 87 86 octets

BEGIN{for(;;i++){printf("%02d:%02d:%02d\n",i/3600%60,i/60%60,i%60);system("sleep 1")}}

Ne fonctionne pas dans TIO.

Noskcaj
la source
Votre programme ne semble pas s'imprimer 00:00:00au moment où il a démarré.
user202729
A corrigé. Merci
Noskcaj
2

APL (Dyalog) , 37 octets

{∇⍵+×⎕DL 1⊣⎕←1↓∊':'@1∘⍕¨100+⍵⊤⍨360}0

Essayez-le en ligne!

Programme complet.

Assez similaire à la réponse d'Adám, cependant écrite indépendamment et utilise une ⎕AIapproche non basée.

Erik le Outgolfer
la source
2

Bash + coreutils + date GNU, 50 octets

o=`date +"%s"`;yes date +%X -ud\"-$o sec\"|sh|uniq

Inspirée par @Dennis, cette solution ne nécessite pas de changement de temps. Il stocke le décalage initial à partir de maintenant à l'époque UNIX (1er janvier 1970 00:00:00 UTC), en «o», puis affiche [-ud options] (l'heure actuelle - décalage), en date UTC, mais uniquement [option +% X] HH: MM: SS. Cela devrait fonctionner dans les pays où le fuseau horaire actuel n'est pas UTC.

CSM
la source
2

Nettoyer , 173 172 168 168 octets

import StdEnv,System.Time
$n i#i=(i/60^n)rem 60
=(i/10,i rem 10)
f i w#(Clock j,w)=clock w
#j=j/1000
|j>i=[j:f j w]=f i w
Start w=[($2i,':',$1i,':',$0i,'
')\\i<-f -1 w]

Celui-ci ne fonctionne que sous les bundles Windows Clean.

Ajoutez 3 octets si vous voulez qu'il fonctionne sous Linux, comme Clean's CLK_PER_TICK :== 1000000on * nix. Si vous souhaitez qu'il soit multiplateforme, ajoutez plutôt 8 octets, car vous devez utiliser à la CLK_PER_TICKplace de la valeur sur laquelle il est défini. (Le lien TIO est plus grand en raison de ce qui précède )

Essayez-le en ligne!

Οurous
la source
2

Python 2 , 69 + 3 ( TZ=) = 72 octets

from time import*;s=time()
while 1:print ctime(time()-s)[11:19]+'\r',

Cela fonctionne en boucle continue, sans sommeil, mettant à jour l'heure sur la même ligne plutôt que d'imprimer une nouvelle ligne chaque seconde. (Toujours autorisé par les règles, j'espère.)

Cette version légèrement plus longue (72 + 3 = 75 octets) s'imprime à la place sur une nouvelle ligne toutes les secondes:

from time import*;s=time()
while 1:print ctime(time()-s)[11:19];sleep(1)

Les deux nécessitent que vous soyez dans le fuseau horaire UTC. Sous Linux, vous pouvez y parvenir en définissant la TZvariable d'environnement. Par exemple TZ= python.

mercator
la source
2

> <> , 106 octets 82 + 9 = 91 octets

Merci à Jo King d'avoir suggéré le -adrapeau! Découvrez également leur réponse .

0v+1oan<n0/
:/<</?(a:,*a6-}:%*a6:,*a6-}:%*a6:\\
n<n0/<</?(a:ro":"
":"n<n0/<</?(a:o

Essayez-le en ligne! (mais vous devrez attendre le délai d'attente de 60 secondes).

J'ai dû utiliser une fonctionnalité de> <> dont je n'avais jamais eu besoin auparavant: ce code nécessite l'indicateur -t.0125, qui définit la vitesse d'exécution à 0,0125 seconde par tick, ou 80 ticks par seconde. Il y a aussi le -adrapeau, qui fait que les espaces comptent comme une tique (dans certains cas - l'interprète est un peu bizarre à ce sujet).

Fondamentalement, le code conserve un compteur qui est incrémenté chaque fois que le poisson traverse la boucle, et le reste de la boucle convertit le compteur en hh:mm:ssformat et l'imprime. La boucle prend exactement 80 ticks.

Cela devrait fonctionner en théorie, mais en pratique, chaque tick est légèrement plus long que 0,0125 seconde, en raison du temps de calcul. Changer le \\sur la deuxième ligne pour <<donner des timings plus précis sur TIO.

Vous pouvez également regarder le code en action au terrain de jeu de poissons , sauf que cet interprète traite les espaces légèrement différemment de l'interprète officiel. Alternativement, vous pouvez supprimer les indicateurs sur TIO pour faire fonctionner le code à vitesse maximale, pour vérifier le comportement pendant des temps après une minute.

Pas un arbre
la source
-1 octet en remplaçant le v dans la première ligne par \!et en supprimant deux des supplémentaires <. Un autre couple d'octets si vous utilisez le -adrapeau, qui compte les espaces blancs et les instructions ignorées comme des tiques
Jo King
@JoKing, Le -adrapeau m'a laissé jouer un peu plus, merci! Je pense que vous pouvez aussi utiliser l' \!astuce dans votre code: essayez-le en ligne!
Pas un arbre du
2

Java 8, programme complet, 150 octets

interface M{static void main(String[]a)throws Exception{for(int i=0;;Thread.sleep(1000))System.out.printf("%02d:%02d:%02d%n",i/3600,i/60%60,i++%60);}}

Essayez-le ici (expire après 60 secondes, j'ai donc mis le sommeil à 1 pour voir plus de sortie).

Explication:

interface M{                    // Program:
  static void main(String[]a)   //  Mandatory main-method
     throws Exception{          //    Mandatory throws for Thread.sleep
    for(int i=0;                //   Start at 0
        ;                       //   Loop indefinitely
         Thread.sleep(1000))    //     After every iteration: Sleep for 1 sec
      System.out.printf("%02d:%02d:%02d%n",
                                //    Print in the format "HH:mm:ss\n":
        i/3600,i/60%60,i++%60); //     The hours, minutes and seconds
                                //     (and increase `i` by 1 afterwards with `i++`)
                                //   End of loop (implicit / single-line body)
  }                             //  End of mandatory main-method
}                               // End of program

Java 8, fonction, 94 octets

v->{for(int i=0;;Thread.sleep(1000))System.out.printf("%02d:%02d:%02d%n",i/3600,i/60%60,i++%60);}

Essayez-le ici (expire après 60 secondes, j'ai donc mis le sommeil à 1 pour voir plus de sortie).

Explication:

v->{   // Method with empty unused parameter and no return-type
  ...  //  Same as the program above
}      // End of method

Voici un petit gif pour voir qu'il fonctionne comme prévu lorsque 1000 ms sont utilisées:

entrez la description de l'image ici

Kevin Cruijssen
la source
2

PHP, 59 48 octets

while(1){sleep(1);echo date('H:i:s',$i++)."\n";}

Inspiré par la réponse de Darren H .

Ancienne version :

<?php while(1){sleep(1);echo date('H:i:s',$i++-3600)."\n";}
roberto06
la source
Les balises ouvertes PHP peuvent être omises dans la réponse, vous économisant 6 octets.
Daniel W.
Grande pensée, mais 3600 doit être 86400 sinon le compteur démarre à 23:00:00 donc malheureusement vous gagnez un octet, battez-moi quand même de 9!
Darren H
@DarrenH Je pense que cela dépend de votre région, je n'y avais pas pensé. Je suis en GMT + 1, c'est pourquoi j'ai ajouté 3600, mais je suppose que pour les anglais, vous pouvez supprimer le -3600tout, ce qui économiserait 5 octets.
roberto06
1

Shell , 177 octets

Notez que ce n'est pas entièrement conforme à POSIX car il utilise date +%s, qui est une dateextension courante .

a=`date +%s`;while true;do b=`date +%s`;s=`expr $b - $a`;h=`expr $s / 3600`;s=`expr $s % 3600`;m=`expr $s / 60`;s=`expr $s % 60`;printf '\r%02d:%02d:%02d' $h $m $s;sleep 1;done
MarkWeston
la source
7
Normalement, vous devez donner aux gens une chance de répondre à votre défi avant d'y répondre vous-même. Je recommande une semaine car certains ne peuvent être ici qu'à certains moments de la semaine.
Adám
1
@ Adám Je n'ai pas accepté ma réponse, et à l'époque j'ai posté des réponses beaucoup plus courtes (comme la vôtre).
MarkWeston
1

Rubis, 192117 octets (crédit à Dada)

t=Time.now
loop do
m,s=(Time.now-t).to_i.divmod(60)
h,m=m.divmod(60)
printf"%02d:%02d:%02d
",h,m,s
sleep 1
end

Comment ça marche?

Vous allez utiliser la version étendue (la conversion en une heure est donnée comme une fonction distincte et utilise un format de sortie différent):

def format_secs(s) # Converts the value in seconds to the required format
    mins, secs = s.divmod(60) # divmod returns the quotient and the remainder of a number
    hours, mins = mins.divmod(60)
    [hours,mins,secs].map { |e| e.to_s.rjust(2,'0') }.join ':'

    =begin
    [hours,mins,secs] -Creates a new array using the values allready provided for hours, minutes and seconds
    .map { - Creates a new array based on a operation on each of an array's values
    .to_s.rjust(2,'0')} - Turns the number into a string, and then adds "0" if needed to make the timer's result at least two digits
    .join ':' - Combines the result of the operation into a single string with a ":" in between the two numbers
    =end
end

t = Time.now # Saves the time at the program's (Rough) start

loop do
    puts format_secs((Time.now - t).to_i) # Returns the result of  the "format_secs" operation on the difference between the two times (in seconds) converted to a pure integer
    sleep 1 # Waits for one second
end
James007
la source
6
Bienvenue sur le site! Chaque réponse à un défi de code-golf doit être jouée. Vous devez au moins supprimer les espaces blancs inutiles et utiliser des noms de variable à 1 caractère. Cela vous donnerait environ 120 octets, et l'utilisation printfau lieu de putspeut économiser quelques octets supplémentaires: Essayez-le en ligne! . Bon golf sur PPCG!
Dada
1

APL NARS, 109 63 57 caractères

q;t
t←0
{∊⍵,¨':: '}{1<⍴x←⍕⍵:x⋄'0',x}¨(3⍴60)⊤⌊t+←⎕DL 1⋄→2

3 + 3 + 48 + 3 = 57 (vu les autres solutions Apl aussi)

{1<⍴x←⍕⍵:x⋄'0',x}

convertir l'INT ⍵ dans la chaîne de chiffres d'une manière si la longueur de cette chaîne est 1 que d'ajouter un '0' devant

{∊⍵,¨':: '}

combiner le tableau dans ⍵ avec le tableau «::»

00:00:01 
00:00:02 
00:00:03 
00:00:04 
00:00:05 
00:00:06 
00:00:07 
00:00:08 
00:00:09 
RosLuP
la source
1

Code machine x86-64 (appel système Linux): 78 octets

Synchronisation en boucle spin RDTSC , sys_writeappel système Linux .

x86-64 ne fournit pas un moyen pratique d'interroger la fréquence de "l'horloge de référence" RDTSC au moment de l'exécution. Vous pouvez lire un MSR (et faire un calcul basé sur cela) , mais cela nécessite le mode noyau, ou root + ouverture /dev/cpu/%d/msr, j'ai donc décidé de faire de la fréquence une constante de temps de construction. (Ajustez FREQ_RDTSCsi nécessaire: toute constante 32 bits ne changera pas la taille du code machine)

Notez que les processeurs x86 ont depuis plusieurs années une fréquence RDTSC fixe, il est donc utilisable comme source de temps, pas comme compteur de performances de cycle d'horloge de base, sauf si vous prenez des mesures pour désactiver les changements de fréquence. (Il existe des compteurs de performances réels pour compter les cycles CPU réels.) Habituellement, il coche à la fréquence nominale de l'autocollant, par exemple 4,0 GHz pour mon i7-6700k, indépendamment du turbo ou de l'économie d'énergie. Quoi qu'il en soit, cette temporisation d'attente ne dépend pas de la moyenne de la charge (comme le ferait une boucle de retard calibrée), et n'est pas non plus sensible à l'économie d'énergie du processeur.

Ce code fonctionnera pour tout x86 avec une fréquence de référence inférieure à 2 ^ 32 Hz, soit jusqu'à ~ 4,29 GHz. Au-delà de cela, les 32 bas de l'horodatage se termineraient en 1 seconde, donc je devrais aussi regarder les edx32 bits élevés du résultat.

Résumé :

pousser 00:00:00\nsur la pile. Puis en boucle:

  • sys_write appel système
  • Boucle ADC sur les chiffres (en commençant par le dernier) pour incrémenter le temps de 1. Emballage / report traité avec un cmp/ cmov, le résultat CF fournissant le report pour le chiffre suivant.
  • rdtsc et enregistrez l'heure de début.
  • tourner rdtscjusqu'à ce que le delta soit> = ticks par seconde de la fréquence RDTSC.

Liste NASM:

 1  Address                            ; mov  %1, %2       ; use this macro to copy 64-bit registers in 2 bytes (no REX prefix)
 2           Machine code           %macro MOVE 2
 3           bytes                      push  %2
 4                                      pop   %1
 5                                  %endmacro
 6                                  
 7                                      ; frequency as a build-time constant because there's no easy way detect it without root + system calls, or kernel mode.
 8                                      FREQ_RDTSC equ 4000000000
 9                                  global _start
10                                  _start:
11 00000000 6A0A                        push     0xa                       ; newline
12 00000002 48BB30303A30303A3030        mov      rbx, "00:00:00"
13 0000000C 53                          push     rbx
14                                      ; rsp points to  `00:00:00\n`
20                                  
21                                      ; rbp = 0                (Linux process startup.  push imm8 / pop is as short as LEA for small constants)
22                                      ; low byte of rbx = '0'
23                                  .print:
24                                      ; edx potentially holds garbage (from rdtsc)
25                                  
26 0000000D 8D4501                      lea      eax, [rbp+1] ; __NR_write = 1
27 00000010 89C7                        mov      edi, eax     ; fd = 1 = stdout
28                                      MOVE     rsi, rsp
28 00000012 54                  <1>  push %2
28 00000013 5E                  <1>  pop %1
29 00000014 8D5008                      lea      edx, [rax-1 + 9]     ; len = 9 bytes.
30 00000017 0F05                        syscall               ; sys_write(1, buf, 9)
31                                  
32                                      ;; increment counter string:  least-significant digits are at high addresses (in printing order)
33 00000019 FD                          std                        ;  so loop backwards from the end, wrapping each digit manually
34 0000001A 488D7E07                    lea      rdi, [rsi+7]
35                                      MOVE     rsi, rdi
35 0000001E 57                  <1>  push %2
35 0000001F 5E                  <1>  pop %1
36                                  
37                                      ;; edx=9 from the system call
38 00000020 83C2FA                      add   edx, -9 + 3      ; edx=3 and set CF (so the low digit of seconds will be incremented by the carry-in)
39                                      ;stc
40                                  .string_increment_60:          ; do {
41 00000023 66B93902                    mov    cx, 0x0200 + '9'    ; saves 1 byte vs. ecx.
42                                      ; cl = '9' = wrap limit for manual carry of low digit.  ch = 2 = digit counter
43                                    .digitpair:
44 00000027 AC                          lodsb
45 00000028 1400                        adc      al, 0           ; carry-in = cmp from previous iteration; other instructions preserve CF
46 0000002A 38C1                        cmp      cl, al          ; manual carry-out + wrapping at '9' or '5'
47 0000002C 0F42C3                      cmovc    eax, ebx        ; bl = '0'.  1B shorter than JNC over a MOV al, '0'
48 0000002F AA                          stosb
49                                  
50 00000030 8D49FC                      lea     ecx, [rcx-4]    ; '9' -> '5' for the tens digit, so we wrap at 59
51 00000033 FECD                        dec     ch
52 00000035 75F0                        jnz    .digitpair
53                                      ; hours wrap from 59 to 00, so the max count is 59:59:59
54                                  
55 00000037 AC                          lodsb                        ; skip the ":" separator
56 00000038 AA                          stosb                        ; and increment rdi by storing the byte back again.  scasb would clobber CF
57                                  
58 00000039 FFCA                        dec     edx
59 0000003B 75E6                        jnz   .string_increment_60
60                                  
61                                      ; busy-wait for 1 second.  Note that time spent printing isn't counted, so error accumulates with a bias in one direction
62 0000003D 0F31                        rdtsc                         ; looking only at the 32-bit low halves works as long as RDTSC freq < 2^32 = ~4.29GHz
63 0000003F 89C1                        mov      ecx, eax             ; ecx = start
64                                  .spinwait:
65                                  ;    pause
66 00000041 0F31                        rdtsc                      ; edx:eax = reference cycles since boot
67 00000043 29C8                        sub      eax, ecx          ; delta = now - start.  This may wrap, but now we have the delta ready for a normal compare
68 00000045 3D00286BEE                  cmp      eax, FREQ_RDTSC   ; } while(delta < counts_per_second)
69                                   ;   cmp      eax, 40  ; fast count to test printing
70 0000004A 72F5                        jb     .spinwait
71                                  
72 0000004C EBBF                        jmp .print
  next address = 0x4E = size = 78 bytes.

Décommentez l' pauseinstruction d'économiser une puissance significative: cela chauffe un cœur de ~ 15 degrés C sans pause, mais seulement de ~ 9 avec pause. (Sur Skylake, où il pausedort pendant ~ 100 cycles au lieu de ~ 5. Je pense que cela économiserait plus s'il rdtscn'était pas aussi lent, donc le CPU ne fait pas beaucoup de temps).


Une version 32 bits serait plus courte de quelques octets, par exemple en utilisant une version 32 bits pour pousser la chaîne initiale 00: 00: 00 \ n.

16                          ;    mov      ebx, "00:0"
17                          ;    push     rbx
18                          ;    bswap    ebx
19                          ;    mov      dword [rsp+4], ebx    ; in 32-bit mode, mov-imm / push / bswap / push would be 9 bytes vs. 11

Et en utilisant également 1 octet dec edx. L' int 0x80appel système ABI n'utiliserait pas esi / edi, donc la configuration du registre pour syscall vs lodsb / stosb pourrait être plus simple.

Peter Cordes
la source
J'aurais pu utiliser un nanosleepappel système, mais c'était plus intéressant. Avec root sur Linux, il est possible de lire le bon MSR et d'obtenir par programmation la fréquence RDTSC.
Peter Cordes
1

q / kdb + , 40 octets

Solution:

.z.ts:{-1($)18h$a+:1};a:-1;(.)"\\t 1000"

Exemple:

q).z.ts:{-1($)18h$a+:1};a:-1;(.)"\\t 1000"
q)00:00:00
00:00:01
00:00:02
00:00:03
00:00:04
00:00:05

Explication:

Il y a trois commandes en cours d'exécution ici:

  1. .z.ts:{-1($)18h$a+:1}; / override timer function
  2. a:-1; / initialise variable a to -1
  3. (.)"\\t 1000" / start the timer with 1000ms precision

Répartition de la fonction minuterie:

.z.ts:{-1 string 18h$a+:1} / ungolfed timer function
      {                  } / lambda function
                     a+:1  / add 1 to variable a
                 18h$      / cast to seconds
          string           / cast to string
       -1                  / write to stdout
.z.ts:                     / assign this function to .z.ts

Prime:

Alternative 1 pour 41 octets :

a:.z.t;.z.ts:{-1($)18h$x-a};(.)"\\t 1000"

Alternative 2 pour 26 + 7 octets = 33 octets

.z.ts:{-1($)18h$a+:1};a:-1

et en ajoutant -t 1000comme arguments au q binaire.

streetster
la source