Terapkan Stopwatch Sederhana

25

Tantangan

Tugas Anda adalah menulis sebuah program yang, sekali sedetik (termasuk segera ketika program Anda dimulai), mencetak waktu yang telah berlalu sejak program Anda dimulai.

Aturan

  • Waktu harus dicetak dalam hh:mm:ssformat. (memimpin nol untuk nilai satu digit)
  • Prangko waktu harus dipisahkan oleh CR, LF, atau CRLF. (tidak ada spasi putih terkemuka)
  • Waktu baru harus muncul setiap detik. (stdout tidak dapat disangga selama sedetik)
  • Perilaku program jika dijalankan melewati 23:59:59 tidak ditentukan.
  • Anda dapat menggunakan sleep(1)bahkan jika detik tertentu dapat dilewati setiap kali overhead untuk mencetak, menghitung, mengulang, dll terakumulasi menjadi satu detik.

Contoh output:

00:00:00
00:00:01
00:00:02
00:00:04
00:00:05
⋮

Perhatikan bahwa 00:00:03tidak ada di sini karena memproses overhead. Nilai-nilai yang dilewati sebenarnya (jika ada) tentu saja tergantung pada implementasi dan / atau sistem.

Implementasi referensi dalam C: (hanya sistem yang kompatibel dengan 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);
    }
}

Kriteria menang

Ini adalah , kode terpendek dalam byte menang!

MarkWeston
sumber
Catatan untuk tantangan selanjutnya, klarifikasi dalam komentar adalah hal yang buruk untuk dilakukan. referensi
user202729

Jawaban:

9

MATL , 17 16 byte

`Z`12L/13XOD1Y.T

Cobalah di MATL Online!

Bagaimana itu bekerja

`         % Do...while loop
  Z`      %   Push seconds elapsed since start of program
  12L     %   Push 86400 (predefined literal)
  /       %   Divide. This transforms seconds into days
  13XO    %   Convert to date string with format 13, which is 'HH:MM:SS'
  D       %   Display
  1Y.     %   Pause for 1 second
  T       %   True. Used as loop condition for infinite loop
          % End loop (implicit)
Luis Mendo
sumber
4
Bagaimana Anda menjawab 37 menit setelah ditutup? o_O menyalahkan caching
Mr. Xcoder
9
@ Mr.Xcoder Saya baru-baru ini belajar menggunakan the Force
Luis Mendo
29

Operasi bahasa scripting Flashpoint ,  174  171 byte

s=""
#l
t=_time
t=t-t%1
a=t%60
c=(t-a)/60
b=c%60
c=(c-b)/60
d=""
e=d
f=d
?a<10:d=0
?b<10:e=0
?c<10:f=0
s=s+format["%1%2:%3%4:%5%6\n",f,c,e,b,d,a]
hint s
@t+1<_time
goto"l"

Beraksi:

158 byte, jika waktu sebelumnya ditimpa oleh waktu berikutnya:

#l
t=_time
t=t-t%1
a=t%60
c=(t-a)/60
b=c%60
c=(c-b)/60
d=""
e=d
f=d
?a<10:d=0
?b<10:e=0
?c<10:f=0
hint format["%1%2:%3%4:%5%6",f,c,e,b,d,a]
@t+1<_time
goto"l"

Secara teknis, tidak ada carriage return yang digunakan, jadi saya tidak yakin apakah versi ini terbatas pada aturan.

Steadybox
sumber
5
Saya tidak mengharapkan operasi flashpoint.
Polyducks
10
@Polyducks tidak ada yang mengharapkan operasi flashpoint
Pureferret
Karena di Unix, CR akan menimpa baris, saya pikir jawaban kedua divalidasi oleh 'baik CR, LF, atau CRLF diperbolehkan'
Stan Strum
1
@StanStrum Setidaknya di Ubuntu saya CRtidak akan menimpa baris. Bahkan, CRLF, LFCRdan LFsemua semantik setara.
13

Bash + coreutils, 28 26 byte

date -s0|yes date +c%T|sh

Karakter yang tidak dapat dicetak antara +dan %merupakan byte ESC .

Ini mengatur waktu sistem menjadi 00:00:00 dan karenanya membutuhkan hak akses root. Itu juga mengasumsikan bahwa zona waktu adalah UTC dan bahwa tidak ada proses lain akan mengganggu jam sistem.

Setiap timing baru me-reset terminal, sehingga menimpa yang sebelumnya.


Bash + coreutils, 38 29 byte

date -s0|yes date +%T|sh|uniq

Batasan yang sama seperti sebelumnya berlaku. Setiap timing baru ditampilkan pada baris baru.

Dennis
sumber
Karena tidak mengubah bytecount saya akan memisahkan yang pertama datedari yang lain dengan linefeed kecil yang bagus. Tapi itu mungkin terlalu baik untuk seseorang yang dapat menemukan solusi seperti solusi kedua Anda> :-(
Aaron
date -s0mencetak waktu baru untuk STDOUT; Saya menggunakan pipa untuk membungkam output itu.
Dennis
Oh benar, terima kasih atas penjelasannya!
Aaron
5

APL (Dyalog Unicode) , 51 byte

Badan program penuh.

s←⎕AI
1↓∊':'@1∘⍕¨100+30 60 60 1E33⊃⎕AI-s
DL 1
2

Cobalah online! (Tekan Ctrl + Enter untuk memulai, dan lagi untuk berhenti.)

⎕AISebuah ccount Aku NFORMASI (user ID, menghitung waktu, waktu koneksi, keying waktu)

s← menetapkan ke s(untuk s tart waktu)
⎕AI-s kurangi sdari⎕AI

3⊃ pilih elemen ketiga (hubungkan waktu dalam milidetik)
0 60 60 1E3⊤konversikan ke campuran-radix ini
3↑ ambil 3 pertama (tetes milidetik)
100+ seratus ditambahkan ke masing-masing (untuk pad nol)
':'@1∘⍕¨ ubah dengan tanda titik dua pada karakter pertama dari representasi string masing-masing
ϵ daftar (ratakan)
1↓ jatuhkan usus besar pertama (dan secara implisit cetak ke stdout)

⎕DL 1D e l ay satu detik

→2 pergi ke baris nomor dua

Adám
sumber
5

R , 59 44 byte

Fdalam R default FALSE, tetapi ini adalah variabel biasa dan dapat didefinisikan ulang. Ketika digunakan dalam aritmatika, FALSEdipaksa untuk 0. F+1Karena itu meminta kembali 1. Kami menetapkan Funtuk menjadi F+1, memformatnya dengan baik, mencetak, dan menunggu satu detik. Berlanjut tanpa batas.

repeat{print(hms::hms(F<-F+1))
Sys.sleep(1)}

Tidak berfungsi pada TIO (karena kurangnya hmspaket), tapi inilah contoh keluaran dari mesin saya:

00:00:00
00:00:01
00:00:02
00:00:03
00:00:04
00:00:05
00:00:06
00:00:07
00:00:08
00:00:09
00:00:10
00:00:11
00:00:12
00:00:13
rturnbull
sumber
5

bash + sleep + date, juga 50 49 47 46 45 41 byte

while date -ud@$[s++] +%T;do sleep 1;done

Untuk mengambil waktu putaran, tekan ^ C dengan cepat, jalankan ini lalu jalankan kembali di atas:

laps=("${laps[@]}" $s) ; echo ${laps[-1]}

Untuk mengatur ulang:

s=0; unset laps

Sintaks $ [s ++] tampaknya masih berfungsi, tetapi tidak lagi (AFAICS) didokumentasikan di bashhalaman manual. Dan itu masih satu byte lebih pendek daripada menggunakan for (()) loop, setelah saya menghapus tanda kutip di sekitarnya.

Will Crawford
sumber
AFAICT, $[]adalah bentuk yang sudah usang / tidak terdokumentasi tetapi masih didukung$(()) . Saya tidak yakin apakah itu biasa digunakan dalam jawaban kode-golf, tetapi aturan umumnya adalah bahwa kode Anda hanya harus bekerja pada setidaknya satu versi juru bahasa untuk bahasa Anda. IMO baik-baik saja.
Peter Cordes
s=0tidak diperlukan, karena substitusi aritmatika akan memperlakukan variabel yang tidak disetel sebagai 0 . -ujuga tidak diperlukan jika Anda hanya mengasumsikan zona waktu default (UTC).
Dennis
-u diperlukan di mesin saya :)
Will Crawford
4

Cepat , 144 byte

import Foundation
let s=Date()
while 1>0{let d=Int(-s.timeIntervalSinceNow)
print(String(format:"%02d:%02d:%02d",d/3600,d/60%60,d%60))
sleep(1)}

Penjelasan

import Foundation                       // Import `Date` and `sleep()`
let s = Date()                          // Get the time at the start of the program
while 1 > 0 {                           // While 1 > 0 (forever):
  let d = Int(-s.timeIntervalSinceNow)  //   Calculate time difference
  print(String(format:"%02d:%02d:%02d", //   Print the time
      d/3600,d/60%60,d%60))
  sleep(1)                              //   Sleep one second
}
Herman L.
sumber
4

JavaScript (ES6), 99 byte

f=_=>console.log(new Date(new Date-d).toUTCString().slice(17,25))
f(d=Date.now(setInterval(f,1e3)))

Darrylyeo
sumber
2
Jam tidak mulai dari 0 untuk saya. Perubahan offset tergantung pada zona waktu jam sistem. (Menang 10)
LukeS
@ Lukas Whoops, diperbaiki!
darrylyeo
4

Matlab (R2016b), 50 byte

t=now;while 1,disp(datestr(now-t,13)),pause(1),end

Penjelasan:

t=now; % Stores the current time
while 1 % Loops forever
    disp(datestr(now-t,13)) % Computes the difference since the program started
    % And prints with format 13 ('HH:MM:SS') - this may change between versions
    pause(1) % Waits one second
end

Versi alternatif (50 byte juga: P):

now;while 1,disp(datestr(now-ans,13)),pause(1),end
Thiago Oleinik
sumber
Selamat datang di situs ini! :)
DJMcMayhem
Terima kasih sobat:)
Thiago Oleinik
@LuisMendo Terima kasih atas sarannya, tapi saya tidak mengerti ... Dalam contoh Anda, apa variabelnya t? Juga, inputnya datestradalah dalam hitungan hari, jadi saya harus membaginya dengan 86400, yang akan meningkatkan jumlah byte menjadi dua ...
Thiago Oleinik
3

Julia 0,6 , 75 68 byte

for h=0:23,m=0:59,s=0:59;@printf "%02i:%02i:%02i
" h m s;sleep(1)end

Cobalah online!

Dengan tidur (1) diizinkan, simpangan for-loop sederhana lebih pendek daripada menggunakan metode penanganan waktu bawaan Julias.

Solusi lama tanpa tidur (1) menggunakan DateTime

t=now()-DateTime(0);Timer(x->println(Dates.format(now()-t,"HH:MM:SS")),0,1)

tadalah jumlah waktu yang berlalu dari 'hari 0' hingga saat program dimulai. now()-tadalah momen dalam waktu , yang kemudian diformat menggunakan Dates.format().

t0=now(); ...; now()-t0akan menghasilkan perbedaan waktu , yang tidak dapat digunakan dengan Dates.format().

Waktunya sendiri sepele dengan built-in Timer.

LukeS
sumber
3

Python 2 , 85 byte

import time
t=0
while 1:print(":%02d"*3)[1:]%(t/3600,t/60%60,t%60);time.sleep(1);t+=1

Kredit

Neil
sumber
Anda dapat menyimpan satu byte dengan mengganti "%02d:%02d:%02d"dengan(":%02d"*3)[1:]
wnnmaw
1
Anda tidak perlu %24, perilaku tidak ditentukan setelah 23:59:59.
Erik the Outgolfer
@EriktheOutgolfer Poin bagus, diperbarui.
Neil
3

JavaScript (ES6), 88 byte

f=_=>console.log(new Date(i++*1e3).toUTCString().slice(17,25))
f(i=0,setInterval(f,1e3))

Pada dasarnya pendekatan yang sama dengan jawaban @ darrylyeo , tetapi bekerja untuk semua zona waktu dan menggunakan cara yang sedikit berbeda untuk sampai ke 0.

[Sunting] Jawaban Darryl telah diperbaiki. Ini masih lebih pendek.

Birjolaxew
sumber
3

> <> , 82 + 7 = 89 byte

0\!
:/+1oan~?=3ln?$0(a:o":"n~?=4ln?$0(a:ro":"n~?=5ln?$0(a:,*a6-}:%*a6:,*a6-}:%*a6:

Cobalah online!

+7 byte untuk menggunakan flag -t.0125untuk membuat setiap instruksi membutuhkan 1/80 detik. Setiap loop memiliki 80 instruksi, membuat setiap loop panjangnya satu detik. Karena waktu perhitungan, ini sebenarnya lebih lama dalam praktek.

Aku benar-benar harus penyangga ini semua jalan sampai ke 100 sampai aku melihat @Not A Tree jawaban yang memiliki cara 7 byte yang lebih baik dari saya untuk menghasilkan jam dan menit, pemangkasan di bawah 80. Mereka juga terinspirasi penggunaan \/yang dilaksanakan dua kali per loop.

Bagaimana itu bekerja

0\...
./...
Initialises the stack with a 0 to represent the time

0\!
:/....................................................,*a6-}:%*a6:,*a6-}:%*a6:
Puts the hours, minutes and seconds in the stack

0\!
:/....n~?=3ln?$0(a:o":"n~?=4ln?$0(a:ro":"n~?=5ln?$0(a:...
Print out the hours, minutes, seconds separated by colons. 
If the number is below 0, print a leading 0. 
If the number is not, then there is an extra 0 on the stack, which is popped.

0\!
./+1oa...
Print a newline and increment the counter
And restart the loop

Bonus:

Versi satu baris dengan ukuran yang sama, 80 + 9 byte:

0::6a*%:}-6a*,:6a*%:}-6a*,:a(0$?nl5=?~n":"or:a(0$?nl4=?~n":"o:a(0$?nl3=?~nao1+>!

Ini menggunakan -abendera untuk menambahkan kutu untuk instruksi yang dilewati.

Jo King
sumber
3

PHP 4+, 70 64 byte

$x=time();while(1){sleep(1);echo date('H:i:s',time()-$x)."\n";}

PHP 5.3+, 69 63 byte

$x=time();a:sleep(1);echo date('H:i:s',time()-$x)."\n";goto a;
Darren H
sumber
Tag terbuka PHP dapat dihilangkan dalam jawaban yang menghemat 6 byte.
Daniel W.
2

Python 3 , 112 byte

Dengan asumsi menggunakan penundaan 1 detik tidak apa-apa, bahkan jika (jarang) mungkin melompati satu detik.

from time import*;a=0
while 1:d=divmod;m,s=d(a,60);print(":".join(f"{k:02d}"for k in(*d(m,60),s)));a+=1;sleep(1)
Hannes Karppila
sumber
2

VBA, 90

t=0:while(1):?format(t,"hh:mm:ss"):t=t+timeserial(0,0,1):q=timer:while q-timer<1:wend:wend

berjalan di jendela langsung: titik kegagalan yang diharapkan di suatu tempat sekitar 23 juta tahun (resolusi titik mengambang gagal ~ 8,5e9 hari)

SeanC
sumber
2

Jelly , 23 byte

:⁽½c,60;%60d⁵j”:ṄœS1ṛ‘ß

Cobalah online!

Erik the Outgolfer
sumber
Apakah itu bekerja dengan waktu di atas 1 menit?
H.PWiz
@ H.PWiz Seharusnya, menjalankan beberapa tes. EDIT: Sepertinya dividen salah untuk jam ... tetap untuk menghemat sedikit!
Erik the Outgolfer
2

AWK , 110 87 86 byte

BEGIN{for(;;i++){printf("%02d:%02d:%02d\n",i/3600%60,i/60%60,i%60);system("sleep 1")}}

Tidak berfungsi di TIO.

Noskcaj
sumber
Program Anda tampaknya tidak mencetak 00:00:00pada saat itu dimulai.
user202729
Memperbaikinya. Terima kasih
Noskcaj
2

APL (Dyalog) , 37 byte

{∇⍵+×⎕DL 1⊣⎕←1↓∊':'@1∘⍕¨100+⍵⊤⍨360}0

Cobalah online!

Program lengkap.

Cukup mirip dengan jawaban Adam, namun ditulis secara independen dan menggunakan pendekatan non- ⎕AIberbasis.

Erik the Outgolfer
sumber
2

Bash + coreutils + tanggal GNU, 50 byte

o=`date +"%s"`;yes date +%X -ud\"-$o sec\"|sh|uniq

Terinspirasi oleh @ Dennis, solusi ini tidak memerlukan waktu untuk diubah. Menyimpan toko offset awal dari sekarang ke zaman UNIX (1 Jan 1970 00:00:00 UTC), di 'o', dan kemudian menampilkan [-ud opsi] (waktu saat ini - offset), pada tanggal UTC, tetapi hanya [+% X opsi] HH: MM: SS. Ini harus bekerja di negara-negara di mana zona waktu saat ini bukan UTC.

CSM
sumber
2

Bersih , 173 172 168 byte

import StdEnv,System.Time
$n i#i=(i/60^n)rem 60
=(i/10,i rem 10)
f i w#(Clock j,w)=clock w
#j=j/1000
|j>i=[j:f j w]=f i w
Start w=[($2i,':',$1i,':',$0i,'
')\\i<-f -1 w]

Yang ini hanya berfungsi di bawah bundel Windows Clean.

Tambahkan 3 byte jika Anda ingin bekerja di Linux, seperti Bersihkan CLK_PER_TICK :== 1000000di * nix Jika Anda ingin menggunakan platform silang, tambahkan 8 byte sebagai gantinya, karena Anda harus menggunakan CLK_PER_TICKalih-alih nilai yang ditetapkan. ( TIO tautan lebih besar karena di atas )

Cobalah online!

Suram
sumber
2

Python 2 , 69 + 3 ( TZ=) = 72 byte

from time import*;s=time()
while 1:print ctime(time()-s)[11:19]+'\r',

Ini berjalan dalam loop terus menerus, tanpa tidur, memperbarui waktu pada baris yang sama daripada mencetak baris baru setiap detik. (Masih diizinkan oleh aturan, saya harap.)

Versi yang sedikit lebih panjang ini (72 + 3 = 75 byte) dicetak pada baris baru setiap detik sebagai gantinya:

from time import*;s=time()
while 1:print ctime(time()-s)[11:19];sleep(1)

Kedua hal ini mengharuskan Anda berada di zona waktu UTC. Di Linux Anda dapat mencapai ini dengan mengatur TZvariabel lingkungan. Misalnya TZ= python.

mercator
sumber
2

> <> , 106 byte 82 + 9 = 91 byte

Terima kasih kepada Jo King karena menyarankan -abendera! Lihat jawaban mereka juga.

0v+1oan<n0/
:/<</?(a:,*a6-}:%*a6:,*a6-}:%*a6:\\
n<n0/<</?(a:ro":"
":"n<n0/<</?(a:o

Cobalah online! (tetapi Anda harus menunggu waktu tunggu 60 detik).

Saya harus menggunakan fitur> <> yang belum pernah saya butuhkan sebelumnya: kode ini memerlukan flag -t.0125, yang menetapkan kecepatan eksekusi menjadi 0,0125 detik per kutu, atau 80 kutu per detik. Ada juga -abenderanya, yang menjadikan spasi putih dihitung sebagai tanda centang (dalam beberapa kasus - penerjemah agak aneh tentang ini).

Pada dasarnya, kode menyimpan penghitung yang bertambah setiap kali ikan melewati loop, dan sisa dari loop mengubah penghitung untuk hh:mm:ssmemformat dan mencetaknya. Loop ini membutuhkan 80 kutu.

Ini seharusnya bekerja secara teori, tetapi dalam praktiknya, setiap centang sedikit lebih lama dari 0,0125 detik, karena waktu perhitungan. Mengubah \\baris kedua untuk <<memberikan pengaturan waktu yang lebih akurat pada TIO.

Anda juga dapat menonton kode ini dalam aksi di taman bermain ikan , kecuali bahwa juru bahasa ini memperlakukan ruang putih sedikit berbeda dari juru bahasa resmi. Atau, Anda dapat menghapus bendera di TIO untuk membuat kode berjalan dengan kecepatan tinggi, untuk memverifikasi perilaku selama satu menit setelah satu menit.

Bukan pohon
sumber
-1 byte dengan mengganti v di baris pertama dengan \!dan menghapus dua ekstra <. Beberapa byte lagi jika Anda menggunakan -aflag, yang menghitung spasi dan melompati instruksi sebagai kutu
Jo King
@JoKing, -aBendera izinkan saya golf sedikit lagi, terima kasih! Saya pikir Anda dapat menggunakan \!trik dalam kode Anda juga: Cobalah online!
Bukan pohon
2

Java 8, program lengkap, 150 byte

interface M{static void main(String[]a)throws Exception{for(int i=0;;Thread.sleep(1000))System.out.printf("%02d:%02d:%02d%n",i/3600,i/60%60,i++%60);}}

Coba di sini (waktu habis setelah 60 detik, jadi saya telah mengatur tidur ke 1 untuk melihat lebih banyak output).

Penjelasan:

interface M{                    // Program:
  static void main(String[]a)   //  Mandatory main-method
     throws Exception{          //    Mandatory throws for Thread.sleep
    for(int i=0;                //   Start at 0
        ;                       //   Loop indefinitely
         Thread.sleep(1000))    //     After every iteration: Sleep for 1 sec
      System.out.printf("%02d:%02d:%02d%n",
                                //    Print in the format "HH:mm:ss\n":
        i/3600,i/60%60,i++%60); //     The hours, minutes and seconds
                                //     (and increase `i` by 1 afterwards with `i++`)
                                //   End of loop (implicit / single-line body)
  }                             //  End of mandatory main-method
}                               // End of program

Java 8, fungsi, 94 byte

v->{for(int i=0;;Thread.sleep(1000))System.out.printf("%02d:%02d:%02d%n",i/3600,i/60%60,i++%60);}

Coba di sini (waktu habis setelah 60 detik, jadi saya telah mengatur tidur ke 1 untuk melihat lebih banyak output).

Penjelasan:

v->{   // Method with empty unused parameter and no return-type
  ...  //  Same as the program above
}      // End of method

Berikut adalah gif kecil untuk melihatnya berfungsi sebagaimana dimaksud ketika 1000 ms digunakan:

masukkan deskripsi gambar di sini

Kevin Cruijssen
sumber
2

PHP, 59 48 byte

while(1){sleep(1);echo date('H:i:s',$i++)."\n";}

Terinspirasi oleh jawaban Darren H .

Versi lama :

<?php while(1){sleep(1);echo date('H:i:s',$i++-3600)."\n";}
roberto06
sumber
Tag terbuka PHP dapat dihilangkan dalam jawaban yang menghemat 6 byte.
Daniel W.
Pemikiran yang bagus, tetapi 3600 harus 86.400 sebaliknya konter dimulai pada pukul 23:00:00 jadi sayangnya Anda mendapatkan byte, masih mengalahkan saya dengan 9 meskipun!
Darren H
@ DarrenH Saya pikir itu tergantung pada lokasi Anda, saya belum memikirkan hal itu. Saya dalam GMT + 1, itu sebabnya saya menambahkan 3600, tapi saya kira untuk orang Inggris, Anda dapat menghapus-3600 semuanya, yang akan menghemat 5 byte.
roberto06
1

Shell , 177 byte

Perhatikan bahwa ini tidak sepenuhnya sesuai POSIX karena menggunakan date +%s, yang merupakan dateekspansi umum .

a=`date +%s`;while true;do b=`date +%s`;s=`expr $b - $a`;h=`expr $s / 3600`;s=`expr $s % 3600`;m=`expr $s / 60`;s=`expr $s % 60`;printf '\r%02d:%02d:%02d' $h $m $s;sleep 1;done
MarkWeston
sumber
7
Biasanya, Anda harus memberi orang kesempatan untuk menjawab tantangan Anda sebelum menjawabnya sendiri. Saya merekomendasikan seminggu karena beberapa mungkin hanya ada di sini pada waktu-waktu tertentu selama seminggu.
Adám
1
@ Adám saya belum menerima jawaban saya, dan pada saat itu saya mengirimkan jawaban yang jauh lebih pendek (seperti milik Anda) dikirimkan.
MarkWeston
1

Ruby, 192 117 byte (Kredit ke Dada)

t=Time.now
loop do
m,s=(Time.now-t).to_i.divmod(60)
h,m=m.divmod(60)
printf"%02d:%02d:%02d
",h,m,s
sleep 1
end

Bagaimana cara kerjanya?

Akan menggunakan versi yang diperluas (Konversi ke waktu diberikan sebagai fungsi terpisah dan menggunakan format output yang berbeda):

def format_secs(s) # Converts the value in seconds to the required format
    mins, secs = s.divmod(60) # divmod returns the quotient and the remainder of a number
    hours, mins = mins.divmod(60)
    [hours,mins,secs].map { |e| e.to_s.rjust(2,'0') }.join ':'

    =begin
    [hours,mins,secs] -Creates a new array using the values allready provided for hours, minutes and seconds
    .map { - Creates a new array based on a operation on each of an array's values
    .to_s.rjust(2,'0')} - Turns the number into a string, and then adds "0" if needed to make the timer's result at least two digits
    .join ':' - Combines the result of the operation into a single string with a ":" in between the two numbers
    =end
end

t = Time.now # Saves the time at the program's (Rough) start

loop do
    puts format_secs((Time.now - t).to_i) # Returns the result of  the "format_secs" operation on the difference between the two times (in seconds) converted to a pure integer
    sleep 1 # Waits for one second
end
James007
sumber
6
Selamat datang di situs ini! Setiap jawaban untuk tantangan kode-golf harus golf . Anda setidaknya harus menghapus spasi putih yang tidak berguna, dan menggunakan nama variabel 1 karakter. Itu akan membuat Anda sekitar 120 byte, dan menggunakan printfbukannya putsdapat menyimpan beberapa byte lagi: Cobalah secara online! . Selamat bermain golf di PPCG!
Dada
1

APL NARS, 109 63 57 karakter

q;t
t←0
{∊⍵,¨':: '}{1<⍴x←⍕⍵:x⋄'0',x}¨(3⍴60)⊤⌊t+←⎕DL 1⋄→2

3 + 3 + 48 + 3 = 57 (lihat solusi Apl lainnya juga)

{1<⍴x←⍕⍵:x⋄'0',x}

konversikan INT string dalam string angka dengan cara jika panjang string itu adalah 1 daripada tambahkan satu '0' di depannya

{∊⍵,¨':: '}

menggabungkan array dalam ⍵ dengan array '::'

00:00:01 
00:00:02 
00:00:03 
00:00:04 
00:00:05 
00:00:06 
00:00:07 
00:00:08 
00:00:09 
RosLuP
sumber
1

kode mesin x86-64 (panggilan sistem Linux): 78 byte

Waktu putar-putar RDTSC , Linuxsys_write panggilan sistem .

x86-64 tidak menyediakan cara yang nyaman untuk menanyakan frekuensi "jam referensi" RDTSC pada waktu berjalan. Anda dapat membaca MSR (dan melakukan perhitungan berdasarkan itu) , tetapi itu membutuhkan mode kernel, atau pembukaan root + /dev/cpu/%d/msr, jadi saya memutuskan untuk membuat frekuensi konstan-waktu build. (MenyesuaikanFREQ_RDTSC seperlunya: konstanta 32-bit tidak akan mengubah ukuran kode mesin)

Perhatikan bahwa CPU x86 selama beberapa tahun telah memperbaiki frekuensi RDTSC sehingga dapat digunakan sebagai sumber waktu, bukan penghitung kinerja siklus clock inti kecuali jika Anda mengambil langkah untuk menonaktifkan perubahan frekuensi. (Ada penghitung perf aktual untuk menghitung siklus CPU nyata.) Biasanya itu berdetak pada frekuensi stiker nominal, misalnya 4.0GHz untuk i7-6700k saya terlepas dari turbo atau hemat daya. Bagaimanapun, waktu tunggu yang sibuk ini tidak tergantung pada rata-rata beban (seperti loop penundaan yang dikalibrasi), dan juga tidak sensitif terhadap penghematan daya CPU.

Kode ini akan berfungsi untuk x86 apa pun dengan frekuensi referensi di bawah 2 ^ 32 Hz, yaitu hingga ~ 4,29 GHz. Di luar itu, timestamp 32 rendah akan membungkus semua jalan dalam 1 detik, jadi saya harus melihat edx32 bit hasil yang tinggi juga.

Ringkasan :

dorong 00:00:00\ntumpukan. Kemudian dalam satu lingkaran:

  • sys_write panggilan sistem
  • ADC-loop atas angka (dimulai dengan yang terakhir) untuk peningkatan waktu dengan 1. Wrapping / carry-out ditangani dengan cmp/ cmov, dengan hasil CF menyediakan carry-in untuk digit berikutnya.
  • rdtsc dan menghemat waktu mulai.
  • putar rdtscsampai delta>> kutu per detik dari frekuensi RDTSC.

Daftar NASM:

 1  Address                            ; mov  %1, %2       ; use this macro to copy 64-bit registers in 2 bytes (no REX prefix)
 2           Machine code           %macro MOVE 2
 3           bytes                      push  %2
 4                                      pop   %1
 5                                  %endmacro
 6                                  
 7                                      ; frequency as a build-time constant because there's no easy way detect it without root + system calls, or kernel mode.
 8                                      FREQ_RDTSC equ 4000000000
 9                                  global _start
10                                  _start:
11 00000000 6A0A                        push     0xa                       ; newline
12 00000002 48BB30303A30303A3030        mov      rbx, "00:00:00"
13 0000000C 53                          push     rbx
14                                      ; rsp points to  `00:00:00\n`
20                                  
21                                      ; rbp = 0                (Linux process startup.  push imm8 / pop is as short as LEA for small constants)
22                                      ; low byte of rbx = '0'
23                                  .print:
24                                      ; edx potentially holds garbage (from rdtsc)
25                                  
26 0000000D 8D4501                      lea      eax, [rbp+1] ; __NR_write = 1
27 00000010 89C7                        mov      edi, eax     ; fd = 1 = stdout
28                                      MOVE     rsi, rsp
28 00000012 54                  <1>  push %2
28 00000013 5E                  <1>  pop %1
29 00000014 8D5008                      lea      edx, [rax-1 + 9]     ; len = 9 bytes.
30 00000017 0F05                        syscall               ; sys_write(1, buf, 9)
31                                  
32                                      ;; increment counter string:  least-significant digits are at high addresses (in printing order)
33 00000019 FD                          std                        ;  so loop backwards from the end, wrapping each digit manually
34 0000001A 488D7E07                    lea      rdi, [rsi+7]
35                                      MOVE     rsi, rdi
35 0000001E 57                  <1>  push %2
35 0000001F 5E                  <1>  pop %1
36                                  
37                                      ;; edx=9 from the system call
38 00000020 83C2FA                      add   edx, -9 + 3      ; edx=3 and set CF (so the low digit of seconds will be incremented by the carry-in)
39                                      ;stc
40                                  .string_increment_60:          ; do {
41 00000023 66B93902                    mov    cx, 0x0200 + '9'    ; saves 1 byte vs. ecx.
42                                      ; cl = '9' = wrap limit for manual carry of low digit.  ch = 2 = digit counter
43                                    .digitpair:
44 00000027 AC                          lodsb
45 00000028 1400                        adc      al, 0           ; carry-in = cmp from previous iteration; other instructions preserve CF
46 0000002A 38C1                        cmp      cl, al          ; manual carry-out + wrapping at '9' or '5'
47 0000002C 0F42C3                      cmovc    eax, ebx        ; bl = '0'.  1B shorter than JNC over a MOV al, '0'
48 0000002F AA                          stosb
49                                  
50 00000030 8D49FC                      lea     ecx, [rcx-4]    ; '9' -> '5' for the tens digit, so we wrap at 59
51 00000033 FECD                        dec     ch
52 00000035 75F0                        jnz    .digitpair
53                                      ; hours wrap from 59 to 00, so the max count is 59:59:59
54                                  
55 00000037 AC                          lodsb                        ; skip the ":" separator
56 00000038 AA                          stosb                        ; and increment rdi by storing the byte back again.  scasb would clobber CF
57                                  
58 00000039 FFCA                        dec     edx
59 0000003B 75E6                        jnz   .string_increment_60
60                                  
61                                      ; busy-wait for 1 second.  Note that time spent printing isn't counted, so error accumulates with a bias in one direction
62 0000003D 0F31                        rdtsc                         ; looking only at the 32-bit low halves works as long as RDTSC freq < 2^32 = ~4.29GHz
63 0000003F 89C1                        mov      ecx, eax             ; ecx = start
64                                  .spinwait:
65                                  ;    pause
66 00000041 0F31                        rdtsc                      ; edx:eax = reference cycles since boot
67 00000043 29C8                        sub      eax, ecx          ; delta = now - start.  This may wrap, but now we have the delta ready for a normal compare
68 00000045 3D00286BEE                  cmp      eax, FREQ_RDTSC   ; } while(delta < counts_per_second)
69                                   ;   cmp      eax, 40  ; fast count to test printing
70 0000004A 72F5                        jb     .spinwait
71                                  
72 0000004C EBBF                        jmp .print
  next address = 0x4E = size = 78 bytes.

Batalkan komentar pada pauseinstruksi untuk menghemat daya yang signifikan: ini memanaskan satu inti hingga ~ 15 derajat C tanpa pause, tetapi hanya pada ~ 9 dengan pause. (Di Skylake, di mana pausetidur untuk ~ 100 siklus, bukan ~ 5. Saya pikir itu akan menghemat lebih banyak jika rdtsctidak juga lambat-ish sehingga CPU tidak melakukan banyak waktu).


Versi 32-bit akan lebih pendek beberapa byte, misalnya menggunakan versi 32-bit ini untuk mendorong string awal 00: 00: 00 \ n.

16                          ;    mov      ebx, "00:0"
17                          ;    push     rbx
18                          ;    bswap    ebx
19                          ;    mov      dword [rsp+4], ebx    ; in 32-bit mode, mov-imm / push / bswap / push would be 9 bytes vs. 11

Dan juga menggunakan 1 byte dec edx. The int 0x80system call ABI tidak akan menggunakan esi / edi, sehingga register setup untuk syscall vs lodsb / stosb mungkin lebih sederhana.

Peter Cordes
sumber
Saya bisa menggunakan nanosleepsystem call, tapi ini lebih menarik. Dengan root di Linux, dimungkinkan untuk membaca MSR yang tepat dan secara terprogram mendapatkan frekuensi RDTSC.
Peter Cordes
1

q / kdb + , 40 byte

Larutan:

.z.ts:{-1($)18h$a+:1};a:-1;(.)"\\t 1000"

Contoh:

q).z.ts:{-1($)18h$a+:1};a:-1;(.)"\\t 1000"
q)00:00:00
00:00:01
00:00:02
00:00:03
00:00:04
00:00:05

Penjelasan:

Ada tiga perintah yang dieksekusi di sini:

  1. .z.ts:{-1($)18h$a+:1}; / override timer function
  2. a:-1; / initialise variable a to -1
  3. (.)"\\t 1000" / start the timer with 1000ms precision

Rincian fungsi pengatur waktu:

.z.ts:{-1 string 18h$a+:1} / ungolfed timer function
      {                  } / lambda function
                     a+:1  / add 1 to variable a
                 18h$      / cast to seconds
          string           / cast to string
       -1                  / write to stdout
.z.ts:                     / assign this function to .z.ts

Bonus:

Alternatif 1 untuk 41 byte :

a:.z.t;.z.ts:{-1($)18h$x-a};(.)"\\t 1000"

Alternatif 2 untuk 26 + 7 byte = 33 byte

.z.ts:{-1($)18h$a+:1};a:-1

dan menambahkan -t 1000sebagai argumen ke q biner.

streetster
sumber