Zaimplementuj stoper

23

Zaimplementuj prosty cyfrowy stoper , który wyświetli upływ czasu w sekundach i minutach, jak opisano poniżej.

Ważny

Proszę przeczytać sekcje Wyświetlania i Kontroli !

Pokaz

Upływający czas powinien być wyświetlany w MM:SSformacie, zastępując poprzednio wyświetlany ciąg czasu „w miejscu” (dozwolone jest również wyczyszczenie całego ekranu lub jego części).

Stoper musi być aktualizowany co najmniej co sekundę.

Przykłady:

0 minut, 0 sekund

00:00

0 minut, 33 sekund

00:33

1 minuta, 50 sekund

01:50

Początkowo możesz zacząć od „00: 00” lub dowolnej innej wartości z zakresu [00: 00-59: 59].

Po osiągnięciu stopera 59:59należy go zresetować 00:00i kontynuować od nowa.

Możesz użyć innej podstawy (zamiast dziesiętnej) lub nawet innego systemu liczbowego, jeśli chcesz, o ile postępujesz według ogólnego wzorca.

Na przykład 13:03może być wyświetlany jako:

Dziesiętny

13:03

Szesnastkowy

0D:03

Base64

N:D

Baza czwarto-wyobrażona

10101:3

Cyfry rzymskie

XIII:III

Uwaga: jeśli używasz systemu dziesiętnego / bazy dziesiętnej, musi być on zakodowany przy użyciu drukowalnych znaków ASCII (lub Unicode), np. Użycie dwóch binarnych (niedrukowalnych) bajtów na minuty i sekundy jest niedozwolone.

Musisz także uzupełnić dane wyjściowe odpowiednio zerami, jeśli twój system numeryczny na to pozwala.

:Dopuszczalne jest również zastąpienie znaku separatora dowolnym innym znakiem drukowalnym (w tym cyframi).

Sterownica

Stoper powinien rozpocząć wstrzymane , a pobyt w tym stanie, aż użytkownik wyraźnie zaczyna go, naciskając „kontrola” klucza (patrz poniżej).

Jeśli podczas odliczania stopera użytkownik ponownie naciśnie klawisz „Control” , stoper powinien zatrzymać się (zachowując bieżący czas), aż do ponownego naciśnięcia klawisza „Control” .

Klawisz „kontrolny” może być pojedynczym naciśnięciem klawisza, np. sLub dowolną kombinacją klawiszy, np. Ctrl+Shift+XAle musi być „atomowy”, naciskanie wielu klawiszy w sekwencji, np. sWtedy Enter, nie jest dozwolone .

Do zatrzymania i wznowienia stopera należy użyć tego samego klawisza „kontrolnego” (lub kombinacji) .

Musisz użyć specjalnego klawisza „kontrolnego” , tzn. „Dowolny klucz” jest niedozwolony.

Alternatywnie możesz użyć pojedynczego lub podwójnego kliknięcia myszą zamiast naciśnięcia klawisza w celu „sterowania”.


Zasady

  • To jest , najkrótsza odpowiedź w bajtach wygrywa;
  • Obowiązują standardowe luki w kodzie golfowym;
  • Twój program musi (teoretycznie) działać wiecznie.
zepelin
źródło
Czy można wprowadzić klawisz „kontroli”?
Loovjo
@Loovjo Tak, wystarczy dowolny klawisz lub kombinacja klawiszy, w tym Enter (o ile można go zatrzymać i wznowić za pomocą tego samego klucza).
zeppelin
powiązane
Jonathan Allan
1
Czy potrzebujemy szczegółowości poniżej sekundy? To 00:05znaczy, jeśli użytkownik zatrzyma około 7000 milisekund po wydrukowaniu, a następnie w pewnym momencie wznowi ponownie, czy musi 00:06pojawić się 3000 milisekund po naciśnięciu przycisku wznowienia, czy też czy można wydrukować go pełną sekundę po naciśnięciu przycisku wznowienia?
smls
@smls Po wznowieniu można odczekać pełną sekundę.
zeppelin

Odpowiedzi:

8

SmileBASIC, 86 77 71 bajtów

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

DIALOGwyświetla pole tekstowe na ekranie dotykowym. Nto liczba sekund, przez które pole tekstowe pozostanie na ekranie, zanim zniknie. Jeśli Ntak 0, pozostaje, dopóki użytkownik nie naciśnie przycisku na ekranie dotykowym.

DIALOGZwraca, 1jeśli użytkownik nacisnął przycisk i 0zamknął się automatycznie. Gdy użytkownik naciska przycisk pauzy, powraca 1, a czas wyświetlania jest ustawiony na 0, wstrzymując stoper. Po tym, jak użytkownik ponownie naciśnie przycisk, ustawiamy czas wyświetlania z powrotem na 1, wznawiając licznik czasu. Zasadniczo, za każdym razem , gdy DIALOGpowraca 1, czas wyświetlania jest przełączany pomiędzy 1i 0używaniem !=, co jest równoważne logicznemu XOR, o ile oba wejścia są równe 1 lub 0.

12Me21
źródło
To wygląda niesamowicie! Byłoby bardzo mile widziane, gdybyś mógł przedstawić animowany „screencast” o tym, jak to działa.
zeppelin
Ok, zrobię to wkrótce
12Me21
Można go również przetestować na tym emulatorze: citra-emu.org/game/smilebasic
roblogic
9

Python 2, 167 129 bajtów

-36 bajtów głównie * od wykorzystania pomysłu Maltysena na łapanie ctrl-cza pomocą wyjątku - idź, daj kredyt!
-4 bajty dzięki DLosc (init ni bzamiast 0 f())
-1 bajt dzięki FlipTack ( p^=1raczej zamiast p=1-p)
-2 bajty dzięki Felipe Nardi Batista (usuń specyfikatory precyzji)

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

Działa tak samo jak mój oryginał, ale z sekwencją klawiszy sterujących ctrl+c.
(Testowany przeze mnie z Python 2.7.8 na Windows 7, 64-
bitowy ; Testowany przez Briana Mintona z Python 2.7.13 na Linux, 64-bitowy)

* zwinął również ifinstrukcję do wyszukiwania listy, aby uzyskać ją tryjako jednowierszową.

Mój oryginał:

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

(Testowany przeze mnie w Pythonie 2.7.8 w systemie Windows 7, 64-bitowym - ten kod jest jednak specyficzny dla systemu Windows z powodu korzystania z msvcrtbiblioteki)

Klawisz sterujący to „p”.

ni bsą inicjowane do tej samej wartości przy uruchomieniu, dając „przesunięcie” równe 0; pjest inicjowany na 0, co oznacza stan wstrzymania.

Każde naciśnięcie klawisza sterującego powoduje zmianę wartości p. Podczas przełączania ze stanu wstrzymanego na aktywny stan bjest aktualizowany do nowej wartości, zachowując wszelkie bieżące przesunięcie względem poprzednich aktywnych stanów za pomocą b-n.

Podczas stanu aktywnego njest wielokrotnie aktualizowany do aktualnego czasu przez połączenie time.time().

Różnica pomiędzy na b, tjest to całkowita liczba sekund (w tym części ułamkowej) upłynął w stan aktywny (e).

Minęły minuty, t/60a każda minuta i sekunda są wyświetlane mod 60 z (t/60%60,t%60). Zera wiodące są poprzedzane przed każdym za pomocą formatowania ciągu części całkowitej za pomocą '...%0.2d...'. Wydrukowanie krotki (końcowej ,), w której pierwszy element ma wiodący znak powrotu karetki ( \r), powoduje zastąpienie wcześniej wydrukowanego tekstu.

Jonathan Allan
źródło
Ach tak, dobry haczyk, pierwotnie miałem, ^=ale w pewnym momencie zmieniłem formułę.
Jonathan Allan
@DLosc rzeczywiście, dzięki ...
Jonathan Allan
To nie jest specyficzne dla systemu Windows. Właśnie przetestowałem to na Linuksie 64-bitowym z Pythonem 2.7.13 i działało. (z klawiszem sterującym Ctrl-C)
Brian Minton
@BrianMinton dziękuję za poinformowanie mnie!
Jonathan Allan
jaka jest potrzeba .w %0.2d? działa dobrze, ponieważ%02d
Felipe Nardi Batista
6

Python - 160 159 143 bajtów

Dzięki @JonathanAllan za uratowanie mnie 18 bajtów!

Używa tylko wbudowanych bibliotek, więc kluczem sterującym jest ctrl-cłapanie go za pomocą 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
źródło
Och, miło. Myślę, że może może być krótszy z właśnie except:? Mam działającą wersję, która to robi ...
Jonathan Allan
@JonathanAllan oh cool, nie wiedziałem, że możesz to zrobić.
Maltysen
5

narzędzia bash + Unix, 90 lub 93 bajty

Wersja 90-bajtowa:

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

Wersja 93-bajtowa:

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

Ctrl-C jest znakiem wznowienia / pauzy. Spacja to separator między minutami a sekundami.

Różnica między dwiema wersjami polega na tym, że 90-bajtowy program będzie działał przez 2 ^ 63 sekundy (w tym momencie bash da mi przepełnienie liczb całkowitych).

Wersja 93-bajtowa będzie naprawdę działać wiecznie.

Pierwotny problem zawierał wymóg: „Twój program musi (teoretycznie) działać wiecznie”.

Jeśli uruchomienie przez 2 ^ 63 sekundy wystarczy, aby spełnić to wymaganie, wówczas rozwiązanie 90-bajtowe działa. Ten czas trwania jest ponad 20 razy większy niż wiek wszechświata!

Jeśli program musi być w stanie działać dłużej, będę musiał skorzystać z 93-bajtowego rozwiązania.


Powinienem chyba zaznaczyć, że to rozwiązanie, a także co najmniej niektóre inne opublikowane, będzie bardzo powoli opóźniało się do prawdziwego upływu czasu. Ten poślizg jest spowodowany tym, że program śpi przez jedną sekundę między każdym wykonaniem korpusu pętli, ale wykonanie pętli zajmuje trochę czasu. W praktyce będzie to nieistotne.

Mitchell Spector
źródło
Wygląda na to, że nie wyświetli początkowej wartości na ekranie, dopóki jej nie „cofniesz”.
zeppelin
„Stoper powinien rozpocząć pauzę i pozostać w tym stanie, dopóki użytkownik nie uruchomi go wyraźnie, naciskając klawisz„ Control ”(patrz poniżej).” Czy brakuje mi specyfikacji?
Mitchell Spector
tak, jest to poprawne, ale powinno nadal wyświetlać wartość początkową Initially, you can start with '00:00' or with any other value in range [00:00-59:59], która pozostanie na ekranie, dopóki nie naciśniesz „control” po raz pierwszy. Przepraszam, jeśli nie byłem w stanie sformułować tego wystarczająco jasno!
zeppelin
OK, to ma sens - zmodyfikuję to.
Mitchell Spector
1
Wygląda teraz dobrze!
zeppelin
5

QBasic, 213 211 bajtów

Klawisz Control to tab. Pozostawienie tego działania może spowodować pożary laptopa. Zostałeś ostrzeżony.

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

Tutaj jest w akcji, wstrzymuje się o 10, 15 i 20 sekund:

Uruchomiony stoper

Nie golfił i skomentował

' 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

Zauważ, że wartości TIMERsą zmiennoprzecinkowe. Nie wpływa to na wynik, ponieważ MODi \obcina się do liczb całkowitych. Ale zwiększa dokładność zaoszczędzonego czasu: jeśli zatrzymasz stoper tuż przed tyknięciem, zobaczysz, gdy uruchomisz go ponownie, że liczba zmienia się w mniej niż sekundę.

DLosc
źródło
4

Partia, 132 bajty

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

Naciśnięcie nspowoduje (od) wstrzymanie stopera. Migotanie wyjściowe można zmniejszyć kosztem trzech (lub czterech) bajtów.

Neil
źródło
4

Pure Bash, 141 bajtów

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

Wykorzystuje to tylko wbudowane Bash (bez narzędzi zewnętrznych). Znak kontrolny jest Ctrl-Ztaki, że standardowa SIGTSTPobsługa wstrzymuje stoper.

Jeśli Ctrl-Zzostanie naciśnięty, gdy podpowłoka jest na pierwszym planie, spowoduje wstrzymanie wykonania i powrót skryptu zewnętrznego na pierwszy plan, gdzie będzie cicho czekać. Jeśli zewnętrzny skrypt jest na pierwszym planie, moduł obsługi pułapek wznowi wykonywanie podpowłoki i będzie odliczał ponownie.

Michael Homer
źródło
3

JavaScript w konsoli Chrome, 143 bajty

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)

Po wprowadzeniu w konsoli włącza licznik do 00:00, a następnie włącza kontrolę naciśnięcia klawisza na dokumencie.

Nie dzieje się wiele magii, zwłaszcza (i/60)|0liczba pięter

Wykonano i przetestowano w konsoli Chrome

gzbz
źródło
Niezła odpowiedź. Można usunąć niektóre bajty, używając fikcyjnego argumentu dla funkcji, które nie przyjmują argumentu, a pierwszy argument w setInterval można zastąpić ciągiem zawierającym kod.
Łukasz
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)
Łukasz
Och, fajnie :) Nauczyłem się tutaj kilku rzeczy. Ciąg w interwale i _ => g ++. Dzięki :)
gzbz
3

HTML + JavaScript (ES6), 191 192 187 183 174 bajtów

<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

Wyjaśnienie

Kliknij stoper, aby uruchomić lub zatrzymać stoper. W związku z tym jedno kliknięcie jest klawiszem sterującym . Separator między dwiema wartościami to dwukropek.

Za każdym razem, gdy użytkownik kliknie kliknięcie, wartość parametru bjest sprawdzana. Jest on inicjowany, dla 0którego następuje ocena false, więc ciąg kodu jest oceniany co 1000 milisekund. Ustawia zmienną na identyfikator interwału, dzięki czemu można ją później zatrzymać. Jeśli bzawiera liczbę, sprawdza true, więc interwał jest zatrzymywany. Zwraca wartość undefined, więc cykl trwa.

Łańcuch kodu zmienia html elementu o id a(stoper). Najpierw minuty są analizowane przez pobranie poprzedniej wartości stopera, podzielenie jej przez dwukropek i uzyskanie wartości minut, która jest zwiększana o 0, jeśli wartość sekund nie jest 59 (większa niż 58), a 1 w przeciwnym razie, modulo 60 Następnie ta wartość jest uzupełniana. Potem pojawia się dwukropek i wreszcie sekundy. Kod po prostu pobiera starą wartość, zwiększa ją o 1, pobiera modulo 60 i opcjonalnie uzupełnia.

Luke
źródło
To wcale nie działa. Właśnie dostaję błąd ReferenceError: d nie jest zdefiniowany
Alexis Tyler
Prawdopodobnie możesz także zaoszczędzić kilka bajtów, usuwając href = #, ponieważ tak naprawdę nie jest potrzebny, ponieważ używasz onclick.
Alexis Tyler
Właśnie to naprawiłem. Usunąłem również href, ponieważ miałeś rację. Dzięki!
Łukasz
Czy nie możesz umieścić kliknięcia na znaczniku b i podać go w odpowiedzi?
Przypuszczam, że to działa. Uratował 9B. Wielkie dzięki!
Łukasz
3

C 309 179 bajtów

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

Wersja bez golfa:

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

Użycie: Naciśnij, Enteraby zatrzymać i wznowić stoper.

Wyjaśnienie:

  • Poczekaj na Enternaciśnięcie klawisza, breakpierwszą whilepętlę i poczekaj, aż Enterpojawi się następna .
  • Po kolejnym Enternaciśnięciu klawisza gotopierwsza whilepętla i wznawianie liczenia.

Wiem, że gotojest to zła praktyka kodowania w C, ale nie mogłem wymyślić innego sposobu.

Abel Tom
źródło
Kod się nie kompiluje. Ponadto getchar()blokuje do momentu naciśnięcia jakiejś postaci.
G. Sliepen
kompiluje i działa na komputerze z systemem Linux
Abel Tom
Być może wersja bez golfa, ale wersja z golfem nie. Już się m=0,s=0;nie udaje, ponieważ nigdzie nie zadeklarowano tych zmiennych.
G. Sliepen
3

JavaScript, 124 bajty

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)

„Klawisz sterujący” to kliknięcie dokumentu. Aby to przetestować, wklej kod w konsoli lub w pliku HTML wewnątrz <script>tagu.

Wyjaśnienie:

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

Testowane w Chrome

TheCopyright
źródło
1
Witamy na stronie! Czy można edytować link do strony testowej online, takiej jak Wypróbuj online! , aby inni użytkownicy mogli zweryfikować twoją odpowiedź?
caird coinheringaahing
Dzięki @cairdcoinheringaahing, to jest z jsfiddle: jsfiddle.net/xjw7o0ps
TheCopyright
2

PHP, 94 91 bajtów

Zakładam, że 32 to kod klucza spacji (który prawdopodobnie nie jest);
Obecnie nie mam możliwości przetestowania ncurses. Ale reszta kodu działa dobrze.

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

zaczyna się o 00:00, ale zwiększa się natychmiast po zakończeniu pauzy

Jeśli (podobnie jak ja) nie masz ncurses, możesz przetestować, zastępując drugi dateparametr przez $t+=$r^=!rand(sleep(1),19);lub $t+=$r^=++$x%20<1+sleep(1);. ( sleepzawsze wraca 0.)

awaria

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
    ;
Tytus
źródło
2

C # 220 bajtów

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

    }
}

Grał w golfa

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

Używanie sklawisza do uruchamiania / zatrzymywania. Cały program działa, pamiętając o użyciu TimeDeltaDateTime.Now

Większość C # -Magic tutaj pochodzi z funkcji C # 7.0 using static.

CSharpie
źródło
2

Bash, 65 bajtów

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

Pamiętaj, że musi być zapisany w skrypcie pliku, aby działał poprawnie, w przeciwnym razie spróbuj:

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

Wersja rozszerzona, aby to wyjaśnić:

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

%(...)TFormat printf jest ważna w bash 5+.

Izaak
źródło
Nie działa Po prostu drukuje 00:00i zwiększa licznik po uderzeniu Ctrl-C. Nie ma animacji timera. (Testowane na bash 5.0.7)
roblogic
1
Czy napisałeś kod do skryptu? Albo spróbuj: bash -c 'trap d=\$[!d] 2;for((;;)){ printf "\r%(%M:%S)T" $[n+=d];sleep 1;}'. @roblogic
Isaac
Ach, zadziałało! Skrypt musi być uruchamiany z bash -c:)
roblogic
1

C (gcc) , 121 115 bajtów

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

Wypróbuj online!

Ustawia moduł obsługi sygnału dla SIGINT, który jest wyzwalany przez naciśnięcie Control-C. Trzymamy przesunięcie czasowe bi wyświetlamy zegar ścienny minus przesunięcie czasowe. Jeśli jesteśmy zatrzymani, zwiększaj podstawę czasu za każdym razem, gdy tyka zegar ścienny, aby zatrzymać wyświetlany czas.

Dzięki @ceilingcat za golenie 6 bajtów!

G. Sliepen
źródło
0

Data Zsh + Gnu, 242 bajty

Wyposażony w 1/100 sekundy! Wymaga interaktywnego terminala, ale tutaj jest link TIO .
Naciśnij, Enteraby uruchomić / zatrzymać stoper; Ctrl-Cdo wyjścia.

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

Komentarze (nieco nieaktualne):

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
źródło
@Isaac, nie ma szans, żebym pobił twoją odpowiedź za zwięzłość i elegancję, więc pomyślałem, że zamiast tego dodam funkcje ...
roblogic
1
To doskonały cel @roblogic :-) .... .... wciąż rozumiem twój kod ....
Isaac
0

Commodore BASIC (C64 / TheC64 Mini, VIC-20, PET, C16 / + 4) - 147 bajtów tokenizowanych i 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}w wykazie jest to, SHIFT+CLR/HOMEktóry wyprowadza jako jeden znak PETSCII, gdy występuje po otwierającym cudzysłowie, podczas gdy {home}jest CLR/HOMEkluczem bez przesunięcia, pod tym samym warunkiem podążania za otwierającym cudzysłowiem.

Użyj spacji jako klawisza sterującego.

Aby pracować z Commodore 128 w BASIC 7, zmień listę w następujących wierszach:

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

Dodaje dodatkowe siedem tokenów do liczby (ponieważ wszystkie liczby są przechowywane w języku BASIC jako 7 bajtów, więc goto10jest 8 bajtów tokenizowanych, podczas gdy gotojest tylko 1).

Shaun Bebbers
źródło