Thực hiện đồng hồ bấm giờ đơn giản


25

Thử thách

Nhiệm vụ của bạn là viết một chương trình, mỗi giây một lần (bao gồm ngay lập tức khi chương trình của bạn được bắt đầu), in thời gian đã trôi qua kể từ khi chương trình của bạn được bắt đầu.

Quy tắc

  • Thời gian phải được in ở hh:mm:ssđịnh dạng. (các số 0 đứng đầu cho các giá trị một chữ số)
  • Các dấu thời gian phải được phân tách bằng CR, LF hoặc CRLF. (không có khoảng trắng hàng đầu)
  • Một thời gian mới phải xuất hiện mỗi giây. (thiết bị xuất chuẩn không thể được đệm trong một giây)
  • Hành vi của chương trình nếu chạy quá 23:59:59 là không xác định.
  • Bạn có thể sử dụng sleep(1)ngay cả khi một giây cụ thể có thể bị bỏ qua bất cứ khi nào chi phí để in, tính toán, lặp, v.v. tích lũy thành một giây.

Ví dụ đầu ra:

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

Lưu ý rằng 00:00:03thiếu ở đây do xử lý trên không. Các giá trị bỏ qua thực tế (nếu có) tất nhiên phụ thuộc vào việc triển khai và / hoặc hệ thống.

Tham chiếu triển khai trong C: (chỉ các hệ thống tương thích 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);
    }
}

Tiêu chí chiến thắng

Đây là , mã ngắn nhất trong byte win!


Lưu ý cho những thách thức sau này, làm rõ trong các ý kiến ​​là một điều xấu để làm. tài liệu tham khảo
user202729

Câu trả lời:


9

MATL , 17 16 byte

`Z`12L/13XOD1Y.T

Hãy thử nó tại MATL Online!

Làm thế nào nó hoạt động

`         % 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)

4
Làm thế nào trên thế giới bạn đã trả lời này 37 phút sau khi nó đã bị đóng cửa? o_O đổ lỗi cho bộ nhớ đệm
Ông Xcoder

9
@ Mr.Xcoder Gần đây tôi đã học cách sử dụng Thần lực
Luis Mendo

29

Hoạt động ngôn ngữ kịch bản 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"

Trong hành động:

158 byte, nếu lần trước bị ghi đè vào lần tiếp theo:

#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"

Về mặt kỹ thuật, không có lợi nhuận vận chuyển được sử dụng, vì vậy tôi không chắc phiên bản này có tuân theo các quy tắc hay không.


5
Tôi đã không mong đợi flashpoint hoạt động.
Polyducks 27/12/17

10
@Polyducks không ai mong đợi flashpoint hoạt động
Pureferret


Vì trong Unix, một CR sẽ ghi đè lên dòng, tôi nghĩ rằng câu trả lời thứ hai được xác thực bởi 'CR, LF hoặc CRLF được cho phép'
Stan Strum

1
@StanStrum Ít nhất trên Ubuntu của tôi CRsẽ không ghi đè lên dòng. Trong thực tế, CRLF, LFCRLFđều là ngữ nghĩa tương đương.

13

Bash + coreutils, 28 26 byte

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

Ký tự không thể in giữa +%là một byte ESC .

Điều này đặt thời gian hệ thống thành 00:00:00 và do đó yêu cầu quyền root. Nó cũng giả định rằng múi giờ là UTC và không có quá trình nào khác sẽ can thiệp vào đồng hồ hệ thống.

Mỗi thời gian mới đặt lại thiết bị đầu cuối, do đó ghi đè lên thiết bị đầu cuối.


Bash + coreutils, 38 29 byte

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

Những hạn chế tương tự như trước khi áp dụng. Mỗi thời điểm mới được hiển thị trên một dòng mới.


Vì nó không thay đổi bytecount, tôi tách phần đầu tiên datevới phần còn lại bằng một dòng nhỏ xinh. Nhưng nó có thể là quá tốt để ai đó có thể đưa ra một cái gì đó như giải pháp thứ hai của bạn> :-(
Aaron

date -s0in thời gian mới sang STDOUT; Tôi đang sử dụng đường ống để tắt đầu ra đó.
Dennis

Oh đúng, cảm ơn đã giải thích!
Aaron

5

APL (Dyalog Unicode) , 51 byte

Toàn thân chương trình.

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

Hãy thử trực tuyến! (Nhấn Ctrl + Enter để bắt đầu và một lần nữa để dừng.)

⎕AIThông tin ccount I (ID người dùng, thời gian tính toán, thời gian kết nối, thời gian khóa)

s← gán cho s(đối với s tart thời gian)
⎕AI-s trừ stừ⎕AI

3⊃ chọn các yếu tố thứ ba (thời gian kết nối trong mili giây)
0 60 60 1E3⊤chuyển đổi để hỗn hợp radix này
3↑ mất 3 đầu tiên (giọt mili giây)
100+ một trăm thêm vào mỗi (để số không pad)
':'@1∘⍕¨ sửa đổi với một dấu hai chấm ở ký tự đầu tiên của chuỗi đại diện của mỗi
ε nlist (flatten)
1↓ thả dấu hai chấm đầu tiên (và in ngầm vào thiết bị xuất chuẩn)

⎕DL 1D e l ay một giây

→2 đi đến dòng số hai


5

R , 59 44 byte

Ftrong R mặc định FALSE, nhưng đó là một biến thông thường và có thể được xác định lại. Khi được sử dụng trong số học, FALSEbị ép buộc 0. Yêu cầu F+1trả lại do đó 1. Chúng tôi chỉ định FF+1, định dạng độc đáo, in và chờ trong một giây. Tiếp tục vô tận.

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

Không hoạt động trên TIO (do thiếu hmsgói), nhưng đây là một đầu ra mẫu từ máy của tôi:

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

5

bash + ngủ + ngày, cũng 50 49 47 46 45 41 byte

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

Để mất một thời gian vòng, nhanh chóng nhấn ^ C, chạy này và sau đó chạy lại ở trên:

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

Để thiết lập lại:

s=0; unset laps

Cú pháp $ [s ++] dường như vẫn hoạt động, nhưng không còn (AFAICS) được ghi lại trong bashtrang man. Và nó vẫn ngắn hơn một byte so với sử dụng vòng lặp for ((...)), khi tôi xóa các trích dẫn xung quanh nó.


AFAICT, $[]là một hình thức không được chấp nhận / không có giấy tờ nhưng vẫn được hỗ trợ$(()) . Tôi không chắc liệu nó có thường được sử dụng trong các câu trả lời golf-code không, nhưng quy tắc chung là mã của bạn chỉ phải hoạt động trên ít nhất một phiên bản trình thông dịch cho ngôn ngữ của bạn. IMO nó ổn.
Peter Cordes

s=0không bắt buộc, vì sự thay thế số học sẽ coi một biến không đặt là 0 . -ucũng không cần thiết nếu bạn chỉ giả sử múi giờ mặc định (UTC).
Dennis

-u là cần thiết trên máy của tôi :)
Will Crawford

4

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

Giải trình

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
}

4

JavaScript (ES6), 99 byte

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


2
Giờ không bắt đầu từ 0 đối với tôi. Độ lệch thay đổi tùy theo múi giờ của hệ thống. (Win10)
LukeS

@LukeS Rất tiếc, đã sửa!
darrylyeo

4

Matlab (R2016b), 50 byte

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

Giải trình:

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

Phiên bản thay thế (50 byte quá: P):

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

Chào mừng đến với trang web! :)
DJMcMayhem

Cảm ơn người bạn đời:)
Thiago Oleinik

@LuisMendo Cảm ơn bạn đã gợi ý, nhưng tôi không hiểu ... Trong ví dụ của bạn, biến là tgì? Ngoài ra, đầu vào tính datestrbằng ngày, vì vậy tôi sẽ phải chia cho 86400, số này sẽ tăng số byte lên hai ...
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

Hãy thử trực tuyến!

Với chế độ ngủ (1) được cho phép, các vòng lặp lồng nhau đơn giản sẽ ngắn hơn so với sử dụng các phương pháp xử lý thời gian tích hợp sẵn của Julias.

Giải pháp cũ không ngủ (1) bằng DateTime

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

tlà lượng thời gian được truyền từ 'ngày 0' đến khi chương trình bắt đầu. now()-tlà một khoảnh khắc trong thời gian , sau đó được định dạng bằng cách sử dụng Dates.format().

t0=now(); ...; now()-t0sẽ mang lại một sự khác biệt thời gian , mà không thể được sử dụng với Dates.format().

Thời gian chính nó là tầm thường với tích hợp Timer.


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

Tín dụng


Bạn có thể lưu một byte bằng cách thay thế "%02d:%02d:%02d"bằng(":%02d"*3)[1:]
wnnmaw

1
Bạn không cần %24, hành vi không xác định sau 23:59:59.
Erik the Outgolfer 28/12/17

@EriktheOutgolfer Điểm tốt, cập nhật.
Neil

3

JavaScript (ES6), 88 byte

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

Về cơ bản cách tiếp cận tương tự như câu trả lời của @ darrylyeo , nhưng hoạt động cho tất cả các múi giờ và sử dụng một cách hơi khác để về 0.

[Chỉnh sửa] Câu trả lời của Darryl đã được sửa. Điều này vẫn còn ngắn hơn, mặc dù.


3

> <> , 82 + 7 = 89 byte

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

Hãy thử trực tuyến!

+7 byte để sử dụng cờ -t.0125 để làm cho mỗi lệnh mất 1/80 giây. Mỗi vòng lặp có 80 hướng dẫn, làm cho mỗi vòng lặp dài một giây. Bởi vì thời gian tính toán, điều này thực sự dài hơn trong thực tế.

Tôi thực sự đã phải đệm tất cả lên đến 100 cho đến khi tôi thấy câu trả lời của @Not A Tree có cách tốt hơn 7 byte so với của tôi để tạo ra số giờ và phút, cắt nó xuống dưới 80. Họ cũng truyền cảm hứng cho việc sử dụng \/được thực hiện hai lần mỗi vòng lặp.

Làm thế nào nó hoạt động

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

Tiền thưởng:

Phiên bản một dòng có cùng kích thước, 80 + 9 byte:

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

Điều này sử dụng -acờ để thêm đánh dấu cho các hướng dẫn bỏ qua.


3

PHP 4+, 70 64 byte

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

PHP 5.3 trở lên, 69 63 byte

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

Các thẻ mở PHP có thể được bỏ qua trong câu trả lời giúp bạn tiết kiệm 6 byte.
Daniel W.

2

Python 3 , 112 byte

Giả sử sử dụng độ trễ 1 giây là ổn, ngay cả khi nó (hiếm khi) có thể bỏ qua một giây.

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)

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

chạy trong cửa sổ ngay lập tức: điểm thất bại dự kiến ​​ở đâu đó khoảng 23 triệu năm (độ phân giải dấu phẩy động thất bại ~ 8,5e9 ngày)



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

Không hoạt động trong TIO.


Chương trình của bạn dường như không in 00:00:00vào thời điểm nó bắt đầu.
dùng202729

Đã sửa nó. Cảm ơn
Noskcaj


2

Bash + coreutils + ngày GNU, 50 byte

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

Lấy cảm hứng từ @Dennis, giải pháp này không đòi hỏi thời gian để thay đổi. Cửa hàng này lưu trữ phần bù ban đầu từ giờ đến kỷ nguyên UNIX (ngày 1 tháng 1 năm 1970 00:00:00 UTC), trong 'o', và sau đó hiển thị [tùy chọn -ud] (thời gian hiện tại - bù), vào ngày UTC, nhưng chỉ [+% X tùy chọn] HH: MM: SS. Điều này sẽ hoạt động ở các quốc gia nơi múi giờ hiện tại không phải là UTC.


2

Sạch sẽ , 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]

Cái này chỉ hoạt động trong gói Windows Clean.

Thêm 3 byte nếu bạn muốn nó hoạt động trong Linux, như Clean's CLK_PER_TICK :== 1000000on * nix. Nếu bạn muốn nó là nền tảng chéo, thay vào đó hãy thêm 8 byte, vì bạn cần sử dụng CLK_PER_TICKthay vì giá trị mà nó được đặt thành. ( Liên kết TIO lớn hơn do ở trên )

Hãy thử trực tuyến!


2

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

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

Điều này chạy trong một vòng lặp liên tục, không ngủ, cập nhật thời gian trên cùng một dòng thay vì in một dòng mới mỗi giây. (Vẫn được cho phép bởi các quy tắc, tôi hy vọng.)

Phiên bản dài hơn một chút (72 + 3 = 75 byte) này in trên một dòng mới mỗi giây:

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

Cả hai điều này đòi hỏi bạn phải ở múi giờ UTC. Trên Linux, bạn có thể đạt được điều này bằng cách đặt TZbiến môi trường. Ví dụ TZ= python.


2

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

Cảm ơn Jo King đã gợi ý -alá cờ! Kiểm tra câu trả lời của họ quá.

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

Hãy thử trực tuyến! (nhưng bạn sẽ phải chờ thời gian chờ 60 giây).

Tôi đã sử dụng một tính năng của> <> mà trước đây tôi chưa bao giờ cần: mã này yêu cầu cờ -t.0125, đặt tốc độ thực hiện thành 0,0125 giây mỗi tích tắc, hoặc 80 tích tắc mỗi giây. Ngoài ra còn có -acờ, làm cho khoảng trắng được tính là một đánh dấu (trong một số trường hợp - trình thông dịch hơi kỳ lạ về điều này).

Về cơ bản, mã giữ một bộ đếm tăng lên mỗi khi cá đi qua vòng lặp và phần còn lại của vòng lặp chuyển đổi bộ đếm thành hh:mm:ssđịnh dạng và in nó. Vòng lặp mất đúng 80 tick.

Điều này sẽ hoạt động trên lý thuyết, nhưng trong thực tế, mỗi đánh dấu dài hơn 0,0125 giây, vì thời gian tính toán. Thay đổi\\ dòng thứ hai để <<đưa ra thời gian chính xác hơn trên TIO.

Bạn cũng có thể xem mã hoạt động tại sân chơi cá , ngoại trừ việc trình thông dịch này xử lý khoảng trắng hơi khác so với trình thông dịch chính thức. Ngoài ra, bạn có thể xóa các cờ trên TIO để làm cho mã chạy ở tốc độ cao nhất, để xác minh hành vi nhiều lần sau một phút.


-1 byte bằng cách thay thế v trong dòng đầu tiên bằng \!và loại bỏ hai trong số thêm <. Một vài byte khác nếu bạn sử dụng -acờ, tính khoảng trắng và bỏ qua các hướng dẫn dưới dạng dấu tick
Jo King

@JoKing, -aLá cờ cho tôi chơi golf thêm một chút nữa, cảm ơn bạn! Tôi nghĩ bạn cũng có thể sử dụng \!thủ thuật trong mã của mình: Hãy thử trực tuyến!
Không phải là một cái cây

2

Java 8, chương trình đầy đủ, 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);}}

Hãy thử ở đây (hết thời gian sau 60 giây, vì vậy tôi đã đặt chế độ ngủ thành 1 để xem thêm đầu ra).

Giải trình:

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, hàm, 94 byte

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

Hãy thử ở đây (hết thời gian sau 60 giây, vì vậy tôi đã đặt chế độ ngủ thành 1 để xem thêm đầu ra).

Giải trình:

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

Đây là một gif nhỏ để xem nó hoạt động như dự định khi 1000 ms được sử dụng:

nhập mô tả hình ảnh ở đây


2

PHP, 59 48 byte

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

Lấy cảm hứng từ câu trả lời của Darren H .

Phiên bản cũ :

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

Các thẻ mở PHP có thể được bỏ qua trong câu trả lời giúp bạn tiết kiệm 6 byte.
Daniel W.

Suy nghĩ tuyệt vời, nhưng 3600 cần phải là 86400 nếu không bộ đếm bắt đầu lúc 23:00:00 vì vậy thật không may bạn có được một byte, mặc dù vậy vẫn đánh bại tôi bằng 9!
Darren H

@DarrenH Tôi nghĩ nó phụ thuộc vào địa phương của bạn, tôi đã không nghĩ về điều đó. Tôi đang ở GMT + 1, đó là lý do tại sao tôi đã thêm 3600, nhưng tôi đoán với người Anh, bạn có thể loại bỏ -3600hoàn toàn, sẽ tiết kiệm được 5 byte.
roberto06

1

Shell , 177 byte

Lưu ý rằng đây không hoàn toàn phù hợp POSIX vì nó sử dụng date +%s, đây là một bản datemở rộng phổ biến .

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

7
Thông thường, bạn nên cho mọi người cơ hội trả lời thử thách của mình trước khi tự trả lời. Tôi đề nghị một tuần vì một số chỉ có thể ở đây vào những thời điểm nhất định trong tuần.
Adám

1
@ Adám Tôi chưa chấp nhận câu trả lời của mình và tại thời điểm tôi đăng các câu trả lời ngắn hơn nhiều (như của bạn) đã được gửi.
MarkWeston

1

Ruby, 192 117 byte (Tín dụng cho 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

Làm thế nào nó hoạt động?

Sẽ sử dụng phiên bản mở rộng (Chuyển đổi theo thời gian được cung cấp dưới dạng một chức năng riêng biệt và sử dụng định dạng đầu ra khác nhau):

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

6
Chào mừng bạn đến với trang web! Mỗi câu trả lời cho một thử thách golf-code phải được đánh gôn. Ít nhất bạn nên xóa các khoảng trắng vô dụng và sử dụng tên biến 1 ký tự. Điều đó sẽ giúp bạn có được khoảng 120 byte và sử dụng printfthay vì putscó thể tiết kiệm thêm một vài byte: Hãy thử trực tuyến! . Chúc bạn chơi golf vui vẻ trên PPCG!
Dada

1

APL NARS, 109 63 57 ký tự

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

3 + 3 + 48 + 3 = 57 (cũng thấy các giải pháp Apl khác)

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

chuyển đổi INT ⍵ trong chuỗi các chữ số theo cách nếu chiều dài của chuỗi đó là 1 hơn thêm một '0' phía trước chuỗi

{∊⍵,¨':: '}

kết hợp mảng trong với mảng '::'

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 

1

Mã máy x86-64 (cuộc gọi hệ thống Linux): 78 byte

Thời gian quay vòng RDTSC , sys_writegọi hệ thống Linux .

x86-64 không cung cấp một cách thuận tiện để truy vấn tần số "đồng hồ tham chiếu" RDTSC trong thời gian chạy. Bạn có thể đọc MSR (và thực hiện phép tính dựa trên đó) , nhưng yêu cầu chế độ kernel, hoặc root + open /dev/cpu/%d/msr, vì vậy tôi quyết định biến tần số thành hằng số thời gian xây dựng. (Điều chỉnhFREQ_RDTSC khi cần thiết: mọi hằng số 32 bit sẽ không thay đổi kích thước của mã máy)

Lưu ý rằng CPU x86 trong vài năm đã cố định tần số RDTSC để có thể sử dụng làm nguồn thời gian, không phải là bộ đếm hiệu suất chu kỳ xung nhịp lõi trừ khi bạn thực hiện các bước để tắt thay đổi tần số. (Có bộ đếm hoàn hảo thực tế để đếm chu kỳ CPU thực.) Thông thường, nó đánh dấu ở tần số nhãn danh nghĩa, ví dụ 4.0GHz cho i7-6700k của tôi bất kể turbo hay tiết kiệm điện. Dù sao, thời gian chờ bận này không phụ thuộc vào mức trung bình tải (như vòng lặp trễ được hiệu chỉnh) và cũng không nhạy cảm với việc tiết kiệm năng lượng của CPU.

Mã này sẽ hoạt động cho mọi x86 với tần số tham chiếu dưới 2 ^ 32 Hz, tức là lên tới ~ 4,29 GHz. Ngoài ra, 32 dấu thời gian thấp sẽ bao trùm toàn bộ trong 1 giây, do đó tôi cũng phải xem xét edx32 bit cao của kết quả.

Tóm tắt :

đẩy 00:00:00\nvào ngăn xếp. Sau đó, trong một vòng lặp:

  • sys_write cuộc gọi hệ thống
  • Vòng lặp ADC qua các chữ số (bắt đầu bằng chữ số cuối cùng) để tăng thời gian thêm 1. Bao bọc / thực hiện được xử lý bằng cmp/ cmov, với kết quả CF cung cấp giá trị thực hiện cho chữ số tiếp theo.
  • rdtsc và tiết kiệm thời gian bắt đầu.
  • quay rdtsccho đến khi delta là> = tick mỗi giây của tần số RDTSC.

Danh sách 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.

Không chú ý đến pausehướng dẫn để tiết kiệm năng lượng đáng kể: điều này làm nóng một lõi lên ~ 15 độ C mà không có pause, nhưng chỉ bằng ~ 9 với pause. (Trên Skylake, nơi pausengủ trong ~ 100 chu kỳ thay vì ~ 5. Tôi nghĩ rằng nó sẽ tiết kiệm hơn nếu rdtsckhông phải là chậm vì vậy CPU không hoạt động nhiều thời gian).


Phiên bản 32 bit sẽ ngắn hơn một vài byte, ví dụ: sử dụng phiên bản 32 bit này để đẩy chuỗi 00: 00: 00 \ n ban đầu.

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

Và cũng sử dụng 1 byte dec edx. Các int 0x80hệ thống gọi ABI sẽ không sử dụng esi / edi, vì vậy các thiết lập đăng ký cho syscall vs lodsb / STOSB có thể đơn giản hơn.


Tôi có thể đã sử dụng một nanosleepcuộc gọi hệ thống, nhưng điều này thú vị hơn. Với root trên Linux, có thể đọc đúng MSR và lập trình lấy tần số RDTSC.
Peter Cordes

1

q / kdb + , 40 byte

Dung dịch:

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

Thí dụ:

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

Giải trình:

Có ba lệnh đang được thực hiện ở đây:

  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

Sự cố của chức năng hẹn giờ:

.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

Tiền thưởng:

Thay thế 1 cho 41 byte :

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

Thay thế 2 cho 26 + 7 byte = 33 byte

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

và thêm -t 1000làm đối số cho nhị phân q.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.