Desafio
Sua tarefa é escrever um programa que, uma vez por segundo (inclusive imediatamente quando o programa for iniciado), imprima o tempo decorrido a partir do momento em que o programa foi iniciado.
Regras
- A hora deve ser impressa no
hh:mm:ss
formato. (zeros à esquerda para valores de um dígito) - Os carimbos de hora devem ser separados por CR, LF ou CRLF. (sem espaço em branco à esquerda)
- Um novo horário deve aparecer a cada segundo. (stdout não pode ser armazenado em buffer por um segundo)
- O comportamento do programa se for executado depois das 23:59:59 é indefinido.
- Você pode usar
sleep(1)
mesmo que um segundo específico possa ser pulado sempre que a sobrecarga de impressão, cálculo, loop, etc. se acumular em um segundo.
Exemplo de saída:
00:00:00
00:00:01
00:00:02
00:00:04
00:00:05
⋮
Observe que 00:00:03
está faltando aqui devido à sobrecarga de processamento. Os valores ignorados reais (se houver) dependem da implementação e / ou sistema.
Implementação de referência em C: (apenas sistemas compatíveis com 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);
}
}
Critérios de vitória
Este é o código-golfe , o código mais curto em bytes ganha!
Respostas:
MATL ,
1716 bytesExperimente no MATL Online!
Como funciona
fonte
Linguagem de script da operação Flashpoint ,
174171 bytesEm ação:
158 bytes, se o horário anterior for substituído pela próxima vez:
Tecnicamente, nenhum retorno de carro é usado; portanto, não tenho certeza se esta versão se restringe às regras.
fonte
CR
não sobrescreverá a linha. Na verdade,CRLF
,LFCR
eLF
são todos semanticamente equivalente.Bash + coreutils,
2826 bytesO caractere não imprimível entre
+
e%
é um byte ESC .Isso define a hora do sistema para 00:00:00 e, portanto, requer privilégios de root. Ele também pressupõe que o fuso horário é UTC e que nenhum outro processo irá interferir no relógio do sistema.
Cada novo tempo reinicia o terminal, substituindo, assim, o anterior.
Bash + coreutils,
3829 bytesAs mesmas restrições de antes se aplicam. Cada novo tempo é mostrado em uma nova linha.
fonte
date
do resto com um pequeno e agradável avanço de linha. Mas pode ser muito agradável para alguém capaz de chegar a algo como sua segunda solução> :-(date -s0
imprime o novo horário em STDOUT; Estou usando o cano para silenciar essa saída.APL (Dyalog Unicode) , 51 bytes
Corpo do programa completo.
Experimente online! (Pressione Ctrl + Enter para iniciar e novamente para parar.)
⎕AI
A ccount I nformação (ID de usuário, tempo de computação, tempo de conexão, tempo de chaveamento)s←
atribuir as
(para s tart tempo)⎕AI-s
subtrairs
do⎕AI
3⊃
escolha o terceiro elemento (tempo de conexão em milissegundos)0 60 60 1E3⊤
converta para esta mistura mista,3↑
pegue os 3 primeiros (descarta os milissegundos)100+
cem adicionados a cada (para zeros),':'@1∘⍕¨
altere com dois pontos no primeiro caractere da representação de seqüência de caracteres de∊
ϵ nlist (achatar)1↓
soltar o primeiro dois pontos (e imprimir implicitamente em stdout)⎕DL 1
D e L ay um segundo→2
vá para a linha número doisfonte
R ,
5944 bytesF
em R o padrão éFALSE
, mas é uma variável regular e pode ser redefinida. Quando usado em aritmética,FALSE
é coagido a0
. Solicitando,F+1
portanto, retornos1
. AtribuímosF
para serF+1
, formate-o bem, imprima e aguarde um segundo. Continua indefinidamente.Não funciona no TIO (devido à falta do
hms
pacote), mas aqui está um exemplo de saída da minha máquina:fonte
festança + suspensão + data,
também 504947464541 bytesPara tirar uma volta, pressione ^ C, execute-o e execute novamente o procedimento acima:
Reiniciar:
A sintaxe $ [s ++] parece ainda funcionar, mas não está mais (AFAICS) documentada na
bash
página do manual. E ainda é um byte mais curto do que usar o loop for ((...)), depois que removi as aspas.fonte
$[]
é uma forma obsoleta / não documentada, mas ainda é suportada$(())
. Não tenho certeza se é comumente usado em respostas de código-golfe, mas a regra geral é que seu código precisa funcionar em pelo menos uma versão do intérprete para o seu idioma. OMI está bem.s=0
não é necessário, pois a substituição aritmética tratará uma variável não definida como 0 .-u
também não é necessário se você apenas assumir o fuso horário padrão (UTC).Rápido , 144 bytes
Explicação
fonte
JavaScript (ES6), 99 bytes
fonte
Matlab (R2016b), 50 bytes
Explicação:
Versão alternativa (50 bytes também: P):
fonte
:)
t
? Além disso, a entrada paradatestr
é em dias, então eu teria que dividir por86400
, o que aumentaria o número de bytes por dois ...Julia 0.6 ,
7568 bytesExperimente online!
Com sleep (1) permitido, for-loops aninhados simples são mais curtos do que os métodos de manipulação de tempo internos do Julias.
Solução antiga sem suspensão (1) usando DateTime
t
é a quantidade de tempo que passou do 'dia 0' para o início do programa.now()-t
é um momento no tempo , que é formatado usandoDates.format()
.t0=now(); ...; now()-t0
produziria uma diferença de tempo que não pode ser usada comDates.format()
.O tempo em si é trivial com o build-in
Timer
.fonte
Python 2 , 85 bytes
Créditos
fonte
"%02d:%02d:%02d"
por(":%02d"*3)[1:]
%24
, o comportamento é indefinido depois23:59:59
.JavaScript (ES6), 88 bytes
Essencialmente, a mesma abordagem da resposta de @ darrylyeo , mas funciona para todos os fusos horários e usa uma maneira ligeiramente diferente de chegar a 0.
A resposta de Darryl foi corrigida. Isso ainda é mais curto, no entanto.
fonte
> <> , 82 + 7 = 89 bytes
Experimente online!
+7 bytes para usar o sinalizador
-t.0125
para fazer com que cada instrução tome 1/80 de segundo. Cada loop tem 80 instruções, tornando cada loop um segundo. Por causa do tempo de computação, isso é realmente mais longo na prática.Na verdade, eu tive que armazenar isso em buffer até 100, até que vi a resposta do @Not A Tree que tinha 7 bytes de maneira melhor do que a minha para gerar horas e minutos, aparando abaixo de 80. Eles também inspiraram o uso dos
\/
quais são executados duas vezes por loop.Como funciona
Bônus:
Uma versão de uma linha do mesmo tamanho, 80 + 9 bytes:
Isso usa o
-a
sinalizador para adicionar ticks para instruções ignoradas.fonte
PHP 4+,
7064 bytesPHP 5.3+,
6963 bytesfonte
Python 3 , 112 bytes
Supondo que o atraso de 1 segundo seja aceitável, mesmo que (raramente) possa pular um segundo.
fonte
VBA, 90
executado na janela imediata: ponto de falha esperado em torno de 23 milhões de anos (a resolução de ponto flutuante falha ~ 8,5e9 dias)
fonte
Gelatina , 23 bytes
Experimente online!
fonte
AWK ,
1108786 bytesNão funciona no TIO.
fonte
00:00:00
no momento em que foi iniciado.APL (Dyalog) , 37 bytes
Experimente online!
Programa completo.
Bem parecido com a resposta de Adám, porém escrito de forma independente e usando uma
⎕AI
abordagem não baseada.fonte
Bash + coreutils + data GNU, 50 bytes
Inspirada em @Dennis, esta solução não exige que o tempo seja alterado. Ele armazena o deslocamento inicial de agora para a época UNIX (1 de janeiro de 1970 00:00:00 UTC), em 'o' e exibe [-ud options] (o horário atual - deslocamento), na data UTC, mas somente [opção +% X] HH: MM: SS. Isso deve funcionar em países onde o fuso horário atual não é UTC.
fonte
Limpo ,
173172168 bytesEste funciona apenas nos pacotes do Windows Clean.
Adicione 3 bytes se quiser que ele funcione no Linux, como o Clean
CLK_PER_TICK :== 1000000
no * nix. Se você deseja que ela seja multiplataforma, adicione 8 bytes, em vez disso, conforme for necessário, emCLK_PER_TICK
vez do valor definido. (O link do TIO é maior devido ao acima )Experimente online!
fonte
Python 2 , 69 + 3 (
TZ=
) = 72 bytesIsso é executado em um loop contínuo, sem suspensão, atualizando o horário na mesma linha, em vez de imprimir uma nova linha a cada segundo. (Ainda permitido pelas regras, espero.)
Esta versão um pouco mais longa (72 + 3 = 75 bytes) imprime em uma nova linha a cada segundo:
Ambos exigem que você esteja no fuso horário UTC. No Linux, você pode conseguir isso configurando a
TZ
variável de ambiente. Por exemploTZ= python
.fonte
> <> ,
106 bytes82 + 9 = 91 bytesObrigado a Jo King por sugerir a
-a
bandeira! Confira a resposta deles também.Experimente online! (mas você terá que aguardar o tempo limite de 60 segundos).
Eu usei um recurso de> <> que eu nunca precisei antes: esse código requer o sinalizador
-t.0125
, que define a velocidade de execução para 0,0125 segundos por tick, ou 80 ticks por segundo. Há também a-a
bandeira, que faz com que o espaço em branco conte como uma marca (em alguns casos - o intérprete é um pouco estranho nisso).Basicamente, o código mantém um contador que é incrementado toda vez que o peixe passa pelo loop, e o resto do loop converte o contador em
hh:mm:ss
formato e imprime. O loop leva exatamente 80 ticks.Isso deve funcionar na teoria, mas na prática, cada tick é um pouco maior que 0,0125 segundos, devido ao tempo de computação. Alterar a
\\
na segunda linha para<<
fornece tempos mais precisos no TIO.Você também pode assistir o código em ação no playground de peixes , exceto que esse intérprete trata os espaços em branco de maneira um pouco diferente do intérprete oficial. Como alternativa, você pode remover os sinalizadores no TIO para fazer com que o código seja executado na velocidade máxima, para verificar o comportamento por momentos após um minuto.
fonte
\!
e removendo dois dos extras<
. Outro par de bytes se você usar a-a
bandeira, que conta espaços em branco e ignorados instruções como carrapatos-a
bandeira deixa-me jogar um pouco mais, obrigado! Acho que você também pode usar o\!
truque no seu código: Experimente online!Java 8, programa completo, 150 bytes
Experimente aqui (o tempo limite é excedido após 60 segundos, então configurei o sono como 1 para ver mais resultados).
Explicação:
Java 8, função, 94 bytes
Experimente aqui (o tempo limite é excedido após 60 segundos, então configurei o sono como 1 para ver mais resultados).
Explicação:
Aqui está um pequeno gif para vê-lo funcionar conforme o esperado quando 1000 ms são usados:
fonte
PHP,
5948 bytesInspirado pela resposta de Darren H .
Versão antiga :
fonte
-3600
total, o que economiza 5 bytes.Concha , 177 bytes
Observe que isso não é totalmente compatível com POSIX porque ele usa
date +%s
, o que é umadate
expansão comum .fonte
Ruby,
192117 bytes (Crédito ao Dada)Como funciona?
Vai usar a versão expandida (a conversão para um horário é fornecida como uma função separada e usa um formato de saída diferente):
fonte
printf
vez deputs
pode economizar mais alguns bytes: Experimente online! . Feliz golfe no PPCG!APL NARS,
109 6357 caracteres3 + 3 + 48 + 3 = 57 (veja as outras soluções Apl também)
converta o INT ⍵ na sequência de dígitos de uma maneira, se o comprimento dessa sequência for 1, em seguida, adicione um '0' na frente dela
combinar array em ⍵ com o array '::'
fonte
código da máquina x86-64 (chamada do sistema Linux): 78 bytes
Tempo de rotação do loop RDTSC ,
sys_write
chamada do sistema Linux .O x86-64 não fornece uma maneira conveniente de consultar a frequência do "relógio de referência" RDTSC em tempo de execução. Você pode ler um MSR (e fazer um cálculo com base nisso) , mas isso requer o modo do kernel, ou abertura de raiz +
/dev/cpu/%d/msr
, então decidi tornar a frequência um tempo de compilação constante. (AjusteFREQ_RDTSC
conforme necessário: qualquer constante de 32 bits não altera o tamanho do código da máquina)Observe que as CPUs x86 há vários anos têm frequência RDTSC fixa, por isso é utilizável como fonte de tempo, não como contador de desempenho do ciclo do clock principal, a menos que você tome medidas para desativar as alterações de frequência. (Existem contadores de desempenho reais para contar os ciclos reais da CPU.) Geralmente, ele funciona na frequência nominal dos adesivos, por exemplo, 4,0 GHz para o meu i7-6700k, independentemente de turbo ou economia de energia. De qualquer forma, esse tempo de espera ocupada não depende da média da carga (como seria um loop de atraso calibrado) e também não é sensível à economia de energia da CPU.
Este código funcionará para qualquer x86 com uma frequência de referência abaixo de 2 ^ 32 Hz, ou seja, até ~ 4,29 GHz. Além disso, os 32 baixos do carimbo de data e hora seriam agrupados em 1 segundo, então eu teria que olhar também para os
edx
32 bits altos do resultado.Sumário :
empurre
00:00:00\n
a pilha. Então, em um loop:sys_write
chamada do sistemacmp
/cmov
, com o resultado de CF fornecendo o transporte para o próximo dígito.rdtsc
e salve a hora de início.rdtsc
até que o delta seja> = marca por segundo da frequência RDTSC.Listagem NASM:
Remova o comentário da
pause
instrução para economizar energia significativa: isso aquece um núcleo em ~ 15 graus C sempause
, mas apenas em ~ 9 compause
. (No Skylake, ondepause
dorme por ~ 100 ciclos em vez de ~ 5. Eu acho que economizaria mais serdtsc
também não fosse lento, para que a CPU não fique muito tempo).Uma versão de 32 bits seria alguns bytes mais curta, por exemplo, usando uma versão de 32 bits para enviar a string 00: 00: 00 \ n inicial.
E também usando 1 byte
dec edx
. Aint 0x80
chamada de sistema ABI não usaria esi / edi, portanto, a configuração do registro para o syscall vs. lodsb / stosb pode ser mais simples.fonte
nanosleep
chamada do sistema, mas isso foi mais interessante. Com o root no Linux, é possível ler o MSR correto e obter programaticamente a frequência RDTSC.q / kdb + , 40 bytes
Solução:
Exemplo:
Explicação:
Existem três comandos sendo executados aqui:
.z.ts:{-1($)18h$a+:1}; / override timer function
a:-1; / initialise variable a to -1
(.)"\\t 1000" / start the timer with 1000ms precision
Repartição da função do temporizador:
Bônus:
Alternativa 1 para 41 bytes :
Alternativa 2 para 26 + 7 bytes = 33 bytes
e adicionando
-t 1000
como argumentos ao binário q.fonte