Reto
Su tarea es escribir un programa que, una vez por segundo (incluso inmediatamente cuando se inicia su programa), imprime el tiempo transcurrido desde el momento en que se inició su programa.
Reglas
- El tiempo debe imprimirse en
hh:mm:ss
formato. (ceros a la izquierda para valores de un solo dígito) - Las marcas de tiempo deben estar separadas por CR, LF o CRLF. (sin espacios en blanco iniciales)
- Un nuevo tiempo debe aparecer cada segundo. (stdout no se puede almacenar por un segundo)
- El comportamiento del programa si se ejecuta más allá de las 23:59:59 no está definido.
- Puede usar
sleep(1)
incluso si se puede omitir un segundo específico cada vez que la sobrecarga para imprimir, calcular, repetir, etc. se acumula a un segundo.
Salida de ejemplo:
00:00:00
00:00:01
00:00:02
00:00:04
00:00:05
⋮
Tenga en cuenta que 00:00:03
falta aquí debido a la sobrecarga de procesamiento. Los valores omitidos reales (si los hay) dependen, por supuesto, de la implementación o del sistema.
Implementación de referencia en C: (solo sistemas compatibles con POSIX)
#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);
}
}
Criterios ganadores
Este es el código de golf , ¡el código más corto en bytes gana!
Respuestas:
MATL ,
1716 bytes¡Pruébalo en MATL Online!
Cómo funciona
fuente
Lenguaje de script Operation Flashpoint ,
174171 bytesEn acción:
158 bytes, si la hora anterior se sobrescribe la próxima vez:
Técnicamente, no se utiliza el retorno de carro, por lo que no estoy seguro de si esta versión se limita a las reglas.
fuente
CR
no sobrescribirá la línea. De hecho,CRLF
,LFCR
yLF
son todos semánticamente equivalentes.Bash + coreutils,
2826 bytesEl carácter no imprimible entre
+
y%
es un byte ESC .Esto establece la hora del sistema en 00:00:00 y, por lo tanto, requiere privilegios de root. También supone que la zona horaria es UTC y que ningún otro proceso interferirá con el reloj del sistema.
Cada nueva sincronización restablece el terminal, sobrescribiendo así el anterior.
Bash + coreutils,
3829 bytesSe aplican las mismas restricciones que antes. Cada nueva sincronización se muestra en una nueva línea.
fuente
date
del resto con un pequeño salto de línea. Pero podría ser demasiado bueno para alguien capaz de encontrar algo como su segunda solución> :-(date -s0
imprime la nueva hora en STDOUT; Estoy usando la tubería para silenciar esa salida.APL (Dyalog Unicode) , 51 bytes
Programa completo del cuerpo.
Pruébalo en línea! (Presione Ctrl + Enter para comenzar, y nuevamente para detener).
⎕AI
A UENTA I nformación (ID de usuario, tiempo de cálculo, el tiempo de conexión, tiempo de Keying)s←
asignar as
(por tiempo de tarta s )⎕AI-s
restars
de⎕AI
3⊃
seleccione el tercer elemento (tiempo de conexión en milisegundos),0 60 60 1E3⊤
convierta a esta mezcla mixta,3↑
tome los primeros 3 (suelte los milisegundos)100+
cien agregados a cada (para rellenar ceros)':'@1∘⍕¨
enmendar con dos puntos en el primer carácter de la representación de cadena de cada∊
ϵ nlist (flatten)1↓
suelta los primeros dos puntos (e implícitamente imprime en stdout)⎕DL 1
D e l ay un segundo→2
ir a la línea número dosfuente
R ,
5944 bytesF
en R por defectoFALSE
, pero es una variable regular y se puede redefinir. Cuando se usa en aritmética,FALSE
se obliga a0
. Pidiendo por loF+1
tanto vuelve1
. AsignamosF
a serF+1
, formatearlo bien, imprimir y esperar un segundo. Continúa indefinidamente.No funciona en TIO (debido a la falta del
hms
paquete), pero aquí hay una salida de muestra de mi máquina:fuente
bash + sleep + date,
también 504947464541 bytesPara tomar un tiempo de vuelta, presione rápidamente ^ C, ejecute esto y luego vuelva a ejecutar lo anterior:
Reiniciar:
La sintaxis $ [s ++] parece seguir funcionando, pero ya no está documentada (AFAICS) en la
bash
página del manual. Y todavía es un byte más corto que usar el ciclo for ((...)), una vez que eliminé las comillas a su alrededor.fuente
$[]
es una forma de obsoleto / indocumentado pero aún compatible$(())
. No estoy seguro de si se usa comúnmente en las respuestas de código de golf, pero la regla general es que su código solo debe funcionar en al menos una versión del intérprete para su idioma. OMI está bien.s=0
no es obligatorio, ya que la sustitución aritmética tratará una variable no establecida como 0 .-u
tampoco es necesario si solo asume la zona horaria predeterminada (UTC).Rápido , 144 bytes
Explicación
fuente
JavaScript (ES6), 99 bytes
fuente
Matlab (R2016b), 50 bytes
Explicación:
Versión alternativa (50 bytes también: P):
fuente
:)
t
? Además, la entradadatestr
es en días, por lo que tendría que dividir por86400
, lo que aumentaría el recuento de bytes en dos ...Julia 0.6 ,
7568 bytesPruébalo en línea!
Con sleep (1) permitido, los bucles for anidados simples son más cortos que el uso de los métodos de gestión de tiempo integrados de Julias.
Solución anterior sin dormir (1) usando DateTime
t
es la cantidad de tiempo transcurrido desde el 'día 0' hasta que se inicia el programa.now()-t
es un momento en el tiempo , que luego se formatea conDates.format()
.t0=now(); ...; now()-t0
produciría una diferencia horaria , que no se puede usar conDates.format()
.El tiempo en sí mismo es trivial con el incorporado
Timer
.fuente
Python 2 , 85 bytes
Créditos
fuente
"%02d:%02d:%02d"
con(":%02d"*3)[1:]
%24
, el comportamiento es indefinido después23:59:59
.JavaScript (ES6), 88 bytes
Esencialmente el mismo enfoque que la respuesta de @ darrylyeo , pero funciona para todas las zonas horarias y utiliza una forma ligeramente diferente para llegar a 0.
[Editar] La respuesta de Darryl ha sido corregida. Sin embargo, esto es aún más corto.
fuente
> <> , 82 + 7 = 89 bytes
Pruébalo en línea!
+7 bytes por usar la bandera
-t.0125
para hacer que cada instrucción tome 1/80 de segundo. Cada bucle tiene 80 instrucciones, lo que hace que cada bucle dure un segundo. Debido al tiempo de cálculo, esto en realidad es más largo en la práctica.De hecho, tuve que amortiguar esto hasta 100 hasta que vi la respuesta de @Not A Tree, que tenía 7 bytes mejor que la mía para generar las horas y minutos, recortándola por debajo de 80. También inspiraron el uso de los
\/
cuales se ejecutan dos veces por bucleCómo funciona
Prima:
Una versión de una línea del mismo tamaño, 80 + 9 bytes:
Esto usa la
-a
bandera para agregar marcas para las instrucciones omitidas.fuente
PHP 4+,
7064 bytesPHP 5.3+,
6963 bytesfuente
Python 3 , 112 bytes
Suponiendo que usar retrasos de 1 segundo está bien, incluso si (rara vez) puede omitir un segundo.
fuente
VBA, 90
ejecutar en ventana inmediata: punto de falla esperado en algún lugar alrededor de 23 millones de años (la resolución de punto flotante falla ~ 8.5e9 días)
fuente
Jalea , 23 bytes
Pruébalo en línea!
fuente
AWK ,
1108786 bytesNo funciona en TIO.
fuente
00:00:00
en el momento en que se inicia.APL (Dyalog) , 37 bytes
Pruébalo en línea!
Programa completo
Bastante similar a la respuesta de Adám, sin embargo, escrita independientemente y utiliza un
⎕AI
enfoque no basado.fuente
Bash + coreutils + fecha GNU, 50 bytes
Inspirada por @Dennis, esta solución no requiere tiempo para ser cambiada. Almacena almacena el desplazamiento inicial desde ahora hasta la época UNIX (1 de enero de 1970 00:00:00 UTC), en 'o', y luego muestra [-ud opciones] (la hora actual - desplazamiento), en la fecha UTC, pero solo [+% X opción] HH: MM: SS. Esto debería funcionar en países donde la zona horaria actual no es UTC.
fuente
Limpio ,
173172168 bytesEste solo funciona bajo los paquetes de Windows Clean.
Agregue 3 bytes si desea que funcione en Linux, como Clean está
CLK_PER_TICK :== 1000000
en * nix. Si desea que sea multiplataforma, agregue 8 bytes en su lugar, ya que debe usarlos enCLK_PER_TICK
lugar del valor establecido. (El enlace TIO es más grande debido a lo anterior )Pruébalo en línea!
fuente
Python 2 , 69 + 3 (
TZ=
) = 72 bytesEsto se ejecuta en un bucle continuo, sin dormir, actualizando el tiempo en la misma línea en lugar de imprimir una nueva línea cada segundo. (Todavía permitido por las reglas, espero).
Esta versión un poco más larga (72 + 3 = 75 bytes) se imprime en una nueva línea cada segundo en su lugar:
Ambos requieren que estés en la zona horaria UTC. En Linux puede lograr esto configurando la
TZ
variable de entorno. Por ejTZ= python
.fuente
> <> ,
106 bytes82 + 9 = 91 bytes¡Gracias a Jo King por sugerir la
-a
bandera! Mira su respuesta también.Pruébalo en línea! (pero tendrá que esperar el tiempo de espera de 60 segundos).
Tengo que usar una función de> <> que nunca antes había necesitado: este código requiere la bandera
-t.0125
, que establece la velocidad de ejecución en 0.0125 segundos por tic u 80 ticks por segundo. También está la-a
bandera, que hace que los espacios en blanco cuenten como una marca (en algunos casos, el intérprete es un poco extraño al respecto).Básicamente, el código mantiene un contador que se incrementa cada vez que el pez pasa por el bucle, y el resto del bucle convierte el contador al
hh:mm:ss
formato y lo imprime. El bucle toma exactamente 80 ticks.Esto debería funcionar en teoría, pero en la práctica, cada tic es ligeramente más largo que 0.0125 segundos, debido al tiempo de cálculo. Cambiar el
\\
en la segunda línea para<<
obtener tiempos más precisos en TIO.También puede ver el código en acción en el área de juegos para peces , excepto que este intérprete trata los espacios en blanco de manera ligeramente diferente del intérprete oficial. Alternativamente, puede eliminar las banderas en TIO para hacer que el código se ejecute a la máxima velocidad, para verificar el comportamiento por momentos después de un minuto.
fuente
\!
y eliminando dos de los extras<
. Otro par de bytes si usa la-a
bandera, que cuenta los espacios en blanco y las instrucciones omitidas como ticks-a
bandera me dejó jugar un poco más al golf, ¡gracias! Creo que también puedes usar el\!
truco en tu código: ¡ Pruébalo en línea!Java 8, programa completo, 150 bytes
Pruébelo aquí (agota el tiempo de espera después de 60 segundos, así que configuré la suspensión en 1 para ver más resultados).
Explicación:
Java 8, función, 94 bytes
Pruébelo aquí (agota el tiempo de espera después de 60 segundos, así que configuré la suspensión en 1 para ver más resultados).
Explicación:
Aquí hay un pequeño gif para ver que funciona según lo previsto cuando se usan 1000 ms:
fuente
PHP,
5948 bytesInspirado por la respuesta de Darren H .
Versión antigua :
fuente
-3600
completo, lo que ahorraría 5 bytes.Shell , 177 bytes
Tenga en cuenta que esto no es totalmente compatible con POSIX porque utiliza
date +%s
, que es unadate
expansión común .fuente
Ruby,
192117bytes (crédito a Dada)¿Como funciona?
Para usar la versión expandida (la conversión a una hora se da como una función separada y usa un formato de salida diferente):
fuente
printf
lugar deputs
puede ahorrar unos pocos bytes más: ¡ Pruébelo en línea! . ¡Feliz golf en PPCG!NARS APL,
109 6357 caracteres3 + 3 + 48 + 3 = 57 (visto las otras soluciones Apl también)
convierta el INT ⍵ en la cadena de dígitos de una manera si la longitud de esa cadena es 1 que agregue un '0' delante de ella
combinar matriz en ⍵ con la matriz '::'
fuente
Código de máquina x86-64 (llamada al sistema Linux): 78 bytes
RDTSC spin-loop timing,
sys_write
llamada al sistema Linux .x86-64 no proporciona una manera conveniente de consultar la frecuencia del "reloj de referencia" RDTSC en tiempo de ejecución. Puede leer un MSR (y hacer un cálculo basado en eso) , pero eso requiere el modo kernel, o la raíz + apertura
/dev/cpu/%d/msr
, por lo que decidí hacer que la frecuencia sea constante en el tiempo de construcción. (AjusteFREQ_RDTSC
según sea necesario: cualquier constante de 32 bits no cambiará el tamaño del código de máquina)Tenga en cuenta que las CPU x86 durante varios años han tenido una frecuencia RDTSC fija, por lo que se puede usar como fuente de tiempo, no como contador de rendimiento del ciclo de reloj principal, a menos que tome medidas para deshabilitar los cambios de frecuencia. (Hay contadores de rendimiento reales para contar los ciclos reales de la CPU). Por lo general, funciona a la frecuencia nominal de la pegatina, por ejemplo, 4.0 GHz para mi i7-6700k, independientemente del turbo o el ahorro de energía. De todos modos, este tiempo de espera ocupado no depende del promedio de carga (como lo haría un ciclo de retardo calibrado), y tampoco es sensible al ahorro de energía de la CPU.
Este código funcionará para cualquier x86 con una frecuencia de referencia inferior a 2 ^ 32 Hz, es decir, hasta ~ 4.29 GHz. Más allá de eso, el bajo 32 de la marca de tiempo se ajustaría completamente en 1 segundo, por lo que también tendría que mirar los
edx
32 bits altos del resultado.Resumen :
Empuja
00:00:00\n
la pila. Luego en un bucle:sys_write
llamada al sistemacmp
/cmov
, con el resultado CF proporcionando la transferencia para el siguiente dígito.rdtsc
y guardar la hora de inicio.rdtsc
hasta que el delta sea> = tics por segundo de la frecuencia RDTSC.Listado NASM:
Elimine el comentario de las
pause
instrucciones para ahorrar energía significativa: esto calienta un núcleo en ~ 15 grados C sinpause
, pero solo en ~ 9 conpause
. (En Skylake, dondepause
duerme ~ 100 ciclos en lugar de ~ 5. Creo que ahorraría más sirdtsc
no fuera lento, por lo que la CPU no está haciendo mucho tiempo).Una versión de 32 bits sería unos pocos bytes más corta, por ejemplo, usar una versión de 32 bits de esta para empujar la cadena inicial 00: 00: 00 \ n.
Y también usando 1 byte
dec edx
. Laint 0x80
llamada al sistema ABI no usaría esi / edi, por lo que la configuración del registro para syscall vs. lodsb / stosb podría ser más simple.fuente
nanosleep
llamada al sistema, pero esto fue más interesante. Con root en Linux, es posible leer el MSR correcto y obtener mediante programación la frecuencia RDTSC.q / kdb + , 40 bytes
Solución:
Ejemplo:
Explicación:
Aquí se ejecutan tres comandos:
.z.ts:{-1($)18h$a+:1}; / override timer function
a:-1; / initialise variable a to -1
(.)"\\t 1000" / start the timer with 1000ms precision
Desglose de la función del temporizador:
Prima:
Alternativa 1 para 41 bytes :
Alternativa 2 para 26 + 7 bytes = 33 bytes
y agregando
-t 1000
como argumentos al binario q.fuente