Implementieren Sie eine Stoppuhr

23

Implementieren Sie eine einfache digitale Stoppuhr , die die verstrichene Zeit in Sekunden und Minuten anzeigt, wie unten beschrieben.

Wichtig

Bitte lesen Sie sowohl den Abschnitt Display als auch die Bedienelemente !

Anzeige

Die abgelaufene Zeit sollte im MM:SSFormat angezeigt werden, indem die zuvor angezeigte Zeitzeichenfolge "an Ort und Stelle" ersetzt wird (das Löschen des gesamten oder eines Teils des Bildschirms ist ebenfalls zulässig).

Die Stoppuhr muss mindestens jede Sekunde aktualisiert werden.

Beispiele:

0 Minuten, 0 Sekunden

00:00

0 Minuten, 33 Sekunden

00:33

1 Minute, 50 Sekunden

01:50

Anfänglich können Sie mit '00: 00 'oder einem anderen Wert im Bereich [00: 00-59: 59] beginnen.

Sobald Ihre Stoppuhr erreicht ist 59:59, sollte sie auf zurückgesetzt werden 00:00und von Neuem fortgesetzt werden.

Sie können eine andere Basis (anstelle der Dezimalzahl) oder sogar ein anderes Zahlensystem verwenden, sofern Sie dem allgemeinen Muster folgen.

Zum Beispiel 13:03kann angezeigt werden als:

Dezimal

13:03

Hexadezimal

0D:03

Base64

N:D

Viertel-imaginäre Basis

10101:3

Römische Zahlen

XIII:III

Beachten Sie, dass bei Verwendung eines nicht-dezimalen Zahlensystems / einer nicht-dezimalen Basis die Kodierung mit druckbaren ASCII- (oder Unicode-) Zeichen erfolgen muss, z. B. ist die Verwendung von zwei binären (nicht druckbaren) Bytes für Minuten und Sekunden nicht zulässig.

Sie müssen Ihre Ausgabe auch mit Nullen belassen, sofern Ihr numerisches System dies zulässt.

Das Ersetzen des Trennzeichens :durch ein beliebiges anderes druckbares Zeichen (einschließlich Ziffern) ist ebenfalls zulässig.

Kontrollen

Die Stoppuhr sollte angehalten werden und in diesem Zustand bleiben, bis der Benutzer sie explizit durch Drücken der Steuertaste startet (siehe unten).

Wenn der Benutzer während des Zählens der Stoppuhr erneut die Steuertaste drückt , sollte die Stoppuhr pausieren (wobei die aktuelle Zeit beibehalten wird), bis die Steuertaste ein weiteres Mal gedrückt wird.

Die ‚Kontrolle‘ Schlüssel kann einen einzigen Tastendruck sein, zum Beispiel s, oder eine beliebige Kombination von Tasten, zum Beispiel Ctrl+Shift+X, aber es muss ‚atomic‘ Drücken mehrerer Tasten nacheinander sein, beispielsweise sdann Enter, wird nicht erlaubt .

Dieselbe 'Steuertaste' (oder Kombination) muss verwendet werden, um die Stoppuhr anzuhalten und fortzusetzen.

Sie müssen einen bestimmten 'Kontroll'- Schlüssel verwenden, dh' jeder Schlüssel 'ist nicht zulässig.

Alternativ können Sie einen einfachen oder doppelten Mausklick anstelle eines Tastendrucks für die 'Steuerung' verwenden.


Regeln

  • Dies ist , die kürzeste Antwort in Bytes gewinnt;
  • Es gelten die Standard-Code-Golf-Regelungslücken.
  • Ihr Programm muss (theoretisch) für immer lauffähig sein.
Zeppelin
quelle
Kann der 'Kontroll'-Schlüssel eingegeben werden?
Loovjo
@Loovjo Ja, eine einzelne Taste oder Tastenkombination, einschließlich der Eingabetaste, ist ausreichend (solange sie angehalten und mit derselben Taste fortgesetzt werden kann).
Zeppelin
Related
Jonathan Allan
1
Benötigen wir eine Granularität von weniger als einer Sekunde? Wenn der Benutzer nach dem 00:05Drucken etwa 7000 Millisekunden pausiert und dann zu einem bestimmten Zeitpunkt wieder aufnimmt, müssen dann 00:063000 Millisekunden nach dem Drücken der Wiederaufnahmetaste angezeigt werden, oder ist es in Ordnung, sie eine volle Sekunde nach dem Drücken der Wiederaufnahmetaste zu drucken?
smls
@smls Es ist in Ordnung, nach dem Lebenslauf eine volle Sekunde zu warten.
Zeppelin

Antworten:

8

SmileBASIC, 86 77 71 Bytes

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

DIALOGzeigt ein Textfeld auf dem Touchscreen an. NGibt die Anzahl der Sekunden an, die das Textfeld auf dem Bildschirm angezeigt wird, bevor es verschwindet. Wenn Nja 0, bleibt es, bis der Benutzer die Taste auf dem Touchscreen drückt.

DIALOGGibt zurück, 1ob der Benutzer die Schaltfläche gedrückt hat und 0ob sie automatisch geschlossen wurde. Wenn der Benutzer die Pause-Taste drückt, kehrt diese zurück 1und die Anzeigezeit wird auf eingestellt 0, wodurch die Stoppuhr angehalten wird. Nachdem der Benutzer die Taste erneut gedrückt hat, setzen wir die Anzeigezeit auf zurück 1und setzen den Timer fort. Grundsätzlich wird bei jeder DIALOGRückkehr 1die Anzeigezeit zwischen 1und 0using umgeschaltet !=, was für ein logisches XOR von Bedeutung ist, solange beide Eingänge 1 oder 0 sind.

12Me21
quelle
Das sieht toll aus! Wenn Sie auch einen animierten "Screencast" darüber liefern könnten, wie es funktioniert, wäre das sehr dankbar!
Zeppelin
Ok, ich werde es bald tun
12Me21
Es könnte auch auf diesem Emulator getestet werden: citra-emu.org/game/smilebasic
roblogic
9

Python 2, 167 129 Bytes

-36 Bytes meistens * von Maltysens Idee , ctrl-cmit einer Ausnahme zu fangen - geben Sie Kredit!
-4 Bytes dank DLosc (init nund bstattdessen auf 0 f())
-1 Bytes dank FlipTack ( p^=1stattdessen verwenden p=1-p)
-2 Bytes dank Felipe Nardi Batista (Genauigkeitsangaben entfernen)

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

Funktioniert genauso wie mein Original, nur mit der Steuertastenfolge von ctrl+c.
(Getestet von mir mit Python 2.7.8 unter Windows 7, 64bit;
Getestet von Brian Minton mit Python 2.7.13 unter Linux, 64bit)

* auch reduzierte ifAussage zu einer Listensuche, um die tryals Einzeiler zu bekommen .

Mein Original:

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

(Getestet von mir mit Python 2.7.8 unter Windows 7, 64-Bit - dieser Code ist jedoch Windows-spezifisch, da die msvcrtBibliothek verwendet wird.)

Die Steuertaste ist 'p'.

nund bwerden beim Start auf den gleichen Wert initialisiert, was einen "Offset" von 0 ergibt; pwird auf 0 initialisiert, was einen angehaltenen Zustand anzeigt.

Bei jedem Drücken der Steuertaste wird der Wert von pumgeschaltet. Beim Umschalten von einem angehaltenen Zustand in einen aktiven Zustand bwird mit ein neuer Wert unter Beibehaltung des aktuellen Offsets von dem vorherigen aktiven Zustand (den vorherigen aktiven Zuständen) aktualisiert b-n.

Während eines aktiven Zustands nwird durch Aufruf immer wieder die aktuelle Uhrzeit aktualisiert time.time().

Die Differenz zwischen nund b, tist dann die Gesamtanzahl von Sekunden (einschließlich eines Bruchteils), die während eines aktiven Zustands bzw. aktiver Zustände verstrichen sind.

Die abgelaufenen Minuten sind dann t/60und jede der Minuten und Sekunden wird mit mod 60 angezeigt (t/60%60,t%60). Führenden Nullen werden jeweils vorangestellt, indem die Zeichenfolge des ganzzahligen Teils mit formatiert wird '...%0.2d...'. Durch das Drucken eines Tupels (das nachfolgende ,), bei dem das erste Element einen führenden Wagenrücklauf (das \r) aufweist, wird der zuvor gedruckte Text überschrieben.

Jonathan Allan
quelle
Ah ja, guter Fang, ich hatte ursprünglich ^=doch irgendwann während der Formulierung umgestellt.
Jonathan Allan
@ DLosc in der Tat, danke ...
Jonathan Allan
Es ist nicht Windows-spezifisch. Ich habe dies gerade unter Linux 64-Bit mit Python 2.7.13 getestet und es hat funktioniert. (mit der Steuertaste von Strg-C)
Brian Minton
@ BrianMinton Danke, dass Sie mich wissen lassen!
Jonathan Allan
Was ist der Bedarf für die .in %0.2d? Es funktioniert gut als%02d
Felipe Nardi Batista
6

Python - 160 159 143 Bytes

Vielen Dank an @ JonathanAllan für die Rettung von 18 Bytes!

Verwendet nur eingebaute Bibliotheken, daher ist der Steuerschlüssel ctrl-c, der mit einem abfängt 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
quelle
Oh schön. Ich denke vielleicht könnte es mit gerade kürzer werden except:? Ich habe eine funktionierende Version von mir dabei ...
Jonathan Allan
@ JonathanAllan oh cool, ich wusste nicht, dass du das kannst.
Maltysen
5

Bash + Unix-Dienstprogramme, 90 oder 93 Bytes

90-Byte-Version:

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

93-Byte-Version:

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

Strg-C ist das Resume / Pause-Zeichen. Ein Leerzeichen ist das Trennzeichen zwischen Minuten und Sekunden.

Der Unterschied zwischen den beiden Versionen besteht darin, dass das 90-Byte-Programm 2 ^ 63 Sekunden lang funktioniert (an diesem Punkt gibt mir bash einen Ganzzahlüberlauf).

Die 93-Byte-Version wird wirklich für immer funktionieren.

Das ursprüngliche Problem beinhaltete die Anforderung: "Ihr Programm muss (theoretisch) für immer lauffähig sein."

Wenn eine Laufzeit von 2 ^ 63 Sekunden ausreicht, um diese Anforderung zu erfüllen, funktioniert die 90-Byte-Lösung. Diese Dauer ist mehr als das 20-fache des Zeitalters des Universums!

Wenn das Programm länger ausgeführt werden soll, muss ich mich für die 93-Byte-Lösung entscheiden.


Ich sollte wahrscheinlich darauf hinweisen, dass diese Lösung, wie zumindest einige der anderen, sehr langsam hinter der tatsächlich verstrichenen Zeit zurückbleiben wird. Diese Abweichung ist darauf zurückzuführen, dass das Programm zwischen jeder Ausführung des Schleifenkörpers eine Sekunde lang schläft, die Ausführung des Schleifenkörpers jedoch eine winzige Zeit in Anspruch nimmt. Dies ist in der Praxis ohne Belang.

Mitchell Spector
quelle
Es sieht so aus, als würde dies keinen Anfangswert auf dem Bildschirm anzeigen, bis Sie die "Pause" aufheben.
Zeppelin
"Die Stoppuhr sollte angehalten werden und in diesem Zustand bleiben, bis der Benutzer sie explizit durch Drücken der Steuertaste startet (siehe unten)." Gibt es eine Spezifikation, die ich verpasst habe?
Mitchell Spector
Ja, dies ist korrekt, aber es sollte immer noch ein Anfangswert angezeigt werden Initially, you can start with '00:00' or with any other value in range [00:00-59:59], der auf dem Bildschirm angezeigt wird, bis Sie zum ersten Mal auf "Steuerung" drücken. Entschuldigung, wenn ich das nicht klar genug formulieren konnte!
Zeppelin
OK, das macht Sinn - ich werde es ändern.
Mitchell Spector
1
Sieht jetzt alles gut aus!
Zeppelin
5

QBasic, 213 211 Bytes

Steuertaste ist die Registerkarte. Wenn Sie dieses Programm nicht verwenden, kann dies zu Bränden am Laptop führen. Du wurdest gewarnt.

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

Hier ist es in Aktion und pausiert nach 10, 15 und 20 Sekunden:

Stoppuhr läuft

Ungolfed und kommentiert

' 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

Beachten Sie, dass die Werte von TIMERGleitkomma sind. Dies hat keine Auswirkungen auf die Ausgabe, da MODund \auf ganze Zahlen abgeschnitten. Dies erhöht jedoch die Genauigkeit der gespeicherten Zeit: Wenn Sie den Timer kurz vor einem Häkchen anhalten, werden Sie beim nächsten Start feststellen, dass sich die Zahl in weniger als einer Sekunde ändert.

DLosc
quelle
4

Batch, 132 Bytes

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

Durch Drücken von n(un) wird der Timer angehalten. Das Ausgabeflackern kann auf Kosten von drei (oder vier) Bytes reduziert werden.

Neil
quelle
4

Pure Bash, 141 Bytes

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

Hierfür werden nur Bash-Builtins verwendet (keine externen Tools). Das Steuerzeichen ist Ctrl-Z, so dass die Standardbehandlung SIGTSTPdie Stoppuhr anhält.

Wenn Ctrl-Zgedrückt wird, während die Subshell im Vordergrund ist, wird die Ausführung angehalten und das äußere Skript in den Vordergrund zurückgesetzt, wo es still wartet. Wenn das äußere Skript im Vordergrund ist, setzt der Trap-Handler die Ausführung der Subshell fort und zählt erneut hoch.

Michael Homer
quelle
3

Javascript in der Chrome-Konsole, 143 Bytes

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)

Bei Eingabe in der Konsole wird der Zähler auf 00:00 gesetzt und anschließend die Steuerung aktiviert, die auf dem Dokument per Tastendruck ausgeführt wird.

Es ist nicht viel Magie im Gange, vor allem (i/60)|0die Anzahl der Stockwerke

Fertig und in der Chrome-Konsole getestet

gzbz
quelle
Gute Antwort. Sie können einige Bytes entfernen, indem Sie ein Dummy-Argument für die Funktionen verwenden, für die kein Argument zulässig ist, und Sie können das erste Argument im setInterval durch eine Zeichenfolge ersetzen, die den Code enthält.
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, nett :) Habe hier ein paar Dinge gelernt. Zeichenkette im Intervall und das _ => g ++. Danke :)
gzbz
3

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

<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

Erläuterung

Klicken Sie auf den Timer, um die Stoppuhr zu starten oder anzuhalten. Als solches ist ein einziger Klick der Steuerschlüssel . Das Trennzeichen zwischen den beiden Werten ist ein Doppelpunkt.

Immer wenn der Benutzer auf den Klick klickt, wird der Wert von büberprüft. Es wird initialisiert, auf 0was ausgewertet wird false, sodass alle 1000 Millisekunden eine Code-Zeichenfolge ausgewertet wird. Dadurch wird die Variable auf die ID des Intervalls gesetzt, sodass sie später beendet werden kann. Wenn beine Zahl enthalten ist, wird sie zu ausgewertet true, sodass das Intervall angehalten wird. Dies gibt den Wert zurück undefined, sodass der Zyklus fortgesetzt wird.

Die Code-Zeichenfolge ändert das HTML des Elements mit der ID a(der Stoppuhr). Zuerst werden die Minuten analysiert, indem der vorherige Stoppuhrwert durch den Doppelpunkt geteilt und der Minutenwert abgerufen wird, der um 0 erhöht wird, wenn der Sekundenwert nicht 59 (größer als 58) ist, und ansonsten 1, Modulo 60 Dann wird dieser Wert aufgefüllt. Dann kommt der Doppelpunkt und zuletzt die Sekunde. Der Code erhält einfach den alten Wert, erhöht ihn um 1, nimmt modulo 60 und füllt ihn optional auf.

Luke
quelle
Das scheint überhaupt nicht zu funktionieren. Ich bekomme gerade ReferenceError: d ist nicht definiert
Alexis Tyler
Sie können wahrscheinlich auch ein paar Bytes sparen, indem Sie href = # entfernen, da es nicht wirklich benötigt wird, da Sie onclick verwenden.
Alexis Tyler
Ich habe das gerade behoben. Ich habe auch die Href entfernt, weil du recht hattest. Vielen Dank!
Luke
Können Sie nicht den Klick auf das b-Tag setzen und dies in der Antwort angeben?
Ich nehme an, das funktioniert. Es sparte 9B. Vielen Dank!
Luke
3

C 309 179 Bytes

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

Ungolfed-Version:

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

Verbrauch: Drücken Sie Enterauf Pause und Fortsetzen der Stoppuhr.

Erläuterung:

  • Warte auf EnterTastendruck, breakdie erste whileSchleife und warte bis die nächste Enterkommt.
  • Beim nächsten EnterTastendruck die gotoerste whileSchleife starten und mit dem Zählen fortfahren.

Ich weiß, dass gotoC eine schlechte Codierungspraxis ist, aber ich konnte keinen anderen Weg finden.

Abel Tom
quelle
Der Code wird nicht kompiliert. Außerdem wird getchar()geblockt, bis ein Zeichen gedrückt wird.
G. Sliepen
kompiliert und läuft auf einem Linux-Rechner
Abel Tom
Die ungolfed Version vielleicht, aber die golfed Version nicht. Schon m=0,s=0;daran scheitert es, weil Sie diese Variablen nirgendwo deklariert haben.
G. Sliepen
3

Javascript, 124 Bytes

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)

Der 'Steuerschlüssel' ist ein Klick auf das Dokument. Um dies zu testen, fügen Sie den Code in die Konsole oder in eine HTML-Datei im <script>Tag ein.

Erläuterung:

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

Getestet in Chrome

DasCopyright
quelle
1
Willkommen auf der Seite! Wäre es möglich, einen Link zu einer Online-Testseite zu bearbeiten, z. B. "Online testen" ? , damit andere Benutzer Ihre Antwort überprüfen können?
Caird Coinheringaahing
Danke @cairdcoinheringaahing, dies ist mit jsfiddle: jsfiddle.net/xjw7o0ps
TheCopyright
2

PHP, 94 91 Bytes

Ich gehe davon aus, dass 32 der Schlüsselcode für die Leertaste ist (was es wahrscheinlich nicht ist);
Ich habe derzeit keine Möglichkeit, ncurses zu testen. Aber der Rest des Codes funktioniert gut.

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

beginnt um 00:00, erhöht sich jedoch sofort, wenn die Pause endet

Wenn Sie (wie ich) keine Flüche haben, können Sie dies testen, indem Sie den zweiten dateParameter durch $t+=$r^=!rand(sleep(1),19);oder ersetzen $t+=$r^=++$x%20<1+sleep(1);. ( sleepkehrt immer zurück 0.)

Nervenzusammenbruch

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
quelle
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 gespielt

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

Mit der sTaste starten / stoppen. Das gesamte Programm merkt sich das TimeDelta mitDateTime.Now

Der größte Teil von C # -Magic stammt aus der C # 7.0-Funktion using static.

CSharpie
quelle
2

Bash, 65 Bytes

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

Beachten Sie, dass es in ein Dateiskript geschrieben werden muss, damit es ordnungsgemäß funktioniert. Andernfalls versuchen Sie Folgendes:

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

Erweiterte Version, um es zu erklären:

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

Das %(...)Tzu druckende Format ist in Bash 5+ gültig.

Isaac
quelle
Funktioniert nicht Nur druckt 00:00und erhöht einen Zähler, wenn Sie drücken Ctrl-C. Es gibt keine Animation des Timers. (Getestet auf Bash 5.0.7)
Roblogic
1
Hast du den Code in ein Skript geschrieben? Oder aber bitte versuchen Sie es: bash -c 'trap d=\$[!d] 2;for((;;)){ printf "\r%(%M:%S)T" $[n+=d];sleep 1;}'. @roblogic
Isaac
Ahh, das hat funktioniert! Das Skript muss mit bash -c:) ausgeführt werden
roblogic
1

C (gcc) , 121 115 Bytes

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

Probieren Sie es online!

Legt einen Signal-Handler für SIGINT fest, der durch Drücken von Strg-C ausgelöst wird. Wir behalten einen Zeitversatz bei bund zeigen die Zeit der Wanduhr abzüglich des Zeitversatzes an. Wenn wir angehalten haben, erhöhen Sie die Zeitbasis jedes Mal, wenn die Wanduhr tickt, um die angezeigte Zeit einzufrieren.

Danke an @ceilingcat für das Abschneiden von 6 Bytes!

G. Sliepen
quelle
0

Zsh + Gnu Datum, 242 Bytes

Mit 1/100 Sekunde! Es erfordert ein interaktives Terminal, aber hier ist trotzdem eine TIO-Verbindung .
Drücken Sie Enter, um den Timer zu starten / zu stoppen. Ctrl-Cbeenden.

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

Kommentare (etwas veraltet):

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
quelle
@Isaac, ich kann deine Antwort aus Gründen der Kürze und Eleganz auf keinen Fall übertreffen. Ich dachte, ich würde stattdessen Features hinzufügen ...
roblogic
1
Das ist ein exzellentes Ziel @roblogic :-) .... .... immer noch Ihren Code zu verstehen ....
Isaac
0

Commodore BASIC (C64 / TheC64 Mini, VIC-20, PET, C16 / + 4) - 147 tokenisierte und BASIC-Bytes

 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}In der Auflistung steht, SHIFT+CLR/HOMEwelches als ein PETSCII-Zeichen ausgegeben wird, wenn einem öffnenden Anführungszeichen gefolgt wird, wohingegen {home}der CLR/HOMESchlüssel ohne die Verschiebung unter der gleichen Bedingung einem öffnenden Anführungszeichen folgt.

Verwenden Sie die Leertaste als Steuertaste.

Ändern Sie die Liste in den folgenden Zeilen, um mit dem Commodore 128 in BASIC 7 zu arbeiten:

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

Fügt der Zählung weitere sieben Token hinzu (da alle Zahlen in BASIC als 7 Byte gespeichert sind, sind dies goto108 Token-Bytes, wohingegen gotoes sich nur um 1 handelt).

Shaun Bebbers
quelle