ติดตั้ง Simple Stopwatch


25

ท้าทาย

งานของคุณคือการเขียนโปรแกรมที่ครั้งหนึ่งวินาที (รวมถึงทันทีเมื่อโปรแกรมของคุณเริ่ม) พิมพ์เวลาที่ผ่านไปจากเวลาที่โปรแกรมของคุณเริ่มต้น

กฎระเบียบ

  • เวลาจะต้องพิมพ์ในhh:mm:ssรูปแบบ (ศูนย์นำหน้าสำหรับค่าตัวเลขหลักเดียว)
  • การประทับเวลาจะต้องคั่นด้วย CR, LF หรือ CRLF (ไม่มีช่องว่างนำหน้า)
  • เวลาใหม่จะต้องปรากฏทุกวินาที (stdout ไม่สามารถบัฟเฟอร์เป็นเวลาหนึ่งวินาที)
  • พฤติกรรมของโปรแกรมหากเรียกใช้ผ่าน 23:59:59 ไม่ได้กำหนด
  • คุณสามารถใช้sleep(1)แม้ว่าวินาทีที่เฉพาะเจาะจงอาจถูกข้ามเมื่อใดก็ตามที่ค่าใช้จ่ายในการพิมพ์คำนวณวนรอบ ฯลฯ สะสมเป็นวินาที

ตัวอย่างผลลัพธ์:

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

โปรดทราบว่า00:00:03หายไปที่นี่เนื่องจากการประมวลผลค่าใช้จ่าย ค่าที่ข้ามจริง (ถ้ามี) ขึ้นอยู่กับการใช้งานและ / หรือระบบ

การใช้งานอ้างอิงใน C: (ระบบที่รองรับ 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);
    }
}

เกณฑ์การชนะ

นี่คือรหัสที่สั้นที่สุดในหน่วยไบต์ชนะ!


หมายเหตุสำหรับความท้าทายในภายหลังการชี้แจงในความคิดเห็นเป็นสิ่งที่ไม่ดี การอ้างอิง
user202729

คำตอบ:


9

MATL , 17 16 ไบต์

`Z`12L/13XOD1Y.T

ลองที่MATL Online!

มันทำงานอย่างไร

`         % 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
คุณตอบคำถามนี้ในโลก 37 นาทีได้อย่างไรหลังจากที่มันถูกปิด? o_O โทษการแคช
Mr. Xcoder

9
@ Mr.Xcoder เมื่อเร็ว ๆ นี้ฉันได้เรียนรู้การใช้ Force
Luis Mendo เมื่อ

29

ภาษาสคริปต์การทำงานของ Flashpoint  174  171 ไบต์

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"

ในการดำเนินการ:

158 ไบต์หากครั้งก่อนหน้าถูกเขียนทับในครั้งถัดไป:

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

ในทางเทคนิคแล้วไม่มีการคืนรถถูกนำมาใช้ดังนั้นฉันไม่แน่ใจว่ารุ่นนี้ จำกัด เฉพาะกฎหรือไม่


5
ฉันไม่ได้คาดหวังจุดวาบไฟการทำงาน
Polyducks

10
@Polyducks ไม่มีใครคาดว่าจุดวาบไฟการดำเนินงาน
Pureferret


ตั้งแต่ใน Unix, CR จะเขียนทับเส้นฉันคิดว่าคำตอบที่สองได้รับการตรวจสอบโดย 'CR, LF หรือ CRLF ได้รับอนุญาต'
Stan Strum

1
@StanStrum อย่างน้อยใน Ubuntu ของฉันCRจะไม่เขียนทับเส้น ในความเป็นจริงCRLF, LFCRและLFมีความหมายเทียบเท่าทั้งหมด

13

Bash + coreutils, 28 26 ไบต์

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

อักขระที่ไม่สามารถพิมพ์ได้ระหว่าง+และ%คือESCไบต์

สิ่งนี้ตั้งเวลาของระบบเป็น 00:00:00จึงต้องใช้สิทธิ์รูท นอกจากนี้ยังอนุมานว่าเขตเวลาเป็น UTC และไม่มีกระบวนการอื่นใดที่จะรบกวนการทำงานของนาฬิการะบบ

แต่ละช่วงเวลาใหม่จะรีเซ็ตเทอร์มินัลดังนั้นจึงเขียนทับช่วงเวลาก่อนหน้า


Bash + coreutils, 38 29 ไบต์

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

ข้อ จำกัด เช่นเดียวกับก่อนนำไปใช้ เวลาใหม่แต่ละครั้งจะปรากฏในบรรทัดใหม่


เนื่องจากมันไม่เปลี่ยน bytecount ฉันจะแยกส่วนแรกdateจากส่วนที่เหลือด้วย linefeed เล็ก ๆ ที่ดี แต่มันอาจจะดีเกินไปสำหรับคนที่สามารถหาวิธีแก้ปัญหาที่สองของคุณได้> :-(
Aaron

date -s0พิมพ์เวลาใหม่ไปที่ STDOUT ฉันใช้ไพพ์เพื่อปิดเสียงเอาต์พุตนั้น
เดนนิส

โอ้ใช่แล้วขอบคุณสำหรับคำอธิบาย!
แอรอน

5

APL (Dyalog Unicode) , 51 ไบต์

โปรแกรมร่างกายเต็ม

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

ลองออนไลน์! (กด Ctrl + Enter เพื่อเริ่มและอีกครั้งเพื่อหยุด)

⎕AIccount ฉัน nformation (ID ผู้ใช้เวลาคำนวณเวลาการเชื่อมต่อเวลา keying)

s← กำหนดให้s(สำหรับsทาร์ตเวลา)
⎕AI-s ลบsจาก⎕AI

3⊃ เลือกองค์ประกอบที่สาม (เชื่อมต่อเวลาเป็นมิลลิวินาที)
0 60 60 1E3⊤แปลงเป็น radix ผสมนี้
3↑ ใช้เวลา 3 ครั้งแรก (ลดลงมิลลิวินาที)
100+ หนึ่งร้อยเพิ่มไปยังแต่ละ (เพื่อศูนย์แผ่น)
':'@1∘⍕¨ แก้ไขด้วยลำไส้ใหญ่ที่ตัวละครแรกของการเป็นตัวแทนสตริงของแต่ละ
ϵ nlist (แบน)
1↓ ปล่อยโคลอนแรก (และพิมพ์โดยนัยถึง stdout)

⎕DL 1D E L Ay หนึ่งวินาที

→2 ไปที่หมายเลขบรรทัดสอง


5

R , 59 44 ไบต์

Fใน R เป็นค่าเริ่มต้นFALSEแต่เป็นตัวแปรปกติและสามารถกำหนดใหม่ได้ เมื่อนำมาใช้ในการคำนวณจะถูกบังคับให้FALSE 0ขอดังนั้นผลตอบแทนF+1 1เรากำหนดFให้เป็นจัดF+1รูปแบบเป็นอย่างดีพิมพ์และรอหนึ่งวินาที ดำเนินต่อไปเรื่อย ๆ

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

ไม่ทำงานบน TIO (เนื่องจากขาดhmsแพ็คเกจ) แต่นี่เป็นตัวอย่างผลลัพธ์จากเครื่องของฉัน:

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 + sleep + date, 50 49 47 46 45 41 ไบต์

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

หากต้องการใช้เวลาตักให้กด ^ C อย่างรวดเร็วแล้วรันสิ่งนี้จากนั้นรันใหม่อีกครั้ง:

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

วิธีรีเซ็ต:

s=0; unset laps

ไวยากรณ์ $ [s ++] ดูเหมือนว่าจะยังคงใช้งานได้ แต่ไม่มีเอกสาร (AFAICS) อีกต่อไปในbashหน้าคน และมันก็ยังสั้นกว่าการใช้ for ((... )) ลูปเมื่อฉันลบเครื่องหมายคำพูดรอบ ๆ


AFAICT, $[]เป็นเลิก / ไม่มีเอกสาร $(())แต่ยังคงได้รับการสนับสนุนรูปแบบของ ฉันไม่แน่ใจว่าเป็นคำตอบที่ใช้กันทั่วไปในสนามกอล์ฟหรือไม่ แต่กฎทั่วไปก็คือรหัสของคุณต้องใช้ล่ามอย่างน้อยหนึ่งรุ่นสำหรับภาษาของคุณ IMO ไม่เป็นไร
Peter Cordes

s=0ไม่จำเป็นต้องทดแทนเลขคณิตจะปฏิบัติต่อตัวแปรตั้งค่าเป็น0 -uไม่จำเป็นเช่นกันหากคุณเพียงแค่สมมติเขตเวลาเริ่มต้น (UTC)
เดนนิส

-u เป็นสิ่งจำเป็นในการฉันเครื่อง :)
Will Crawford

4

Swift , 144 ไบต์

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

คำอธิบาย

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 ไบต์

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


2
ชั่วโมงไม่เริ่มต้นที่ 0 สำหรับฉัน การเปลี่ยนแปลงออฟเซ็ตขึ้นอยู่กับเขตเวลาของนาฬิการะบบ (Win10)
Luke

@LukeS อ้าวคงแล้ว!
darrylyeo

4

Matlab (R2016b) ขนาด 50 ไบต์

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

คำอธิบาย:

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

รุ่นอื่น (50 ไบต์เช่นกัน: P):

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

ยินดีต้อนรับสู่เว็บไซต์! :)
DJMcMayhem

ขอบคุณเพื่อน:)
Thiago Oleinik

@LuisMendo ขอบคุณสำหรับคำแนะนำ แต่ฉันไม่เข้าใจ ... ในตัวอย่างของคุณตัวแปรtคืออะไร นอกจากนี้อินพุตยังdatestrอยู่ในอีกหลายวันดังนั้นฉันต้องหารด้วย86400ซึ่งจะเพิ่มจำนวนไบต์ทีละสอง ...
Thiago Oleinik

3

Julia 0.6 , 75 68 bytes

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

ลองออนไลน์!

ด้วยการนอนหลับ (1) ที่ได้รับอนุญาตห่วงซ้อนกันแบบง่ายจะสั้นกว่าการใช้วิธีการจัดการเวลาในตัวของ Julias

โซลูชันเก่าโดยไม่ต้องนอนหลับ (1) ใช้ DateTime

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

tคือจำนวนเวลาที่ผ่านไปจาก 'วันที่ 0' ถึงเมื่อโปรแกรมเริ่ม now()-tเป็นเวลาในเวลาหนึ่งซึ่งจัดรูปแบบโดยใช้Dates.format()แล้ว

t0=now(); ...; now()-t0จะให้ผลผลิตแตกต่างของเวลาDates.format()ที่ไม่สามารถใช้ร่วมกับ

Timerระยะเวลาที่ตัวเองไม่ได้เป็นเรื่องที่มีการสร้างใน


3

Python 2 , 85 ไบต์

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

เครดิต

  • ลดลงจาก 89 ไบต์เป็น 88 โดยwnnmaw
  • ลดลงจาก 88 ไบต์เป็น 85 โดยErik the Outgolfer

คุณสามารถบันทึกหนึ่งไบต์โดยแทนที่"%02d:%02d:%02d"ด้วย(":%02d"*3)[1:]
wnnmaw

1
คุณไม่ต้องการ%24พฤติกรรมจะไม่ได้กำหนดหลังจาก23:59:59นั้น
Erik the Outgolfer

@EriktheOutgolfer จุดดีอัปเดตแล้ว
Neil

3

JavaScript (ES6), 88 ไบต์

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

เป็นแนวทางเดียวกันกับคำตอบของ @ darrylyeoแต่ใช้ได้กับเขตเวลาทั้งหมดและใช้วิธีที่แตกต่างกันเล็กน้อยเพื่อให้ได้ 0

[แก้ไข] คำตอบของ Darryl ได้รับการแก้ไขแล้ว แม้ว่าจะยังสั้นกว่านี้


3

> <> , 82 + 7 = 89 ไบต์

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

ลองออนไลน์!

+7 ไบต์สำหรับการใช้แฟล็ก-t.0125เพื่อทำให้แต่ละคำสั่งใช้เวลา 1 / 80th ของวินาที แต่ละวงมี 80 คำแนะนำทำให้แต่ละวงมีความยาวหนึ่งวินาที เนื่องจากเวลาในการคำนวณสิ่งนี้จึงเป็นจริงในทางปฏิบัติอีกต่อไป

จริง ๆ แล้วฉันต้องบัฟเฟอร์ทั้งหมดจนถึง 100 จนกว่าฉันจะเห็นคำตอบของ @Not A Tree ซึ่งมีวิธีที่ดีกว่า 7 ไบต์กว่าฉันเพื่อสร้างชั่วโมงและนาทีตัดต่ำกว่า 80 พวกเขายังเป็นแรงบันดาลใจให้ใช้งาน\/สองครั้ง ต่อวง

มันทำงานอย่างไร

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

โบนัส:

รุ่นหนึ่งบรรทัดที่มีขนาดเท่ากัน 80 + 9 ไบต์:

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

สิ่งนี้ใช้-aแฟล็กเพื่อเพิ่มเห็บสำหรับคำแนะนำที่ข้าม


3

PHP 4+ 70 64 ไบต์

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

PHP 5.3+, 69 63 ไบต์

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

แท็กเปิด PHP สามารถละเว้นได้ในคำตอบที่ช่วยให้คุณประหยัด 6 ไบต์
แดเนียลดับบลิว

2

Python 3 , 112 ไบต์

การสันนิษฐานโดยใช้ความล่าช้า 1 วินาทีถือว่าโอเคแม้ว่าจะไม่ค่อยมีเลยก็ตาม

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

ทำงานในหน้าต่างทันที: คาดว่าจุดความล้มเหลวประมาณ 23 ล้านปี (การแก้จุดลอยตัวล้มเหลว ~ 8.5e9 วัน)


2

เยลลี่ 23 ไบต์

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

ลองออนไลน์!


ใช้งานได้กับเวลาที่สูงกว่า 1 นาทีหรือไม่
H.PWiz

@ H.PWiz ควรรันการทดสอบบางอย่าง แก้ไข: ดูเหมือนว่าการจ่ายเงินปันผลผิดสำหรับชั่วโมง ... แก้ไขเพื่อประหยัดเล็กน้อย!
Erik the Outgolfer

2

AWK , 110 87 86 ไบต์

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

ไม่ทำงานใน TIO


ดูเหมือนว่าโปรแกรมของคุณจะไม่พิมพ์00:00:00ขณะที่เริ่มทำงาน
user202729

ซ่อมมัน. ขอบคุณ
Noskcaj

2

APL (Dyalog)ขนาด 37 ไบต์

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

ลองออนไลน์!

โปรแกรมเต็มรูปแบบ

ค่อนข้างคล้ายกับคำตอบของAdám แต่เขียนได้อย่างอิสระและใช้วิธีการที่ไม่ใช่⎕AIพื้นฐาน


2

Bash + coreutils + GNU date, 50 bytes

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

แรงบันดาลใจจาก @Dennis โซลูชันนี้ไม่ต้องการเวลาในการเปลี่ยนแปลง มันจัดเก็บออฟเซ็ตเริ่มต้นจากตอนนี้สู่ยุค UNIX (1 ม.ค. 1970 00:00:00 UTC) ใน 'o' แล้วแสดง [-ud options] (เวลาปัจจุบัน - ออฟเซ็ต) ในวันที่ UTC แต่ เฉพาะ [+% X ตัวเลือก] HH: MM: SS สิ่งนี้ควรทำงานในประเทศที่เขตเวลาปัจจุบันไม่ใช่ UTC


2

ทำความสะอาด , 173 172 168 ไบต์

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]

อันนี้ใช้ได้เฉพาะในบันเดิล Windows Clean

เพิ่ม 3 ไบต์หากคุณต้องการให้ทำงานภายใต้ Linux เช่นเดียวกับ Clean's CLK_PER_TICK :== 1000000on * nix หากคุณต้องการให้เป็นแพลตฟอร์มข้ามให้เพิ่ม 8 ไบต์แทนตามที่คุณต้องการใช้CLK_PER_TICKแทนค่าที่ตั้งไว้ ( ลิงก์ TIO ใหญ่กว่าเนื่องจากด้านบน )

ลองออนไลน์!


2

Python 2 , 69 + 3 ( TZ=) = 72 ไบต์

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

สิ่งนี้จะทำงานในการวนซ้ำอย่างต่อเนื่องโดยไม่ต้องนอนหลับปรับปรุงเวลาในบรรทัดเดียวกันแทนที่จะพิมพ์บรรทัดใหม่ในแต่ละวินาที (หวังว่าจะได้รับอนุญาตตามกฎฉันหวังว่า)

รุ่นที่ยาวกว่านี้เล็กน้อย (72 + 3 = 75 ไบต์) พิมพ์บนบรรทัดใหม่ทุกวินาทีแทน:

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

ทั้งสองอย่างนี้คุณต้องอยู่ในเขตเวลา UTC บน Linux คุณสามารถทำได้โดยการตั้งค่าTZตัวแปรสภาพแวดล้อม TZ= pythonเช่น


2

> <> , 106 ไบต์ 82 + 9 = 91 ไบต์

ขอบคุณ Jo King ที่แนะนำ-aธง! ลองดูคำตอบของพวกเขาด้วย

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

ลองออนไลน์! (แต่คุณจะต้องรอให้หมดเวลา 60 วินาที)

ฉันต้องใช้ฟีเจอร์> <> ที่ฉันไม่เคยต้องการมาก่อน: รหัสนี้ต้องใช้การตั้งค่าสถานะ-t.0125ซึ่งกำหนดความเร็วการดำเนินการเป็น 0.0125 วินาทีต่อหนึ่งขีดหรือ 80 ขีดต่อวินาที นอกจากนี้ยังมี-aธงซึ่งทำให้ช่องว่างนับว่าเป็นเห็บ (ในบางกรณี - ล่ามค่อนข้างแปลกเกี่ยวกับเรื่องนี้)

โดยพื้นฐานแล้วโค้ดจะเก็บตัวนับที่เพิ่มขึ้นทุกครั้งที่ปลาผ่านลูปและส่วนที่เหลือของลูปจะแปลงตัวนับเพื่อจัดhh:mm:ssรูปแบบและพิมพ์ การวนซ้ำนั้นใช้เวลา 80 ขีด

สิ่งนี้ควรใช้งานได้ในทางทฤษฎี แต่ในทางปฏิบัติแต่ละเห็บมีความยาวมากกว่า 0.0125 วินาทีเล็กน้อยเนื่องจากเวลาในการคำนวณ การเปลี่ยน\\บนบรรทัดที่สองเป็น<<ให้การจับเวลาที่แม่นยำยิ่งขึ้นบน TIO

นอกจากนี้คุณยังสามารถดูรหัสในการดำเนินการที่สนามเด็กเล่นปลายกเว้นว่าล่ามนี้ปฏิบัติช่องว่างต่างจากนักแปลอย่างเป็นทางการเล็กน้อย อีกทางหนึ่งคุณสามารถลบการตั้งค่าสถานะบน TIO เพื่อให้โค้ดทำงานด้วยความเร็วสูงสุดเพื่อตรวจสอบพฤติกรรมหลังจากผ่านไปหนึ่งนาที


-1 ไบต์โดยการเปลี่ยนโวลต์ในบรรทัดแรกด้วยและลบสองพิเศษ\! <อีกสองสามไบต์ถ้าคุณใช้-aธงซึ่งนับช่องว่างและข้ามคำแนะนำเป็นเห็บ
Jo King

@ โจกิ้ง-aธงให้ฉันตีกอล์ฟเพิ่มอีกหน่อยขอบคุณ! ฉันคิดว่าคุณสามารถใช้\!เคล็ดลับในรหัสของคุณได้เช่นกันลองออนไลน์!
ไม่ใช่ต้นไม้

2

Java 8, โปรแกรมเต็มรูปแบบ, 150 ไบต์

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

ลองที่นี่ (หมดเวลาหลังจาก 60 วินาทีดังนั้นฉันได้ตั้งค่าสลีปเป็น 1 เพื่อดูผลลัพธ์เพิ่มเติม)

คำอธิบาย:

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, ฟังก์ชัน, 94 ไบต์

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

ลองที่นี่ (หมดเวลาหลังจาก 60 วินาทีดังนั้นฉันได้ตั้งค่าสลีปเป็น 1 เพื่อดูผลลัพธ์เพิ่มเติม)

คำอธิบาย:

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

นี่คือ gif ขนาดเล็กเพื่อดูว่าทำงานได้ตามที่ตั้งใจเมื่อใช้ 1,000 ms:

enter image description here


2

PHP, 59 48 ไบต์

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

แรงบันดาลใจจากคำตอบของ Darren Hคำตอบของคาร์เรนเอช

รุ่นเก่า :

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

แท็กเปิด PHP สามารถละเว้นได้ในคำตอบที่ช่วยให้คุณประหยัด 6 ไบต์
แดเนียลดับบลิว

ความคิดที่ดี แต่ 3600 นั้นจำเป็นต้องเป็น 86400 มิฉะนั้นตัวนับจะเริ่มเวลา 23:00:00 โชคไม่ดีที่คุณได้รับไบต์ แต่ก็ยังเอาชนะฉันได้ถึง 9 คน!
Darren H

@ Darren ฉันคิดว่ามันขึ้นอยู่กับสถานที่ของคุณฉันไม่ได้คิดอย่างนั้น ฉันอยู่ใน GMT + 1 นั่นคือเหตุผลที่ฉันเพิ่ม 3600 แต่ฉันเดาว่าสำหรับคนอังกฤษคุณสามารถลบ-3600ทั้งหมดซึ่งจะบันทึก 5 ไบต์
roberto06

1

เปลือกขนาด 177 ไบต์

ขอให้สังเกตว่านี่ไม่ใช่ POSIX ทั้งหมดเพราะมันใช้ date +%sซึ่งเป็นการdateขยายตัวทั่วไป

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
โดยปกติคุณควรให้โอกาสผู้คนในการตอบคำถามก่อนที่จะตอบคำถามด้วยตัวเอง ฉันแนะนำหนึ่งสัปดาห์เพราะบางคนอาจมาที่นี่ในบางช่วงเวลาระหว่างสัปดาห์
อดัม

1
@ Adámฉันไม่ได้รับคำตอบของฉันและในเวลาที่ฉันโพสต์คำตอบที่สั้นกว่ามาก (เช่นคุณ) ถูกส่ง
MarkWeston

1

Ruby, 192 117 ไบต์ (เครดิตถึง 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

มันทำงานยังไง?

จะใช้เวอร์ชันขยาย (การแปลงเป็นเวลาจะให้เป็นฟังก์ชันแยกต่างหากและใช้รูปแบบเอาต์พุตอื่น):

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
ยินดีต้อนรับสู่เว็บไซต์! คำตอบของการแข่งขันกอล์ฟต้องตอบคำถามทุกข้อ อย่างน้อยคุณควรลบช่องว่างที่ไม่มีประโยชน์ออกและใช้ชื่อตัวแปร 1 ตัว คุณจะได้รับประมาณ 120 ไบต์และใช้printfแทนputsสามารถบันทึกเพิ่มเติมอีกไม่กี่ไบต์: ลองออนไลน์! . มีความสุขกับการเล่นกอล์ฟบน PPCG!
Dada

1

APL NARS, 109 63 57 ตัวอักษร

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

3 + 3 + 48 + 3 = 57 (เห็นโซลูชั่น Apl อื่น ๆ ด้วย)

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

แปลง INT ⍵ในสตริงของตัวเลขด้วยวิธีหากความยาวของสตริงนั้นคือ 1 มากกว่าเพิ่มหนึ่ง '0' ไว้ข้างหน้า

{∊⍵,¨':: '}

รวมอาเรย์ใน⍵กับอาเรย์ '::'

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

รหัสเครื่อง x86-64 (การเรียกระบบ Linux): 78 ไบต์

RDTSCปั่นวน , Linuxsys_writeเรียกระบบ

x86-64 ไม่ได้ให้วิธีที่สะดวกในการค้นหาความถี่ "นาฬิกาอ้างอิง" ของ RDTSC ในขณะใช้งาน คุณสามารถอ่าน MSR (และทำการคำนวณตามนั้น)แต่ต้องใช้โหมดเคอร์เนลหรือรูท + เปิด/dev/cpu/%d/msrดังนั้นฉันตัดสินใจที่จะทำให้ความถี่เป็นค่าคงที่เวลาการสร้าง (ปรับFREQ_RDTSCตามความจำเป็น: ค่าคงที่ 32 บิตใด ๆ จะไม่เปลี่ยนขนาดของรหัสเครื่อง)

โปรดทราบว่า x86 CPUs เป็นเวลาหลายปีมีความถี่ RDTSC คงที่ดังนั้นจึงสามารถใช้งานเป็นแหล่งเวลาได้ ได้ตัวนับประสิทธิภาพรอบนาฬิกาหลักยกเว้นว่าคุณทำตามขั้นตอนเพื่อปิดการเปลี่ยนแปลงความถี่ (มีตัวนับที่สมบูรณ์แบบจริงสำหรับการนับรอบ CPU จริง) โดยปกติแล้วมันจะทำเครื่องหมายที่ความถี่สติกเกอร์เล็กน้อยเช่น 4.0GHz สำหรับ i7-6700k ของฉันโดยไม่คำนึงถึงเทอร์โบหรือการประหยัดพลังงาน อย่างไรก็ตามเวลารอไม่ว่างนี้ไม่ได้ขึ้นอยู่กับค่าเฉลี่ยของการโหลด (เช่นการวนรอบล่าช้าที่ปรับเทียบแล้ว) และยังไม่ไวต่อการประหยัดพลังงานของ CPU

รหัสนี้จะทำงานกับ x86 ใด ๆ ที่มีความถี่อ้างอิงต่ำกว่า 2 ^ 32 Hz หรือมากถึง ~ 4.29 GHz นอกเหนือจากนั้นการบันทึกเวลาต่ำ 32 รอบจะห่อหุ้มตลอดเวลาใน 1 วินาทีดังนั้นฉันต้องดูedxผลลัพธ์ 32 บิตสูงเช่นกัน

สรุป :

ดัน00:00:00\nสแต็ค จากนั้นในวง:

  • sys_write การเรียกระบบ
  • ADC-loop เหนือตัวเลข (เริ่มต้นด้วยครั้งสุดท้าย) เพื่อเพิ่มเวลาโดย 1 การตัด / ดำเนินการจัดการด้วยcmp/ cmovด้วยผลลัพธ์ CF ที่ให้การพกพาสำหรับหลักถัดไป
  • rdtsc และประหยัดเวลาเริ่มต้น
  • หมุนrdtscจนกระทั่งเดลต้าคือ> = ติ๊กต่อวินาทีของความถี่ RDTSC

รายชื่อ 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.

บรรทัดเหล่าpauseคำแนะนำเพื่อประหยัดพลังงานอย่างมีนัยสำคัญ: ร้อนนี้หลักเพิ่มขึ้น ~ 15 องศาเซลเซียสโดยไม่ต้องpauseแต่เพียงโดย ~ 9 pauseด้วย (บน Skylake ซึ่งpauseนอนประมาณ ~ 100 รอบแทนที่จะเป็น ~ 5 ฉันคิดว่ามันจะประหยัดได้มากกว่าหากrdtscไม่ช้าเช่นกันดังนั้น CPU จึงไม่ได้ทำอะไรมากมาย)


รุ่น 32 บิตจะสั้นกว่าสองสามไบต์เช่นใช้เวอร์ชั่น 32 บิตเพื่อดันสตริง 00: 00: 00 \ n เริ่มต้น

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

และยังมีการใช้ dec edx1 int 0x80สายระบบ ABI จะไม่ใช้ ESI / EDI เพื่อให้การตั้งค่าลงทะเบียนสำหรับ syscall กับ lodsb / stosb อาจจะง่าย


ฉันสามารถใช้การnanosleepเรียกของระบบ แต่สิ่งนี้น่าสนใจยิ่งกว่า ด้วยรูทบน Linux ทำให้สามารถอ่าน MSR ที่ถูกต้องและรับความถี่ RDTSC โดยทางโปรแกรม
Peter Cordes

1

Q / kdb + , 40 ไบต์

วิธีการแก้:

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

ตัวอย่าง:

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

คำอธิบาย:

มีสามคำสั่งที่ถูกดำเนินการที่นี่:

  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

รายละเอียดของฟังก์ชั่นจับเวลา:

.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

โบนัส:

ทางเลือก 1 สำหรับ41 ไบต์ :

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

ทางเลือก 2 สำหรับ26 + 7 ไบต์ = 33 ไบต์

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

และเพิ่ม-t 1000เป็นอาร์กิวเมนต์ไปยัง q ไบนารี่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.