Implementar un cronómetro

23

Implemente un cronómetro digital simple , que mostrará el tiempo transcurrido en segundos y minutos, como se describe a continuación.

Importante

¡Lea las secciones de Pantalla y Controles !

Monitor

El tiempo transcurrido, debe mostrarse en el MM:SSformato, reemplazando la cadena de tiempo mostrada anteriormente "en el lugar" (también se permite borrar la totalidad o una parte de la pantalla).

El cronómetro debe actualizarse al menos cada segundo.

Ejemplos:

0 minutos, 0 segundos

00:00

0 minutos, 33 segundos

00:33

1 minuto, 50 segundos

01:50

Inicialmente, puede comenzar con '00: 00 'o con cualquier otro valor en el rango [00: 00-59: 59].

Una vez que su cronómetro llega 59:59, debe reiniciarse 00:00y continuar de nuevo.

Puede usar una base diferente (en lugar de decimal) o incluso un sistema de numeración diferente si lo desea, siempre que siga el patrón general.

Por ejemplo, 13:03se puede mostrar como:

Decimal

13:03

Hexadecimal

0D:03

Base64

N:D

Base Quater-imaginaria

10101:3

Números romanos

XIII:III

Tenga en cuenta que si utiliza un sistema / base de numeración no decimal, debe codificarse con caracteres ASCII (o Unicode) imprimibles, por ejemplo, no está permitido usar dos bytes binarios (no imprimibles) durante minutos y segundos.

También debe dejar a la izquierda su salida con ceros, según corresponda, si su sistema numérico lo permite.

Reemplazar el carácter separador :con cualquier otro carácter imprimible (incluidos los dígitos) también es aceptable.

Controles

El cronómetro debe comenzar en pausa y permanecer en este estado, hasta que el usuario lo inicie explícitamente , presionando la tecla 'control' (ver más abajo).

Si, mientras el cronómetro está contando, el usuario presiona la tecla 'control' nuevamente, el cronómetro debe pausar (manteniendo la hora actual), hasta que la tecla 'control' se presione una vez más.

El 'control' clave puede ser una única pulsación de tecla, por ejemplo s, o cualquier combinación de teclas, por ejemplo Ctrl+Shift+X, pero debe ser 'atómica', presionando varias teclas en secuencia, por ejemplo, sentonces Enter, está no permitido .

Se debe usar la misma tecla de 'control' (o combinación) para pausar y reanudar el cronómetro.

Debe usar una tecla específica de 'control' , es decir, 'ninguna tecla' no está permitida.

Alternativamente, puede usar un clic del mouse simple o doble, en lugar de presionar una tecla para 'control'.


Reglas

  • Este es el , gana la respuesta más corta en bytes;
  • Se aplican las lagunas de código estándar de golf;
  • Su programa debe (en teoría) ser capaz de ejecutarse para siempre.
zepelín
fuente
¿Se puede ingresar la tecla 'control'?
Loovjo
@Loovjo Sí, cualquier tecla o combinación de teclas funcionará, incluida Enter (siempre que pueda pausarse y luego reanudarse con la misma tecla).
zepelín
relacionado
Jonathan Allan
1
¿Necesitamos granularidad por debajo del segundo? Es decir, si el usuario hace una pausa de aproximadamente 7000 milisegundos después de que 00:05se imprime y luego, en algún momento, se reanuda nuevamente, ¿deben 00:06aparecer 3000 milisegundos después de presionar la tecla de reanudar, o está bien imprimirlo un segundo después de presionar la tecla de reanudar?
sonríe el
@smls Está bien esperar un segundo completo, después del currículum.
zepelín

Respuestas:

8

SmileBASIC, 86 77 71 bytes

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

DIALOGmuestra un cuadro de texto en la pantalla táctil. Nes el número de segundos que el cuadro de texto permanecerá en la pantalla antes de que desaparezca. Si Nes así 0, permanece hasta que el usuario presiona el botón en la pantalla táctil.

DIALOGDevuelve 1si el usuario presionó el botón y 0si se cerró automáticamente. Entonces, cuando el usuario presiona el botón de pausa, regresa 1y el tiempo de visualización se establece en 0, pausando el cronómetro. Después de que el usuario presiona el botón nuevamente, configuramos el tiempo de visualización nuevamente 1, reanudando el temporizador. Básicamente, cada vez que DIALOGregresa 1, el tiempo de visualización cambia 1y se 0usa !=, lo que es equivalente a un XOR lógico siempre que ambas entradas sean 1 o 0.

12Me21
fuente
¡Esto se ve increíble! Si también pudiera proporcionar un "screencast" animado de cómo funciona, ¡eso sería muy apreciado!
zepelín
Ok, lo haré pronto
12Me21
También podría probarse en este emulador: citra-emu.org/game/smilebasic
roblogic
9

Python 2, 167 129 bytes

-36 bytes en su mayoría * por usar la idea de Maltysen de atrapar ctrl-cusando una excepción: ¡vaya a dar crédito!
-4 bytes gracias a DLosc (init ny ba 0 en lugar de f())
-1 byte gracias a FlipTack (usar en p^=1lugar de p=1-p)
-2 bytes gracias a Felipe Nardi Batista (eliminar especificadores de precisión)

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 igual que mi original, a continuación, pero con la secuencia de teclas de control de ctrl+c.
(Probado por mí con Python 2.7.8 en Windows 7, 64 bits;
Probado por Brian Minton con Python 2.7.13 en Linux, 64 bits)

* también se contrajo la ifdeclaración a una búsqueda en la lista para obtener tryuna sola línea.

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

(Probado por mí con Python 2.7.8 en Windows 7, 64 bits; sin embargo, este código es específico de Windows debido al uso de la msvcrtbiblioteca)

La tecla de control es 'p'.

ny bse inicializan con el mismo valor al inicio, dando un "desplazamiento" de 0; pse inicializa a 0, lo que indica un estado en pausa.

Cada vez que se presiona la tecla de control, pse cambia el valor de . Cuando se cambia de un estado en pausa a un estado activo, bse actualiza a un nuevo valor manteniendo cualquier compensación actual del estado (s) activo anterior con b-n.

Durante un estado activo nse actualiza repetidamente a la hora actual mediante una llamada time.time().

La diferencia entre ny b, tes entonces el número total de segundos (incluida una parte fraccional) transcurrido durante el estado o estados activos.

Los minutos transcurridos son entonces t/60y cada uno de los minutos y segundos se muestran mod 60 con (t/60%60,t%60). Los ceros iniciales se anteponen para cada uno utilizando el formato de cadena de la parte entera con '...%0.2d...'. Imprimir una tupla (el final ,) donde el primer elemento tiene un retorno de carro inicial (el \r) hace que se sobrescriba el texto previamente impreso.

Jonathan Allan
fuente
Ah sí, buena captura, originalmente sí, ^=pero cambié en algún momento durante la formulación.
Jonathan Allan
@DLosc de hecho, gracias ...
Jonathan Allan
No es específico de Windows. Acabo de probar esto en Linux 64 bit con Python 2.7.13 y funcionó. (con la tecla de control de Ctrl-C)
Brian Minton
@BrianMinton gracias por hacérmelo saber!
Jonathan Allan
¿cuál es la necesidad de que el .en %0.2d? funciona bien como%02d
Felipe Nardi Batista
6

Python - 160 159 143 bytes

¡Gracias a @JonathanAllan por salvarme 18 bytes!

Solo usa bibliotecas incorporadas, por lo que la clave de control es ctrl-catraparlo 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)")
Maltysen
fuente
Oh bien. Creo que tal vez podría acortar con solo except:? Tengo una versión mía que funciona haciéndolo ...
Jonathan Allan
@ JonathanAllan oh genial, no sabía que podías hacer eso.
Maltysen
5

bash + utilidades Unix, 90 o 93 bytes

Versión de 90 bytes:

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

Versión 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 es el carácter de reanudación / pausa. Un espacio es el delimitador entre minutos y segundos.

La diferencia entre las dos versiones es que el programa de 90 bytes funcionará durante 2 ^ 63 segundos (en ese momento, bash me dará un desbordamiento de enteros).

La versión de 93 bytes realmente funcionará para siempre.

El problema original incluía el requisito: "Su programa debe (en teoría) ser capaz de ejecutarse para siempre".

Si correr durante 2 ^ 63 segundos es suficiente para cumplir con ese requisito, entonces la solución de 90 bytes funciona. ¡Esa duración es más de 20 veces la edad del universo!

Si el programa necesita poder ejecutarse por más tiempo que eso, tendré que ir con la solución de 93 bytes.


Probablemente debería señalar que esta solución, así como al menos algunas de las otras publicadas, se retrasarán muy lentamente el tiempo transcurrido verdadero. Este deslizamiento se debe a que el programa está inactivo durante un segundo entre cada ejecución del cuerpo del bucle, pero el cuerpo del bucle tarda una pequeña cantidad de tiempo en ejecutarse. Esto será intrascendente en la práctica.

Mitchell Spector
fuente
Parece que esto no mostrará un valor inicial en la pantalla, hasta que lo "pause".
zepelín
"El cronómetro debe comenzar en pausa y permanecer en este estado, hasta que el usuario lo inicie explícitamente, presionando la tecla 'control' (ver más abajo)". ¿Hay alguna especificación que me perdí?
Mitchell Spector
Sí, esto es correcto, pero aún debe mostrar un valor inicial Initially, you can start with '00:00' or with any other value in range [00:00-59:59], que permanecerá en la pantalla hasta que presione 'control' por primera vez. Lo siento si no he podido formular esto lo suficientemente claro.
zepelín
OK, eso tiene sentido, lo modificaré.
Mitchell Spector
1
¡Todo se ve bien ahora!
zepelín
5

QBasic, 213 211 bytes

La tecla de control es la pestaña. Dejar esto en funcionamiento puede provocar incendios en la computadora portátil. Usted ha sido advertido.

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

Aquí está en acción, haciendo una pausa a los 10, 15 y 20 segundos:

Cronómetro corriendo

Ungolfed y comentó

' 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

Tenga en cuenta que los valores de TIMERson de punto flotante. Esto no afecta a la salida, desde MODy \truncado a enteros. Pero sí agrega precisión a la cantidad de tiempo ahorrado: si pausa el temporizador justo antes de un tic, verá que cuando lo enciende nuevamente, el número cambia en menos de un segundo.

DLosc
fuente
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

Al presionar nse (des) pausará el temporizador. El parpadeo de salida se puede reducir a un costo de tres (o cuatro) bytes.

Neil
fuente
4

Bash puro, 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

Esto usa nada más que basuras integradas de Bash (sin herramientas externas). El carácter de control es Ctrl-Z, de modo que el SIGTSTPmanejo estándar detiene el cronómetro.

Si Ctrl-Zse presiona mientras el subshell está en primer plano, hará una pausa en la ejecución y devolverá el script externo al primer plano, donde esperará en silencio. Si el script externo está en primer plano, el controlador de trampa reanudará la ejecución del subshell y volverá a contar.

Michael Homer
fuente
3

Javascript en la consola de 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)

Cuando se ingresa en la consola, inicia el contador a las 00:00 y luego habilita el control que se presiona en el documento.

No hay mucha magia, especialmente (i/60)|0el número de pisos

Hecho y probado en la consola de Chrome

gzbz
fuente
Buena respuesta. Puede eliminar algunos bytes utilizando un argumento ficticio para las funciones que no toman un argumento, y puede reemplazar el primer argumento en setInterval por una cadena que contiene el 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, bien :) Aprendí un par de cosas aquí. Cadena en intervalo y el _ => g ++. Gracias :)
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

Explicación

Haga clic en el temporizador para iniciar o pausar el cronómetro. Como tal, un solo clic es la clave de control . El separador entre los dos valores es dos puntos.

Cada vez que el usuario hace clic en el clic, bse verifica el valor de . Se inicializa según lo 0que evalúa false, por lo que se evalúa una cadena de código cada 1000 milisegundos. Esto establece la variable en la identificación del intervalo, por lo que se puede detener más tarde. Si bcontiene un número, se evalúa como true, por lo que se detiene el intervalo. Esto devuelve el valor undefined, por lo que el ciclo continúa.

La cadena de código cambia el html del elemento con id a(el cronómetro). Primero, los minutos se analizan tomando el valor del cronómetro anterior, dividiéndolo por los dos puntos y obteniendo el valor de los minutos, que aumenta en 0 si el valor de los segundos no es 59 (mayor que 58), y 1 en caso contrario, módulo 60 Entonces este valor se rellena. Luego viene el colon y, por último, los segundos. El código simplemente obtiene el valor anterior, lo aumenta en 1, toma el módulo 60 y, opcionalmente, lo rellena.

Luke
fuente
Esto no parece funcionar en absoluto. Acabo de obtener ReferenceError: d no está definido
Alexis Tyler
Probablemente también pueda guardar algunos bytes eliminando href = # ya que no es realmente necesario ya que está usando onclick.
Alexis Tyler
Acabo de arreglar eso. También quité el href, porque tenías razón. ¡Gracias!
Lucas
¿No puedes poner el onclick en la etiqueta b y especificarlo en la respuesta?
Supongo que eso funciona. Se salvó 9B. ¡Muchas gracias!
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;}

Versión sin golf:

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: presione Enterpara pausar y reanudar el cronómetro.

Explicación:

  • Espere la Enterpulsación de tecla, breakel primer whilebucle y espere hasta que Enterllegue el siguiente .
  • En la siguiente Enterpulsación de tecla, gotoprimer whilebucle y reanuda el conteo.

Ahora, sé que gotoes una mala práctica de codificación en C, pero no pude encontrar otra forma.

Abel Tom
fuente
El código no se compila. Además, getchar()bloquea hasta que se presiona algún carácter.
G. Sliepen
compila y corre en una máquina Linux
Abel Tom
La versión sin golf, quizás, pero la versión con golf no. Ya m=0,s=0;falla, porque no declaraste estas variables en ningún lado.
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)

La 'clave de control' es un clic en el documento. Para probar esto, pegue el código en la consola o en un archivo html dentro de la <script>etiqueta.

Explicación:

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

Probado en cromo

El Copyright
fuente
1
Bienvenido al sitio! ¿Sería posible editar en un enlace a un sitio de prueba en línea, como Pruébelo en línea! , para que otros usuarios puedan verificar su respuesta?
caird coinheringaahing
Gracias @cairdcoinheringaahing, esto es con jsfiddle: jsfiddle.net/xjw7o0ps
TheCopyright
2

PHP, 94 91 bytes

Supongo que 32 es el código clave para la barra espaciadora (que probablemente no lo sea);
Actualmente no tengo forma de probar ncurses. Pero el resto del código funciona bien.

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

comienza en 00:00, pero aumenta inmediatamente cuando finaliza la pausa

Si usted (como yo) no tiene ncurses, puede probar reemplazando el segundo dateparámetro con $t+=$r^=!rand(sleep(1),19);o $t+=$r^=++$x%20<1+sleep(1);. ( sleepsiempre regresa 0)

Descompostura

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

    }
}

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

Usando la stecla para iniciar / detener. Todo el programa funciona recordando el TimeDelta usandoDateTime.Now

La mayoría de C # -Magic aquí proviene de la función C # 7.0 using static.

CSharpie
fuente
2

Bash, 65 bytes

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

Tenga en cuenta que debe escribirse en un script de archivo para que funcione correctamente, o bien, intente:

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

Versión extendida para explicarlo:

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

El %(...)Tformato para imprimirf es válido en bash 5+.

Isaac
fuente
No funciona Simplemente imprime 00:00e incrementa un contador cuando golpeas Ctrl-C. No hay animación del temporizador. (Probado en bash 5.0.7)
roblogic
1
¿Escribiste el código en un script? O de lo contrario por favor trate: bash -c 'trap d=\$[!d] 2;for((;;)){ printf "\r%(%M:%S)T" $[n+=d];sleep 1;}'. @roblogic
Isaac
Ahh, eso funcionó! El script tiene que ejecutarse con bash -c:)
roblogic
1

C (gcc) , 121115 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);}

Pruébalo en línea!

Establece un controlador de señal para SIGINT, que se activa presionando control-C. Mantenemos un desfase de tiempo by mostramos el tiempo del reloj de pared menos el desfase de tiempo. Si estamos en pausa, incremente la base de tiempo cada vez que el reloj de pared marque para congelar el tiempo que se muestra.

¡Gracias a @ceilingcat por reducir 6 bytes!

G. Sliepen
fuente
0

Fecha Zsh + Gnu, 242 bytes

Con 1/100 de segundo! Requiere un terminal interactivo, pero de todos modos aquí hay un enlace TIO .
Presione Enterpara iniciar / detener el temporizador; Ctrl-Csalir.

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

Comentarios (un poco desactualizados):

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
fuente
@ Isaac, no hay forma de que pueda superar tu respuesta por brevedad y elegancia, así que pensé en agregar características en su lugar ...
roblogic
1
Ese es un excelente objetivo @roblogic :-) .... .... todavía entiendo su código ...
Isaac
0

Commodore BASIC (C64 / TheC64 Mini, VIC-20, PET, C16 / + 4) - 147 bytes tokenizados y 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}en el listado se muestra SHIFT+CLR/HOMEcomo un carácter PETSCII cuando se sigue una comilla de apertura, mientras que {home}es la CLR/HOMEclave sin desplazamiento con la misma condición de seguir una comilla de apertura.

Use la barra espaciadora como tecla de control.

Para trabajar con el Commodore 128 en BASIC 7, cambie la lista en las siguientes líneas:

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

Agrega siete tokens adicionales al conteo (ya que todos los números se almacenan en BASIC como 7 bytes, por lo que goto10son 8 bytes tokenizados mientras gotoque solo es 1).

Shaun Bebbers
fuente