Implementa un cronometro


23

Implementa un semplice cronometro digitale , che visualizzerà il tempo trascorso in secondi e minuti, come descritto di seguito.

Importante

Leggi le sezioni Display e Controlli !

Display

Il tempo trascorso, deve essere visualizzato nel MM:SSformato, sostituendo la stringa di tempo "sul posto" precedentemente visualizzata (è anche consentito cancellare l'intero o una parte dello schermo).

Il cronometro deve essere aggiornato almeno ogni secondo.

Esempi:

0 minuti, 0 secondi

00:00

0 minuti, 33 secondi

00:33

1 minuto, 50 secondi

01:50

Inizialmente, puoi iniziare con '00: 00 'o con qualsiasi altro valore nell'intervallo [00: 00-59: 59].

Quando il cronometro raggiunge 59:59, dovrebbe reimpostare 00:00e continuare nuovamente.

Se lo desideri, puoi utilizzare una base diversa (anziché decimale) o anche un sistema numerico diverso, purché segua il modello generale.

Ad esempio 13:03può essere visualizzato come:

Decimale

13:03

esadecimale

0D:03

Base64

N:D

Base quater-immaginaria

10101:3

Numeri romani

XIII:III

Fare attenzione che se si utilizza un sistema / base numerale non decimale, è necessario codificarlo utilizzando caratteri ASCII (o Unicode) stampabili, ad esempio utilizzando due byte binari (non stampabili) per minuti e secondi non è consentito.

È inoltre necessario spostare a sinistra l'output con gli zeri appropriati, se il sistema numerico lo consente.

:È anche accettabile la sostituzione del carattere separatore con qualsiasi altro carattere stampabile (comprese le cifre).

controlli

Il cronometro dovrebbe iniziare in pausa e rimanere in questo stato, fino a quando l'utente non lo avvia esplicitamente , premendo il tasto 'control' (vedi sotto).

Se, mentre il cronometro sta contando, l'utente preme di nuovo il tasto 'control' , il cronometro dovrebbe mettere in pausa (mantenendo l'ora corrente), fino a quando il tasto 'control' viene premuto ancora una volta.

Il 'controllo' chiave può essere un singolo tasto, per esempio s, o qualsiasi combinazione di tasti, ad esempio Ctrl+Shift+X, ma deve essere 'atomico', premendo più tasti in sequenza, ad esempio squindi Enter, è non consentito .

Lo stesso tasto 'control' (o combinazione) deve essere usato per mettere in pausa e ripristinare il cronometro.

È necessario utilizzare una chiave "control" specifica , ovvero "qualsiasi chiave" non è consentita.

In alternativa, è possibile utilizzare un clic singolo o doppio del mouse, anziché un tasto per "controllo".


Regole

  • Questo è , vince la risposta più breve in byte;
  • Si applicano scappatoie standard per il golf da codice;
  • Il tuo programma deve (teoricamente) essere in grado di funzionare per sempre.

Il tasto 'control' può essere inserito?
Loovjo,

@Loovjo Sì, qualsiasi tasto singolo o combinazione di tasti lo farà, incluso Invio (purché possa essere messo in pausa e poi ripreso usando lo stesso tasto).
Zeppelin,


1
Abbiamo bisogno di una granularità inferiore al secondo? Vale a dire se l'utente fa una pausa di circa 7000 millisecondi dopo la 00:05stampa, e poi ad un certo punto riprende, deve 00:06apparire 3000 millisecondi dopo che è stato premuto il tasto Riprendi, oppure è corretto stamparlo un secondo intero dopo che è stato premuto il tasto Riprendi?
smls

@smls Va bene aspettare un secondo intero, dopo il curriculum.
Zeppelin,

Risposte:


8

SmileBASIC, 86 77 71 byte

@L
N=N!=DIALOG(FORMAT$("%02D:%02D",F/60MOD 60,F MOD 60),,,N)F=F+1GOTO@L

DIALOGvisualizza una casella di testo sul touchscreen. Nè il numero di secondi in cui la casella di testo rimarrà sullo schermo prima che scompaia. Se Nè 0, rimane fino a quando l'utente preme il pulsante sul touch screen.

DIALOGRestituisce 1se l'utente ha premuto il pulsante e 0se si è chiuso automaticamente. Pertanto, quando l'utente preme il pulsante di pausa, ritorna 1e il tempo di visualizzazione è impostato su 0, mettendo in pausa il cronometro. Dopo che l'utente ha premuto nuovamente il pulsante, riportiamo il tempo di visualizzazione su 1, riprendendo il timer. Fondamentalmente, ogni volta che DIALOGritorna 1, il tempo di visualizzazione viene commutato tra 1e 0usando !=, che è eqivilante a un XOR logico purché entrambi gli ingressi siano 1 o 0.


Sembra fantastico! Se potessi anche fornire uno "screencast" animato di come funziona, sarebbe molto apprezzato!
Zeppelin,

Ok, lo farò presto
12Me21

Potrebbe anche essere testato su questo emulatore: citra-emu.org/game/smilebasic
roblogic

9

Python 2, 167 129 byte

-36 byte per lo più * dall'uso dell'idea di Maltysen di catturare ctrl-cusando un'eccezione - vai a dare credito!
-4 byte grazie a DLosc (init ne ba 0 anziché f())
-1 byte grazie a FlipTack (usare p^=1anziché p=1-p)
-2 byte grazie a Felipe Nardi Batista (rimuovere gli specificatori di precisione)

import time
f=time.time
n=b=p=0
while 1:
 try:n=[n,f()][p];t=n-b;print'\r%02d:%02d'%(t/60%60,t%60),
 except:b=[b-n+f(),b][p];p^=1

Funziona come il mio originale, di seguito, ma con la sequenza di tasti di controllo di ctrl+c.
(Testato da me con Python 2.7.8 su Windows 7, 64 bit;
Testato da Brian Minton con Python 2.7.13 su Linux, 64 bit)

* ha anche compresso l' ifistruzione in una ricerca elenco per ottenere il trycomando one-liner.

Il mio originale:

import time,msvcrt as m
f=time.time
n=b=p=0
while 1:
 if m.kbhit()and m.getch()==b'p':b=[b-n+f(),b][p];p^=1
 if p:n=f()
 t=n-b;print'\r%0.2d:%0.2d'%(t/60%60,t%60),

(Testato da me con Python 2.7.8 su Windows 7, 64 bit - questo codice, tuttavia, è specifico di Windows a causa dell'uso della msvcrtlibreria)

La chiave di controllo è 'p'.

ne bvengono inizializzati allo stesso valore all'avvio, dando un "offset" di 0; pviene inizializzato su 0, indicando uno stato di pausa.

Ogni volta che si preme il tasto di controllo, il valore di pviene commutato. Quando si passa da uno stato in pausa a uno stato attivo, questo bviene aggiornato con un nuovo valore mantenendo qualsiasi offset di corrente dagli stati attivi precedenti con b-n.

Durante uno stato attivo nviene ripetutamente aggiornato all'ora corrente chiamando time.time().

La differenza tra ne b, tè quindi il numero totale di secondi (inclusa una parte frazionaria) trascorsi durante gli stati attivi.

I minuti trascorsi vengono quindi visualizzati t/60e ciascuno dei minuti e dei secondi viene visualizzato mod 60 con (t/60%60,t%60). Gli zeri iniziali vengono anteposti per ciascuno utilizzando la formattazione di stringa della parte intera con '...%0.2d...'. La stampa di una tupla (il finale ,) in cui il primo elemento ha un ritorno a capo (il \r) fa sì che il testo precedentemente stampato venga sovrascritto.


Ah sì, buona cattura, in origine avevo ^=ma a un certo punto sono passato durante la formulazione.
Jonathan Allan,

@DLosc davvero, grazie ...
Jonathan Allan,

Non è specifico di Windows. Ho appena provato questo su Linux 64 bit con Python 2.7.13 e ha funzionato. (con il tasto di controllo di Ctrl-C)
Brian Minton,

@BrianMinton grazie per avermelo fatto notare!
Jonathan Allan,

qual è il bisogno di .in %0.2d? funziona benissimo come%02d
Felipe Nardi Batista,

6

Python - 160 159 143 byte

Grazie a @JonathanAllan per avermi salvato 18 byte!

Utilizza solo librerie integrate, quindi il tasto di controllo è ctrl-c, catturandolo con un except keyboardInterrupt.

import time
Z=0
print'00:00'
while 1:exec"try:\n while 1:\n  %s\nexcept:1\n"*2%(1,"print'\033c%02d:%02d'%divmod(Z%3600,60);Z+=1;time.sleep(1)")

Oh bello. Penso che forse potrebbe essere più breve con solo except:? Ho una mia versione funzionante che lo fa ...
Jonathan Allan,

@JonathanAllan oh cool, non sapevo che potevi farlo.
Maltysen,

5

bash + utility Unix, 90 o 93 byte

Versione a 90 byte:

trap d=\$[!d] 2;for((n=0;;)){((d|!n))&&dc<<<DP60dod*d$n\r%+n|colrm 1 4&&: $[n++];sleep 1;}

Versione a 93 byte:

trap d=\$[!d] 2;for((n=0;;)){((d|!n))&&dc<<<DP60dod*$n+n|colrm 1 4&&n=$[(n+1)%3600];sleep 1;}

Ctrl-C è il carattere di ripresa / pausa. Uno spazio è il delimitatore tra minuti e secondi.

La differenza tra le due versioni è che il programma a 90 byte funzionerà per 2 ^ 63 secondi (a quel punto, bash mi darà un overflow intero).

La versione a 93 byte funzionerà davvero per sempre.

Il problema originale includeva il requisito: "Il tuo programma deve (teoricamente) essere in grado di funzionare per sempre".

Se l'esecuzione per 2 ^ 63 secondi è sufficiente per soddisfare tale requisito, la soluzione a 90 byte funziona. Quella durata è più di 20 volte l'età dell'universo!

Se il programma deve essere in grado di funzionare più a lungo, dovrò scegliere la soluzione a 93 byte.


Dovrei probabilmente sottolineare che questa soluzione, così come almeno alcune delle altre pubblicate, rimarrà molto lentamente indietro rispetto al vero tempo trascorso. Questo slittamento è dovuto al fatto che il programma sta dormendo per un secondo tra ogni esecuzione del corpo del loop, ma il corpo del loop impiega un po 'di tempo per essere eseguito. Ciò sarà in pratica irrilevante.


Sembra che questo non visualizzerà un valore iniziale sullo schermo, fino a quando non lo "toglierai".
Zeppelin,

"Il cronometro dovrebbe iniziare in pausa e rimanere in questo stato, fino a quando l'utente non lo avvia esplicitamente, premendo il tasto 'control' (vedi sotto)." C'è una specifica che mi è sfuggita?
Mitchell Spector,

sì, questo è corretto, ma dovrebbe comunque visualizzare un valore iniziale Initially, you can start with '00:00' or with any other value in range [00:00-59:59], che rimarrà sullo schermo fino a quando non si preme 'control' per la prima volta. Scusa se non sono stato in grado di formulare questo in modo abbastanza chiaro!
Zeppelin,

OK, ha senso - lo modificherò.
Mitchell Spector,

1
Sembra tutto bene ora!
Zeppelin,

5

QBasic, 213 211 byte

Il tasto di controllo è una scheda. Lasciare questo in esecuzione può causare incendi del laptop. Sei stato avvertito.

DO
WHILE k$<>CHR$(9)
k$=INKEY$
LOCATE 1
?CHR$(48+m\10);CHR$(48+(m MOD 10));":";CHR$(48+(d MOD 60)\10);CHR$(48+(d MOD 10))
IF r THEN
n=TIMER
d=v+n-b+86400
m=d\60MOD 60
END IF
WEND
k$=""
v=v+n-b
r=1-r
b=TIMER
LOOP

Eccolo in azione, in pausa a 10, 15 e 20 secondi:

Cronometro in esecuzione

Ungolf e commentato

' Outer loop runs forever
DO
  ' The WHILE-WEND loop runs until tab is pressed
  WHILE key$ <> CHR$(9)
    key$ = INKEY$
    ' Output the stopwatch value at top left of screen
    LOCATE 1
    ' Unfortunately, QBasic's PRINT USING doesn't have a format for printing
    ' with leading zeros, so we have to do it manually by printing the
    ' 10s digit and the 1s digit
    PRINT CHR$(48 + minute \ 10); CHR$(48 + (minute MOD 10));
    PRINT ":";
    PRINT CHR$(48 + second \ 10); CHR$(48 + (second MOD 10))
    ' Update the current time if the running flag is set
    IF running THEN now = TIMER
    ' Take the difference between now and the last time we started the
    ' stopwatch, plus the amount of saved time from previous runs,
    ' plus 86400 to account for the possibility of running over midnight
    ' (since TIMER is the number of seconds since midnight, and QBasic's
    ' MOD doesn't handle negative values like we would need it to)
    diff = saved + now - lastStarted + 86400
    second = diff MOD 60
    minute = diff \ 60 MOD 60
  WEND
  ' If we're outside the WHILE loop, the user pressed tab
  key$ = ""
  ' Add the previous run's time to the saved amount
  saved = saved + now - lastStarted
  ' Toggle running between 0 and 1
  running = 1 - running
  ' If we're starting, we want to put the current time in lastStarted;
  ' if we're stopping, it doesn't matter
  lastStarted = TIMER
LOOP

Si noti che i valori di TIMERsono in virgola mobile. Questo non influisce l'uscita, dal momento che MODe \Tronca a numeri interi. Ma aggiunge precisione alla quantità di tempo risparmiato: se metti in pausa il timer prima di un segno di spunta, vedrai che quando lo avvii di nuovo il numero cambia in meno di un secondo.


4

Lotto, 132 byte

set/ar=0,m=s=100
:l
cls
@choice/t 1 /d y /m %m:~1%:%s:~1% /n
set/as+=r,m+=c=s/160,s-=c*60,m-=m/160*60,r^^=%errorlevel%-1
goto l

Premendo n(un) si mette in pausa il timer. Lo sfarfallio di uscita può essere ridotto al costo di tre (o quattro) byte.


4

Bash puro, 141 byte

set -m
while ! read -t 1;do printf '\r%02i:%02i' $[s=s>3598?0:s+1,s/60] $[s%60];done&trap 'fg>/dev/null' TSTP
printf '00:00'
kill -STOP $!
read

Questo non usa altro che i built-in di Bash (nessuno strumento esterno). Il carattere di controllo è Ctrl-Z, quindi la SIGTSTPgestione standard mette in pausa il cronometro.

Se Ctrl-Zviene premuto mentre la subshell è in primo piano, metterà in pausa l'esecuzione e riporterà lo script esterno in primo piano, dove attenderà in silenzio. Se lo script esterno è in primo piano, il gestore trap riprenderà l'esecuzione della subshell e conterà nuovamente.


3

Javascript nella console di Chrome, 143 byte

f=document,m=s=g=i=0;setInterval(()=>{if(g%2){m=(i/60|0)%60;s=i++%60}f.write((m>9?m:'0'+m)+':'+(s>9?s:'0'+s));f.close();f.onclick=()=>g++},1e3)

Quando inserito nella console, entra nel contatore alle 00:00 e quindi abilita il controllo che è la pressione dei tasti sul documento.

Non sta succedendo molta magia, in particolare i (i/60)|0piani il numero

Fatto e testato nella console di Chrome


Bella risposta. È possibile rimuovere alcuni byte utilizzando un argomento fittizio per le funzioni che non accettano un argomento e è possibile sostituire il primo argomento in setInterval con una stringa contenente il codice.
Luca,

1
132 B:m=s=g=i=0;(f=document).onclick=_=>g++;setInterval("g%2&&f.close(f.write(`${(m=i/60%60|0)>9?m:'0'+m}:`+((s=i++%60)>9?s:'0'+s)))",1e3)
Luca,

Ohh, bello :) Ho imparato un paio di cose qui. Stringa in intervallo e _ => g ++. Grazie :)
gzbz,

3

HTML + JavaScript (ES6), 191 192 187 183 174 byte

<b onclick='b=b?clearInterval(b):setInterval("a.innerHTML=`${(d=(((c=a.innerHTML.split`:`)[1]>58)+c[0])%60)>9?d:`0`+d}:${(e=++c[1]%60)>9?e:`0`+e}",1e3)'onload='b=0'id=a>00:00

Spiegazione

Fai clic sul timer per avviare o mettere in pausa il cronometro. Pertanto, un singolo clic è la chiave di controllo . Il separatore tra i due valori è due punti.

Ogni volta che l'utente fa clic sul clic, bviene verificato il valore di . Viene inizializzato a 0quale valuta false, quindi una stringa di codice viene valutata ogni 1000 millisecondi. Questo imposta la variabile sull'id dell'intervallo, quindi può essere fermata in un secondo momento. Se bcontiene un numero, viene valutato in true, quindi l'intervallo viene interrotto. Questo restituisce il valore undefined, quindi il ciclo continua.

La stringa di codice cambia l'html dell'elemento con id a(il cronometro). Innanzitutto i minuti vengono analizzati prendendo il valore del cronometro precedente, suddividendolo per i due punti e ottenendo il valore dei minuti, che viene aumentato di 0 se il valore dei secondi non è 59 (maggiore di 58) e 1 altrimenti, modulo 60 Quindi questo valore viene riempito. Poi arrivano i due punti e, infine, i secondi. Il codice ottiene semplicemente il vecchio valore, lo aumenta di 1, prende il modulo 60 e facoltativamente lo riempie.


Questo non sembra funzionare affatto. Ho appena ricevuto ReferenceError: d non è definito
Alexis Tyler,

Probabilmente puoi anche salvare qualche byte rimuovendo href = # poiché non è effettivamente necessario poiché stai usando onclick.
Alexis Tyler,

L'ho appena risolto. Ho anche rimosso l'href, perché avevi ragione. Grazie!
Luca

Non puoi mettere il clic sul tag b e specificarlo nella risposta?

Suppongo che funzioni. Ha salvato 9B. Molte grazie!
Luca,

3

C 309 179 byte

f(){m=0,s=0;A: while(getchar()^'\n'){if(s++==59){if(m++==59)m=0;s=0;}printf("\r%02d:%02d",m,s);sleep(1);system("clear");if(getchar()=='\n'){break;}}while(getchar()^'\n'){}goto A;}

Versione non golfata:

void f()
{
   int m=0,s=0;

   A: while(getchar()^'\n')
      {           
       if(s++==59)
       {
         if(m++==59)
           m=0;

         s=0;
       }
       printf("\r%02d:%02d",m,s);
       sleep(1);  
       system("clear");

        if(getchar()=='\n')
        {
          break;
        }
      }

       while(getchar()^'\n')
       {}
       goto A ;
}

Utilizzo: premere Enterper mettere in pausa e ripristinare il cronometro.

Spiegazione:

  • Attendere la Entersequenza di tasti, breakil primo whileciclo e attendere fino al prossimo Enter.
  • Alla successiva Enterpressione del tasto, gotoprimo whileciclo e riprendere il conteggio.

Ora, so che gotoè una cattiva pratica di programmazione in C, ma non sono riuscito a trovare un altro modo.


Il codice non viene compilato. Inoltre, si getchar()blocca fino a quando non viene premuto un personaggio.
G. Sliepen,

compila e gira su una macchina linux
Abel Tom il

Forse la versione non golfata, ma la versione golfata no. Già m=0,s=0;fallisce, perché non hai dichiarato queste variabili da nessuna parte.
G. Sliepen,

3

Javascript, 124 byte

s=i=1,setInterval("s&&(d=document).close(d.write(`0${i/60%60|0}:`.slice(-3)+`0${i++%60}`.slice(-2))),d.onclick=_=>s=!s",1e3)

La "chiave di controllo" è un clic sul documento. Per verificarlo, incolla il codice nella console o in un file html all'interno del <script>tag.

Spiegazione:

let s = 1
let i = 1
setInterval(() => {
    //If s = true then check after the "&&" operator else false
    s && (d = document).close( //put the document variable inside the d variable, so now i don't need to use anymore the long word 'document, then i close the document
            d.write( //Write into the document the next string
                `0${i/60%60|0}:`.slice(-3) + `0${i++%60}`.slice(-2) //Here is the magic, here I update the 'i' variable and convert the 'i' value to minutes and seconds
            ) 
        ),
        d.onclick = _ => s = !s //Add onclick event to the document, if s = true then s = false, if s = false then s = true
}, 1e3) //1e3 = 1000

Testato in Chrome


1
Benvenuti nel sito! Sarebbe possibile modificare in un collegamento a un sito di test online, ad esempio Provalo online! , in modo che altri utenti possano verificare la tua risposta?
caird coinheringaahing

Grazie @cairdcoinheringaahing, questo è con jsfiddle: jsfiddle.net/xjw7o0ps
TheCopyright

2

PHP, 94 91 byte

Presumo che 32 sia il codice chiave per la barra spaziatrice (che probabilmente non lo è);
Al momento non ho modo di testare ncurses. Ma il resto del codice funziona bene.

for($s=[STDIN];;)echo date("\ri:s",$t+=$r^=stream_select($s,$n,$n,1)&&32==ncurses_getch());

inizia alle 00:00, ma aumenta immediatamente quando termina la pausa

Se (come me) non hai ncurses, puoi provare sostituendo il secondo dateparametro con $t+=$r^=!rand(sleep(1),19);o $t+=$r^=++$x%20<1+sleep(1);. ( sleepritorna sempre 0.)

abbattersi

for($s=[STDIN];                     // set pointer for stream_select
    ;                               // infinite loop:
)
    echo date("\ri:s",                  // 5. print CR + time
        $t+=                            // 4. increment $t if watch is running
        $r^=                            // 3. then toggle pause
            stream_select($s,$n,$n,1)   // 1. wait 1 second for a keystroke
            &&32==ncurses_getch()       // 2. if keystroke, and key==space bar
    ;

2

C # 220 byte

using static System.Console;
using static System.DateTime;
class P
{
    static void Main()
    {
        var l = Now;
        var d = l-l;
        for( var r = 1<0;;Write($"\r{d:mm\\:ss}"))
        {
            if (KeyAvailable&&ReadKey(1<2).KeyChar == 's')
            {
                l = Now;
                r = !r;
            }
            if (r)
                d -= l - (l = Now);
        }

    }
}

golfed

using static System.Console;using static System.DateTime;class P{static void Main(){var l=Now;var d=l-l;for(var r=1<0;;Write($"\r{d:mm\\:ss}")){(KeyAvailable&&ReadKey(1<2).KeyChar=='s'){l=Now;r=!r;}if(r)d-=l-(l=Now);}}}

Utilizzo del stasto per avviare / arrestare. L'intero programma funziona ricordando l'utilizzo di TimeDeltaDateTime.Now

La maggior parte dei C # -Magic qui deriva dalla funzione C # 7.0 using static.


2

Bash, 65 byte

trap d=\$[!d] 2;for((;;)){ printf "\r%(%M:%S)T" $[n+=d];sleep 1;}

Nota che deve essere scritto in uno script di file per funzionare correttamente, oppure prova:

bash -c 'trap d=\$[!d] 2;for((;;)){ printf "\r%(%M:%S)T" $[n+=d];sleep 1;}'

Versione estesa per spiegarlo:

trap d=\$[!d] 2                     # flip d for each INT (ctrl-c) signal.
for((n=0;;)){                       # repeat forever the code inside the {...}
                                    # The n=0 is not strictly needed.
    printf "\r%(%M:%S)T" "$[n+=d]"  # Print Minute:Second string calculated from 
                                    # the n value, increment by the value of d.
                                    # If IFS is not numeric (0-9), then, the
                                    # quotes around "$[n+=d]" could be removed.
    sleep 1                         # wait for 1 second.
}

Il %(...)Tformato di printf è valido in bash 5+.


Non funziona Stampa 00:00e incrementa un contatore quando colpisci Ctrl-C. Non c'è animazione del timer. (Testato su bash 5.0.7)
roblogic

1
Hai scritto il codice in uno script? Oppure riprova: bash -c 'trap d=\$[!d] 2;for((;;)){ printf "\r%(%M:%S)T" $[n+=d];sleep 1;}'. @roblogic
Isaac,

Ah, ha funzionato! Lo script deve essere eseguito con bash -c:)
roblogic il

1

C (gcc) , 121 115 byte

p,r;g(){r^=1;}main(t,b){for(b=time(signal(2,g));;r?p=t:(b+=t!=p))t=time(0)-b,printf("\r%02d:%02d  ",t/60%60,t%60);}

Provalo online!

Imposta un gestore di segnale per SIGINT, che viene attivato premendo control-C. Manteniamo un offset di tempo be visualizziamo il tempo dell'orologio a muro meno il time offset. Se siamo in pausa, aumenta la base dei tempi ogni volta che l'orologio a muro ticchetta per bloccare il tempo visualizzato.

Grazie a @ceilingcat per la rasatura di 6 byte!


0

Data Zsh + Gnu, 242 byte

Con 1/100 di secondo! Richiede un terminale interattivo, ma qui c'è comunque un collegamento TIO .
Premi Enterper avviare / arrestare il timer; Ctrl-Cuscire.

u(){p=`gdate +%s`;q=`gdate +%N`;}
f(){read -t0.01&&{read;break};unset REPLY}
g(){while :;{u;t=$[p-a];s=$[t%60];m=$[(t%3600-s)/60]
echo "\r`printf %02d:%02d $m $s`.$q[1,2]\c";f;}}
<<<ready;read;u;a=$p
while :;{f;echo "\r\e[2A\c";u;a=$[p-t];g;}

Commenti (un po 'obsoleti):

u()echo $[`gdate +%s%N`/1000]       # fn:unix timestamp extended to µs
v()gdate +%s                        # fn:unix time, in s
f(){read -t0.01 -r&&{read -r;break;} # fn:listens for "Enter"
                      ;unset REPLY;}

g(){while :;                        # fn:rolling stopwatch
    {q=`u`;t=$[`v`-a]               #    t=time diff from baseline (s)
    ;echo "\r`printf %02d:%02d      #    format output
    $[(t%3600-s)/60] $s`            #    minutes:seconds
    .${q:10:2}\c";                  #    .xx = partial seconds
    f;}}                            #    listen for "Enter"

                                    # Execution starts here!
<<<ready;read;u;a=$p                # Wait for "Enter"; get baseline $a

while :;{                           # Main program loop
         f;                         # listen for an "Enter"
           echo "\r\e[2A\c"         # go up 1 line of the console
a=$[`v`-t]                          # reset the baseline
                ;g;}                # begin the stopwatch

@Isaac, non c'è modo di battere la tua risposta per brevità ed eleganza, quindi ho pensato di aggiungere funzionalità invece ...
roblogic

1
Questo è un obiettivo eccellente @roblogic :-) .... .... ancora capire il tuo codice ....
Isaac il

0

Commodore BASIC (C64 / TheC64 Mini, VIC-20, PET, C16 / + 4) - 147 byte tokenizzati e BASIC

 0?"{clear}":geta$:ifa$<>" "thengoto
 1ti$="000000"
 2fori=.to1:?"{home}"mid$(ti$,3,2)":"mid$(ti$,5,2):geta$:b$=ti$:i=-(a$=" "):nE:pO198,.
 3geta$:ifa$<>" "then3
 4ti$=b$:goto2

{clear}nell'elenco è quello SHIFT+CLR/HOMEche genera un carattere PETSCII quando segue un segno di virgolette di apertura, mentre {home}è la CLR/HOMEchiave senza lo spostamento sulla stessa condizione di seguire un segno di virgolette di apertura.

Utilizzare la barra spaziatrice come tasto di controllo.

Per lavorare con Commodore 128 in BASIC 7, modifica l'elenco nelle seguenti righe:

 0?"{clear}":geta$:ifa$<>" "thengoto0
 2fori=.to1:?"{home}"mid$(ti$,3,2)":"mid$(ti$,5,2):geta$:b$=ti$:i=-(a$=" "):nE:poK198,.

Aggiunge altri sette token al conteggio (poiché tutti i numeri sono memorizzati in BASIC come 7 byte, quindi goto10sono 8 byte tokenizzati mentre gotoè solo 1).

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.