Implementar um cronômetro

23

Implemente um cronômetro digital simples , que exibirá o tempo decorrido em segundos e minutos, conforme descrito abaixo.

Importante

Por favor, leia as seções Display e Controls !

Exibição

O tempo decorrido deve ser exibido no MM:SS formato, substituindo a sequência de horas exibida anteriormente "no local" (limpar a totalidade ou parte da tela também é permitido).

O cronômetro deve ser atualizado pelo menos a cada segundo.

Exemplos:

0 minutos, 0 segundos

00:00

0 minutos, 33 segundos

00:33

1 minuto, 50 segundos

01:50

Inicialmente, você pode começar com '00: 00 'ou com qualquer outro valor no intervalo [00: 00-59: 59].

Quando o cronômetro chegar 59:59, ele deve redefinir para00:00 e continuar novamente.

Você pode usar uma base diferente (em vez de decimal) ou mesmo um sistema numérico diferente, se desejar, desde que siga o padrão geral.

Por exemplo, 13:03pode ser exibido como:

Decimal

13:03

Hexadecimal

0D:03

Base64

N:D

Base quarto-imaginária

10101:3

Números romanos

XIII:III

Lembre-se de que se você usar um sistema / base numeral não decimal, ele deverá ser codificado usando caracteres ASCII (ou Unicode) imprimíveis, por exemplo, o uso de dois bytes binários (não imprimíveis) por minutos e segundos não será permitido.

Você também deve deixar sua saída com zeros, conforme apropriado, se o seu sistema numérico permitir isso.

Substituir o caractere separador :por qualquer outro caractere imprimível (incluindo dígitos) também é aceitável.

Controles

O cronômetro deve começar em pausa e permanecer nesse estado até que o usuário inicie explicitamente , pressionando a tecla 'control' (veja abaixo).

Se, enquanto o cronômetro estiver contando, o usuário pressionar a tecla 'control' novamente, o cronômetro deverá pausar (mantendo a hora atual), até que o 'controle' tecla seja pressionada mais uma vez.

O 'controlo' chave pode ser uma única tecla, por exemplo s, ou qualquer combinação de teclas, por exemplo Ctrl+Shift+X, mas deve ser 'atómica', pressionando múltiplas chaves em sequência, por exemplo s, em seguida Enter, é não autorizados .

A mesma tecla 'controle' (ou combinação) deve ser usada para pausar e retomar o cronômetro.

Você deve usar uma chave 'control' específica , ou seja, 'qualquer tecla' não é permitida.

Como alternativa, você pode usar um clique simples ou duplo do mouse, em vez de pressionar uma tecla para 'controle'.


Regras

  • Isso é , a resposta mais curta em bytes vence;
  • Aplicam-se lacunas de código-golfe padrão;
  • Seu programa deve (teoricamente) ser capaz de funcionar para sempre.
zepelim
fonte
A tecla 'controle' pode ser inserida?
Loovjo 28/01
@Loovjo Sim, qualquer tecla única ou combinação de teclas funcionará, incluindo Enter (desde que possa ser pausada e depois retomada usando a mesma tecla).
Zeppelin
relacionado
Jonathan Allan
1
Precisamos de granularidade de sub-segundo? Ou seja, se o usuário pausar aproximadamente 7000 milissegundos após a 00:05impressão e, em algum momento, retomar novamente, deve 00:06aparecer 3000 milissegundos após a tecla retomar ser pressionada, ou está correto imprimi-lo um segundo inteiro depois que a tecla retomar foi pressionada?
SMLS
@smls Não há problema em esperar um segundo inteiro, após o resumo.
Zeppelin

Respostas:

8

SmileBASIC, 86 77 71 bytes

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

DIALOGexibe uma caixa de texto na tela de toque. Né o número de segundos em que a caixa de texto permanecerá na tela antes de desaparecer. Se Né0 , ele permanece até o usuário pressionar o botão na tela de toque.

DIALOGRetorna 1se o usuário pressionou o botão e 0se fechou automaticamente. Portanto, quando o usuário pressiona o botão de pausa, ele retorna 1e o tempo de exibição é definido como 0, pausando o cronômetro. Depois que o usuário pressiona o botão novamente, ajustamos o tempo de exibição para 1, retomando o temporizador. Basicamente, sempre que DIALOGretorna 1, o tempo de exibição é alternado entre 1e 0utilizado !=, o que é equivalente a um XOR lógico, desde que ambas as entradas sejam 1 ou 0.

12Me21
fonte
Isso parece incrível! Se você também pudesse fornecer um "screencast" animado de como funciona, isso seria muito apreciado!
Zeppelin
Ok, eu vou fazer isso em breve
12Me21
Também poderia ser testado neste emulador: citra-emu.org/game/smilebasic
roblogic
9

Python 2, 167 129 bytes

-36 bytes principalmente * de usar a idéia de Maltysen de capturar ctrl-cusando uma exceção - vá dar crédito!
-4 bytes graças ao DLosc (init ne b0 ao invés de f())
-1 byte graças ao FlipTack (use p^=1ao invés de p=1-p)
-2 bytes graças a Felipe Nardi Batista (remova os especificadores de precisão)

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

Funciona da mesma forma que o original, abaixo, mas com a sequência de teclas de controle de ctrl+c.
(Testado por mim com o Python 2.7.8 no Windows 7, 64 bits;
Testado por Brian Minton com o Python 2.7.13 no Linux, 64 bits)

* também reduziu a ifinstrução de uma pesquisa de lista para obter a informação trycomo uma linha.

Meu original:

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

(Testado por mim com o Python 2.7.8 no Windows 7, 64 bits - este código, no entanto, é específico do Windows devido ao uso do msvcrt biblioteca)

A tecla de controle é 'p'.

ne bsão inicializados com o mesmo valor na inicialização, fornecendo um "deslocamento" de 0; pé inicializado como 0, indicando um estado de pausa.

Sempre que a tecla de controle é pressionada, o valor de pé alterado. Ao alternar de um estado em pausa para um estado ativo, ele bé atualizado para um novo valor, mantendo qualquer deslocamento atual dos estados ativos anteriores b-n.

Durante um estado ativo, né atualizado repetidamente para a hora atual chamando time.time().

A diferença entre ne b,, té então o número total de segundos (incluindo uma parte fracionária) decorrido durante o (s) estado (s) ativo (s).

Os minutos decorridos são então t/60e cada um dos minutos e segundos é exibido com o mod 60 (t/60%60,t%60). Os zeros à esquerda são anexados a cada um usando a formatação de string da parte inteira com '...%0.2d...'. Imprimir uma tupla (a direita ,) em que o primeiro item tem um retorno de carro (a \r) faz com que o texto impresso anteriormente seja substituído.

Jonathan Allan
fonte
Ah, sim, boa captura, eu originalmente ^=mudei em algum momento durante a formulação.
Jonathan Allan
@DLosc fato, obrigado ...
Jonathan Allan
Não é específico do Windows. Acabei de testar isso no linux de 64 bits com o Python 2.7.13 e funcionou. (com a tecla de controle Ctrl-C)
Brian Minton 02/02
@BrianMinton obrigado por me avisar!
Jonathan Allan
qual é a necessidade do .in %0.2d? funciona muito bem como%02d
Felipe Nardi Batista
6

Python - 160 159 143 bytes

Graças a @ JonathanAllan por me salvar 18 bytes!

Somente usa bibliotecas internas, portanto a chave de controle é ctrl-ccapturada com um 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)")
Maltysen
fonte
Ah legal. Eu acho que talvez pudesse diminuir com apenas except:? Eu tenho uma versão de trabalho da mina fazendo isso ...
Jonathan Allan
@ JonathanAllan oh legal, não sabia que você poderia fazer isso.
Maltysen 28/01
5

utilitários bash + Unix, 90 ou 93 bytes

Versão de 90 bytes:

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

Versão de 93 bytes:

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

Ctrl-C é o caractere de retomar / pausar. Um espaço é o delimitador entre minutos e segundos.

A diferença entre as duas versões é que o programa de 90 bytes funcionará por 2 ^ 63 segundos (nesse ponto, o bash fornecerá um estouro de número inteiro).

A versão de 93 bytes realmente funcionará para sempre.

O problema original incluía o requisito: "Seu programa deve (teoricamente) ser capaz de funcionar para sempre".

Se executar por 2 ^ 63 segundos for suficiente para atender a esse requisito, a solução de 90 bytes funcionará. Essa duração é mais de 20 vezes a idade do universo!

Se o programa precisar ser executado por mais tempo do que isso, terei que usar a solução de 93 bytes.


Provavelmente, devo salientar que esta solução, bem como pelo menos algumas das outras postadas, ficará muito lentamente para trás do verdadeiro tempo decorrido. Esse desvio ocorre porque o programa está inativo por um segundo entre cada execução do corpo do loop, mas o corpo do loop leva uma pequena quantidade de tempo para ser executado. Isso será inconseqüente na prática.

Mitchell Spector
fonte
Parece que isso não exibirá um valor inicial na tela até que você o "pause".
Zeppelin
"O cronômetro deve começar em pausa e permanecer nesse estado até que o usuário o inicie explicitamente, pressionando a tecla 'control' (veja abaixo)." Existe uma especificação que eu perdi?
Mitchell Spector
Sim, isso está correto, mas ainda deve exibir um valor inicial Initially, you can start with '00:00' or with any other value in range [00:00-59:59], que permanecerá na tela até você pressionar 'control' pela primeira vez. Desculpe se não fui capaz de formular isso com clareza suficiente!
Zeppelin
OK, isso faz sentido - eu vou modificá-lo.
precisa saber é o seguinte
1
Parece tudo de bom agora!
Zeppelin
5

QBasic, 213 211 bytes

Chave de controle é tab. Sair dessa execução pode causar incêndios no laptop. Você foi avisado.

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

Aqui está em ação, parando em 10, 15 e 20 segundos:

Cronômetro em execução

Ungolfed e comentou

' 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

Observe que os valores de TIMERsão de ponto flutuante. Isso não afeta a saída, uma vez MODe \truncado para números inteiros. Mas isso adiciona precisão à quantidade de tempo economizado: se você pausar o cronômetro imediatamente antes de um tiquetaque, verá quando o iniciar novamente que o número muda em menos de um segundo.

DLosc
fonte
4

Lote, 132 bytes

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

Pressionar n(des) pausará o temporizador. O tremulação da saída pode ser reduzido a um custo de três (ou quatro) bytes.

Neil
fonte
4

Festa pura, 141 bytes

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

Isso não usa nada além dos Bash builtins (sem ferramentas externas). O caractere de controle é Ctrl-Z, de modo que o padrãoSIGTSTP manuseio pausa o cronômetro.

Se Ctrl-Zfor pressionado enquanto o subshell estiver em primeiro plano, ele interromperá a execução e retornará o script externo para o primeiro plano, onde aguardará silenciosamente. Se o script externo estiver em primeiro plano, o manipulador de traps continuará a execução do subshell e contará novamente.

Michael Homer
fonte
3

Javascript no console do Chrome, 143 bytes

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 inserido no console, ele entra no contador até 00:00 e ativa o controle pressionado com tecla no documento.

Não há muita mágica acontecendo, principalmente a (i/60)|0 o número de andares

Concluído e testado no console do Chrome

gzbz
fonte
Boa resposta. Você pode remover alguns bytes usando um argumento fictício para as funções que não assumem um argumento e pode substituir o primeiro argumento no setInterval por uma sequência que contém o código.
Lucas
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)
Lucas
Ohh, bom :) Aprendi algumas coisas aqui. String no intervalo e _ => g ++. Obrigado :)
gzbz
3

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

<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

Explicação

Clique no cronômetro para iniciar ou pausar o cronômetro. Como tal, um único clique é a chave de controle . O separador entre os dois valores é dois pontos.

Sempre que o usuário clica no clique, o valor de bé verificado. É inicializado para o 0qual é avaliado false, portanto, uma sequência de códigos é avaliada a cada 1000 milissegundos. Isso define a variável para o ID do intervalo, para que possa ser interrompida posteriormente. Se bcontiver um número, ele avalia como true, portanto, o intervalo é parado. Isso retorna o valor undefined, então o ciclo continua.

A sequência de códigos altera o html do elemento com o id a(o cronômetro). Primeiro, os minutos são analisados ​​usando o valor anterior do cronômetro, dividindo-o pelos dois pontos e obtendo o valor dos minutos, que é aumentado em 0 se o valor dos segundos não for 59 (maior que 58) e 1 caso contrário, módulo 60 Então esse valor é preenchido. Depois vem o cólon e, finalmente, os segundos. O código simplesmente obtém o valor antigo, aumenta em 1, pega o módulo 60 e opcionalmente o preenche.

Luke
fonte
Isso parece não funcionar. Acabei de chegar ReferenceError: d não é definido
Alexis Tyler
Provavelmente, você também pode salvar alguns bytes removendo o href = #, pois não é realmente necessário, pois você está usando o onclick.
Alexis Tyler
Eu apenas consertei isso. Também removi o href, porque você estava certo. Obrigado!
Luke
Você não pode colocar o onclick na tag b e especificá-lo na resposta?
Suponho que funcione. Ele salvou 9B. Muito obrigado!
Lucas
3

C 309 179 bytes

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

Versão não destruída:

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

Uso: Pressione Enterpara Pausar e Continuar o Cronômetro.

Explicação:

  • Aguarde o Enterpressionamento de tecla, breako primeiro whileloop e aguarde até o próximo Enter.
  • No próximo Enterpressionamento de tecla, gotoprimeiro faça um whileloop e retome a contagem.

Agora, eu sei que gotoé uma prática ruim de codificação em C, mas não consegui descobrir outra maneira.

Abel Tom
fonte
O código não compila. Além disso, getchar()bloqueia até que algum caractere seja pressionado.
G. Sliepen
compila e roda em uma máquina Linux
Abel Tom
A versão não-golfada, talvez, mas a versão do golfe não. Já m=0,s=0;falha, porque você não declarou essas variáveis ​​em nenhum lugar.
G. Sliepen
3

Javascript, 124 bytes

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)

A 'chave de controle' é um clique no documento. Para testar isso, cole o código no console ou em um arquivo html dentro do diretório<script> tag.

Explicação:

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

Testado no Chrome

Direitos autorais
fonte
1
Bem vindo ao site! Seria possível editar em um link para um site de testes online, como Experimente online! , para que outros usuários possam verificar sua resposta?
caird coinheringaahing
Obrigado @cairdcoinheringaahing, isto é com jsfiddle: jsfiddle.net/xjw7o0ps
TheCopyright
2

PHP, 94 91 bytes

Presumo que 32 seja o código-chave da barra de espaço (o que provavelmente não é);
Atualmente, não tenho como testar ncurses. Mas o resto do código funciona bem.

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

começa em 00:00 , mas aumenta imediatamente quando a pausa termina

Se você (como eu) não possui ncurses, pode testar substituindo o segundo dateparâmetro por $t+=$r^=!rand(sleep(1),19);ou $t+=$r^=++$x%20<1+sleep(1);. (sleep sempre retorna0 .)

demolir

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
    ;
Titus
fonte
2

C # 220 bytes

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

    }
}

Golfe

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

Usando o s tecla para iniciar / parar. Todo o programa funciona lembrando o TimeDelta usandoDateTime.Now

A maioria das mágicas C # aqui vem do recurso C # 7.0 using static.

CSharpie
fonte
2

Bash, 65 bytes

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

Observe que ele deve ser gravado em um script de arquivo para funcionar corretamente; caso contrário, tente:

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

Versão estendida para explicar:

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

O %(...)Tformato para printf é válido no bash 5+.

Isaac
fonte
Não funciona Apenas imprime 00:00e incrementa um contador quando você bate Ctrl-C. Não há animação do cronômetro. (Testado no bash 5.0.7)
roblogic
1
Você escreveu o código em um script? Ou então tente: bash -c 'trap d=\$[!d] 2;for((;;)){ printf "\r%(%M:%S)T" $[n+=d];sleep 1;}'. @roblogic
Isaac
Ahh, isso funcionou! O script deve ser executado com bash -c:)
roblogic
1

C (gcc) , 121 115 bytes

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

Experimente online!

Define um manipulador de sinal para SIGINT, que é acionado pressionando o controle-C. Mantemos um deslocamento de tempo emb e exibimos a hora do relógio de parede menos a diferença horária. Se fizermos uma pausa, aumente a base de tempo toda vez que o relógio da parede bater para congelar o tempo exibido.

Graças a @ceilingcat por cortar 6 bytes!

G. Sliepen
fonte
0

Data Zsh + Gnu, 242 bytes

Apresentando 1/100 de segundo! Requer um terminal interativo, mas aqui está um link TIO .
Pressione Enterpara iniciar / parar o cronômetro;Ctrl-Csair.

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

Comentários (um pouco desatualizados):

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
roblogic
fonte
@ Isaac, não há como eu responder à sua resposta por brevidade e elegância, então pensei em adicionar recursos ...
roblogic 26/08
1
Esse é um excelente objetivo @roblogic :-) .... .... ainda entendendo seu código ....
Isaac
0

Commodore BASIC (C64 / TheC64 Mini, VIC-20, PET, C16 / + 4) - 147 bytes tokenizados 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}na listagem é SHIFT+CLR/HOMEque sai como um caractere PETSCII ao seguir uma aspas de abertura, enquanto que {home}é a CLR/HOMEchave sem a mudança na mesma condição de seguir uma aspas de abertura.

Use a barra de espaço como chave de controle.

Para trabalhar com o Commodore 128 no BASIC 7, altere a listagem nas seguintes linhas:

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

Adiciona sete tokens extras à contagem (como todos os números são armazenados no BASIC como 7 bytes, portanto, goto10 ocorre com 8 bytes tokenizados, enquanto que gotoé apenas 1).

Shaun Bebbers
fonte