Terapkan Stopwatch

23

Terapkan Stopwatch digital sederhana , yang akan menampilkan waktu berlalu dalam detik dan menit, seperti yang dijelaskan di bawah ini.

Penting

Silakan baca bagian Tampilan dan Kontrol !

Tampilan

Waktu berlalu, harus ditampilkan dalam MM:SSformat, dengan mengganti string waktu yang sebelumnya ditampilkan "di tempat" (membersihkan seluruh atau sebagian layar juga diperbolehkan).

Stopwatch harus diperbarui setidaknya setiap detik.

Contoh:

0 menit, 0 detik

00:00

0 menit, 33 detik

00:33

1 menit, 50 detik

01:50

Awalnya, Anda bisa mulai dengan '00: 00 'atau dengan nilai lain apa pun dalam rentang [00: 00-59: 59].

Setelah Stopwatch Anda mencapai 59:59, itu harus mengatur ulang ke 00:00dan melanjutkan lagi.

Anda dapat menggunakan basis yang berbeda (bukan desimal) atau bahkan sistem angka yang berbeda jika Anda inginkan, selama Anda mengikuti pola umum.

Misalnya 13:03bisa ditampilkan sebagai:

Desimal

13:03

Heksadesimal

0D:03

Base64

N:D

Basis quater-imajiner

10101:3

Angka Romawi

XIII:III

Berhati-hatilah bahwa jika Anda menggunakan sistem / pangkalan angka non-desimal, itu harus dikodekan menggunakan karakter ASCII (atau Unicode) yang dapat dicetak, misalnya menggunakan dua byte biner (tidak dapat dicetak) selama beberapa menit dan detik tidak diperbolehkan.

Anda juga harus meninggalkan-pad output Anda dengan nol yang sesuai, jika sistem numerik Anda memungkinkan untuk itu.

Mengganti karakter pemisah :dengan karakter lain yang dapat dicetak (termasuk digit) juga dapat diterima.

Kontrol

Stopwatch harus mulai dijeda , dan tetap dalam kondisi ini, sampai pengguna secara eksplisit memulainya , dengan menekan tombol 'control' (lihat di bawah).

Jika, ketika stopwatch menghitung, pengguna menekan kembali tombol 'control' , stopwatch harus berhenti (menjaga waktu saat ini), sampai tombol 'control' ditekan sekali lagi.

The 'kontrol' kunci dapat keystroke tunggal, misalnya s, atau kombinasi dari kunci, misalnya Ctrl+Shift+X, tetapi harus 'atom', menekan beberapa tombol secara berurutan, misalnya skemudian Enter, yang tidak diperbolehkan .

Kunci 'kontrol' yang sama (atau kombinasi) harus digunakan untuk menjeda dan melanjutkan stopwatch.

Anda harus menggunakan kunci 'kontrol' tertentu , yaitu 'kunci apa saja' tidak diperbolehkan.

Atau, Anda dapat menggunakan klik mouse tunggal atau ganda, alih-alih menekan tombol untuk 'kontrol'.


Aturan

  • Ini adalah , jawaban terpendek dalam byte menang;
  • Lubang kode-golf standar berlaku;
  • Program Anda harus (secara teoritis) mampu berjalan selamanya.
zeppelin
sumber
Bisakah kunci 'kontrol' dimasukkan?
Loovjo
@Loovjo Ya, tombol apa saja atau kombinasi tombol apa pun akan dilakukan, termasuk Enter (selama itu dapat dijeda dan kemudian dilanjutkan menggunakan tombol yang sama).
zeppelin
terkait
Jonathan Allan
1
Apakah kita perlu rincian kedua? Yaitu jika pengguna berhenti sekitar 7000 milidetik setelah 00:05dicetak, dan kemudian di beberapa titik dilanjutkan lagi, haruskah 00:06muncul 3000 milidetik setelah tombol resume ditekan, atau boleh-boleh saja mencetaknya satu detik penuh setelah tombol resume ditekan?
smls
@ smls Tidak apa-apa untuk menunggu satu detik penuh, setelah resume.
zeppelin

Jawaban:

8

SmileBASIC, 86 77 71 byte

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

DIALOGmenampilkan kotak teks di layar sentuh. Nadalah jumlah detik kotak teks akan tetap di layar sebelum menghilang. Jika Nadalah 0, tetap sampai pengguna menekan tombol pada layar sentuh.

DIALOGKembali 1jika pengguna menekan tombol, dan 0jika ditutup secara otomatis. Jadi ketika pengguna menekan tombol pause, ia kembali 1, dan waktu tampilan diatur ke 0, menghentikan stopwatch. Setelah pengguna menekan tombol lagi, kami mengatur waktu tampilan kembali ke 1, melanjutkan timer. Pada dasarnya, setiap kali DIALOGkembali 1, waktu tampilan dialihkan antara 1dan 0menggunakan !=, yang eqivilant ke XOR logis selama kedua input adalah 1 atau 0.

12Me21
sumber
Ini terlihat luar biasa! Jika Anda juga bisa memberikan "screencast" animasi tentang cara kerjanya, itu akan sangat dihargai!
zeppelin
Oke, saya akan segera melakukannya
12Me21
Itu juga bisa diuji pada emulator ini: citra-emu.org/game/smilebasic
roblogic
9

Python 2, 167 129 byte

-36 byte * karena menggunakan ide Maltysen untuk menangkap ctrl-cmenggunakan pengecualian - berikan kredit!
-4 byte berkat DLosc (init ndan b0 bukan f())
-1 byte berkat FlipTack (gunakan p^=1bukan p=1-p)
-2 byte terima kasih kepada Felipe Nardi Batista (hapus penentu presisi)

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

Bekerja sama seperti aslinya, di bawah ini, tetapi dengan urutan tombol kontrol ctrl+c.
(Diuji oleh saya dengan Python 2.7.8 di Windows 7, 64bit;
Diuji oleh Brian Minton dengan Python 2.7.13 di linux, 64bit)

* Juga menciutkan ifpernyataan ke pencarian daftar untuk mendapatkan trysebagai satu-liner.

Asli saya:

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

(Diuji oleh saya dengan Python 2.7.8 pada Windows 7, 64bit - kode ini, bagaimanapun, adalah Windows spesifik karena penggunaan msvcrtperpustakaan)

Kunci kontrol adalah 'p'.

ndan bdiinisialisasi dengan nilai yang sama pada saat start-up, memberikan "offset" 0; pdiinisialisasi ke 0, menunjukkan keadaan dijeda.

Setiap kali tombol kontrol ditekan, nilai pakan diaktifkan. Ketika beralih dari keadaan dijeda ke keadaan aktif bdiperbarui ke nilai baru menjaga setiap arus offset dari keadaan aktif sebelumnya dengan b-n.

Selama keadaan aktif nberulang kali diperbarui ke waktu saat ini dengan menelepon time.time().

Perbedaan antara ndan b,, tadalah jumlah total detik (termasuk bagian fraksional) yang berlalu selama keadaan aktif.

Menit yang berlalu kemudian t/60dan masing-masing menit dan detik ditampilkan dengan mod 60 dengan (t/60%60,t%60). Angka nol terdepan untuk masing-masing menggunakan pemformatan string dari bagian integer '...%0.2d...'. Mencetak tuple (trailing ,) di mana item pertama memiliki carriage return (yang \r) menyebabkan teks yang dicetak sebelumnya ditimpa.

Jonathan Allan
sumber
Ah ya, tangkapan yang bagus, saya awalnya memang telah ^=beralih di beberapa titik selama formulasi.
Jonathan Allan
@Dosc memang, terima kasih ...
Jonathan Allan
Ini bukan khusus Windows. Saya baru saja menguji ini di linux 64 bit dengan Python 2.7.13 dan berhasil. (dengan tombol kontrol Ctrl-C)
Brian Minton
@BrianMinton terima kasih telah memberi tahu saya!
Jonathan Allan
apa yang dibutuhkan untuk .masuk %0.2d? itu berfungsi dengan baik sebagai%02d
Felipe Nardi Batista
6

Python - 160 159 143 byte

Terima kasih kepada @JonathanAllan karena telah menyelamatkan saya 18 byte!

Hanya menggunakan pustaka builtin, jadi kunci kontrolnya adalah ctrl-c, menangkapnya dengan 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
sumber
Oh bagus. Saya pikir mungkin itu bisa lebih pendek hanya dengan except:? Saya memiliki versi kerja saya yang melakukannya ...
Jonathan Allan
@ Jonathan Allan oh keren, tidak tahu Anda bisa melakukan itu.
Maltysen
5

bash + Utilitas Unix, 90 atau 93 byte

Versi 90-byte:

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

Versi 93-byte:

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

Ctrl-C adalah karakter resume / pause. Spasi adalah pembatas antara menit dan detik.

Perbedaan antara kedua versi adalah bahwa program 90-byte akan bekerja selama 2 ^ 63 detik (pada saat itu, bash akan memberi saya integer overflow).

Versi 93-byte akan benar-benar berfungsi selamanya.

Masalah aslinya termasuk persyaratan: "Program Anda harus (secara teoritis) mampu berjalan selamanya."

Jika berjalan selama 2 ^ 63 detik sudah cukup untuk memenuhi persyaratan itu, maka solusi 90-byte berfungsi. Durasi itu lebih dari 20 kali usia alam semesta!

Jika program harus dapat berjalan lebih lama dari itu, saya harus menggunakan solusi 93-byte.


Saya mungkin harus menunjukkan bahwa solusi ini, serta setidaknya beberapa yang lain diposting, akan sangat lambat jatuh di belakang waktu yang telah berlalu. Selip ini karena program tidur selama satu detik antara setiap eksekusi tubuh loop, tetapi tubuh loop memang membutuhkan waktu yang sangat sedikit untuk dieksekusi. Ini akan menjadi tidak penting dalam praktik.

Mitchell Spector
sumber
Sepertinya ini tidak akan menampilkan nilai awal di layar, sampai Anda "berhenti sebentar".
zeppelin
"Stopwatch harus mulai dijeda, dan tetap dalam kondisi ini, sampai pengguna secara eksplisit memulainya, dengan menekan tombol 'kontrol' (lihat di bawah)." Apakah ada spek yang saya lewatkan?
Mitchell Spector
ya ini benar, tetapi masih harus menampilkan nilai awal Initially, you can start with '00:00' or with any other value in range [00:00-59:59], yang akan tetap di layar sampai Anda menekan 'kontrol' untuk pertama kalinya. Maaf jika saya belum dapat merumuskan ini dengan cukup jelas!
zeppelin
OK, itu masuk akal - saya akan memodifikasinya.
Mitchell Spector
1
Terlihat bagus sekarang!
zeppelin
5

QBasic, 213 211 byte

Kunci kontrol adalah tab. Membiarkan ini berjalan dapat menyebabkan laptop terbakar. Anda telah diperingatkan.

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

Ini sedang beraksi, berhenti di 10, 15, dan 20 detik:

Stopwatch berjalan

Tidak diikat dan dikomentari

' 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

Perhatikan bahwa nilai-nilai TIMERadalah floating-point. Ini tidak mempengaruhi output, karena MODdan \memotong ke bilangan bulat. Tapi itu menambah akurasi jumlah waktu yang dihemat: jika Anda menjeda penghitung waktu tepat sebelum tanda centang, Anda akan melihat ketika Anda memulai lagi bahwa jumlahnya berubah dalam waktu kurang dari satu detik.

DLosc
sumber
4

Batch, 132 byte

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

Menekan nakan (un) menghentikan penghitung waktu. Kedipan output dapat dikurangi dengan biaya tiga (atau empat) byte.

Neil
sumber
4

Bash murni, 141 byte

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

Ini tidak menggunakan apa pun kecuali Bash bawaan (tidak ada alat eksternal). Karakter kontrolnya Ctrl-Z, sehingga SIGTSTPpenanganan standar menjeda stopwatch.

Jika Ctrl-Zditekan saat subshell foregrounded, itu akan menghentikan sementara eksekusi dan mengembalikan skrip luar ke foreground, di mana ia akan menunggu diam-diam. Jika skrip luar diletakan di depan, penangan perangkap akan melanjutkan eksekusi subkulit, dan itu akan dihitung kembali.

Michael Homer
sumber
3

Javascript di konsol Chrome, 143 byte

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)

Saat dimasukkan dalam konsol, penghitung masuk ke 00:00 dan kemudian memungkinkan kontrol yang menekan tombol pada dokumen.

Tidak banyak keajaiban terjadi, terutama (i/60)|0lantai nomornya

Dilakukan dan diuji di konsol Chrome

gzbz
sumber
Jawaban bagus. Anda bisa menghapus beberapa byte dengan menggunakan argumen dummy untuk fungsi yang tidak mengambil argumen, dan Anda bisa mengganti argumen pertama di setInterval dengan string yang berisi kode.
Luke
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)
Luke
Ohh, bagus :) Mempelajari beberapa hal di sini. String dalam interval dan _ => g ++. Terima kasih :)
gzbz
3

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

<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

Penjelasan

Klik timer untuk memulai atau menghentikan stopwatch. Dengan demikian, satu klik adalah kunci kontrol . Pemisah antara dua nilai adalah titik dua.

Setiap kali pengguna mengklik klik, nilai bdicentang. Ini diinisialisasi 0yang dievaluasi false, sehingga serangkaian kode dievaluasi setiap 1000 milidetik. Ini mengatur variabel ke id interval, sehingga bisa dihentikan nanti. Jika bberisi angka, itu dievaluasi true, sehingga interval dihentikan. Ini mengembalikan nilai undefined, sehingga siklus berlanjut.

String kode mengubah html elemen dengan id a(stopwatch). Pertama menit diurai dengan mengambil nilai stopwatch sebelumnya, membaginya dengan titik dua, dan mendapatkan nilai menit, yang meningkat sebesar 0 jika nilai detik tidak 59 (lebih besar dari 58), dan 1 jika tidak, modulo 60 Kemudian nilai ini diisi. Lalu datanglah tanda titik dua, dan terakhir, detik. Kode hanya mendapatkan nilai lama, meningkatkannya dengan 1, mengambil modulo 60 dan secara opsional menambahkannya.

Luke
sumber
Ini sepertinya tidak berhasil sama sekali. Saya baru saja mendapatkan ReferenceError: d tidak didefinisikan
Alexis Tyler
Anda mungkin juga dapat menyimpan beberapa byte dengan menghapus href = # karena sebenarnya tidak diperlukan karena Anda menggunakan onclick.
Alexis Tyler
Saya baru saja memperbaikinya. Saya juga menghapus href, karena Anda benar. Terima kasih!
Luke
Tidak bisakah Anda meletakkan onclick pada tag b dan menentukannya dalam jawabannya?
Saya kira itu berhasil. Ini menghemat 9B. Terima kasih banyak!
Luke
3

C 309 179 byte

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 tidak disatukan:

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

Penggunaan: Tekan Enteruntuk Menjeda dan Melanjutkan Stopwatch.

Penjelasan:

  • Tunggu Enterkeystroke, loop breakpertama whiledan tunggu hingga berikutnya Enter.
  • Setelah Enterpenekanan tombol berikutnya , putaran gotopertama whiledan lanjutkan penghitungan.

Sekarang, saya tahu gotoadalah praktik pengkodean yang buruk di C, tapi saya tidak bisa mencari cara lain.

Abel Tom
sumber
Kode tidak dikompilasi. Selanjutnya, getchar()blok sampai beberapa karakter ditekan.
G. Sliepen
kompilasi dan berjalan pada mesin linux
Abel Tom
Versi ungolfed mungkin, tetapi versi golf tidak. Sudah m=0,s=0;gagal, karena Anda tidak mendeklarasikan variabel-variabel ini di mana pun.
G. Sliepen
3

Javascript, 124 byte

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)

'Kunci kontrol' adalah klik pada dokumen. Untuk menguji ini, rekatkan kode di konsol atau dalam file html di dalam <script>tag.

Penjelasan:

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

Diuji di Chrome

Hak Cipta
sumber
1
Selamat datang di situs ini! Apakah mungkin untuk mengedit tautan ke situs pengujian online, seperti Coba online! , sehingga pengguna lain dapat memverifikasi jawaban Anda?
caird coinheringaahing
Terima kasih @cairdcoinheringaahing, ini dengan jsfiddle: jsfiddle.net/xjw7o0ps
TheCopyright
2

PHP, 94 91 byte

Saya berasumsi bahwa 32 adalah kode kunci untuk spasi (yang mungkin bukan);
Saat ini saya tidak memiliki cara untuk menguji ncurses. Tetapi sisa kode berfungsi dengan baik.

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

dimulai pada 00:00, tetapi bertambah segera ketika jeda berakhir

Jika Anda (seperti saya) tidak memiliki ncurses, Anda dapat menguji dengan mengganti dateparameter kedua dengan $t+=$r^=!rand(sleep(1),19);atau $t+=$r^=++$x%20<1+sleep(1);. ( sleepselalu kembali 0.)

kerusakan

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

    }
}

Golf

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

Menggunakan stombol untuk memulai / berhenti. Seluruh program bekerja dengan mengingat penggunaan TimeDeltaDateTime.Now

Kebanyakan C # -Magic di sini berasal dari fitur C # 7.0 using static.

CSharpie
sumber
2

Bash, 65 byte

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

Perhatikan bahwa itu harus ditulis ke skrip file agar berfungsi dengan benar, atau, coba:

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

Versi lanjutan untuk menjelaskannya:

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

The %(...)Tformat yang printf berlaku di bash 5 +.

Ishak
sumber
Tidak bekerja Hanya mencetak 00:00dan menambah penghitung saat Anda menekan Ctrl-C. Tidak ada animasi dari timer. (Diuji pada bash 5.0.7)
roblogic
1
Apakah Anda menulis kode ke skrip? Atau coba: bash -c 'trap d=\$[!d] 2;for((;;)){ printf "\r%(%M:%S)T" $[n+=d];sleep 1;}'. @roblogic
Isaac
Ahh, itu berhasil! Script harus dijalankan dengan bash -c:)
roblogic
1

C (gcc) , 121 115 byte

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

Cobalah online!

Mengatur pengendali sinyal untuk SIGINT, yang dipicu dengan menekan control-C. Kami menyimpan offset waktu b, dan menampilkan waktu jam dinding dikurangi offset waktu. Jika kita dijeda, tambahkan basis waktu setiap kali jam dinding berdetak untuk membekukan waktu yang ditampilkan.

Terima kasih kepada @ceilingcat untuk mencukur 6 byte!

G. Sliepen
sumber
0

Zsh + Gnu date, 242 byte

Menampilkan 1/100 detik! Ini membutuhkan terminal interaktif, tetapi ini adalah tautan TIO .
Tekan Enteruntuk memulai / menghentikan timer; Ctrl-Cuntuk keluar.

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

Komentar (agak ketinggalan zaman):

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
sumber
@Isaac, tidak ada cara saya bisa mengalahkan jawaban Anda untuk singkatnya & elegan, jadi saya pikir saya akan menambahkan fitur sebaliknya ...
roblogic
1
Itu adalah tujuan yang sangat bagus @roblogic :-) .... .... masih memahami kode Anda ....
Isaac
0

Commodore BASIC (C64 / TheC64 Mini, VIC-20, PET, C16 / + 4) - 147 byte tokenized dan 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}dalam daftar adalah SHIFT+CLR/HOMEyang menampilkan sebagai satu karakter PETSCII ketika mengikuti tanda kutip pembukaan, sedangkan {home}adalah CLR/HOMEkunci tanpa perubahan pada kondisi yang sama mengikuti tanda kutip pembukaan.

Gunakan bilah spasi sebagai kunci kontrol.

Untuk bekerja dengan Commodore 128 di BASIC 7, ubah daftar di baris berikut:

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

Menambahkan tujuh token tambahan ke penghitungan (karena semua angka disimpan dalam BASIC sebagai 7 byte, demikian goto10juga 8 token byte sedangkan gotohanya 1).

Shaun Bebbers
sumber