Tantangan
Tugas Anda adalah menulis sebuah program yang, sekali sedetik (termasuk segera ketika program Anda dimulai), mencetak waktu yang telah berlalu sejak program Anda dimulai.
Aturan
- Waktu harus dicetak dalam
hh:mm:ss
format. (memimpin nol untuk nilai satu digit) - Prangko waktu harus dipisahkan oleh CR, LF, atau CRLF. (tidak ada spasi putih terkemuka)
- Waktu baru harus muncul setiap detik. (stdout tidak dapat disangga selama sedetik)
- Perilaku program jika dijalankan melewati 23:59:59 tidak ditentukan.
- Anda dapat menggunakan
sleep(1)
bahkan jika detik tertentu dapat dilewati setiap kali overhead untuk mencetak, menghitung, mengulang, dll terakumulasi menjadi satu detik.
Contoh output:
00:00:00
00:00:01
00:00:02
00:00:04
00:00:05
⋮
Perhatikan bahwa 00:00:03
tidak ada di sini karena memproses overhead. Nilai-nilai yang dilewati sebenarnya (jika ada) tentu saja tergantung pada implementasi dan / atau sistem.
Implementasi referensi dalam C: (hanya sistem yang kompatibel dengan 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);
}
}
Kriteria menang
Ini adalah kode-golf , kode terpendek dalam byte menang!
Jawaban:
MATL ,
1716 byteCobalah di MATL Online!
Bagaimana itu bekerja
sumber
Operasi bahasa scripting Flashpoint ,
174171 byteBeraksi:
158 byte, jika waktu sebelumnya ditimpa oleh waktu berikutnya:
Secara teknis, tidak ada carriage return yang digunakan, jadi saya tidak yakin apakah versi ini terbatas pada aturan.
sumber
CR
tidak akan menimpa baris. Bahkan,CRLF
,LFCR
danLF
semua semantik setara.Bash + coreutils,
2826 byteKarakter yang tidak dapat dicetak antara
+
dan%
merupakan byte ESC .Ini mengatur waktu sistem menjadi 00:00:00 dan karenanya membutuhkan hak akses root. Itu juga mengasumsikan bahwa zona waktu adalah UTC dan bahwa tidak ada proses lain akan mengganggu jam sistem.
Setiap timing baru me-reset terminal, sehingga menimpa yang sebelumnya.
Bash + coreutils,
3829 byteBatasan yang sama seperti sebelumnya berlaku. Setiap timing baru ditampilkan pada baris baru.
sumber
date
dari yang lain dengan linefeed kecil yang bagus. Tapi itu mungkin terlalu baik untuk seseorang yang dapat menemukan solusi seperti solusi kedua Anda> :-(date -s0
mencetak waktu baru untuk STDOUT; Saya menggunakan pipa untuk membungkam output itu.APL (Dyalog Unicode) , 51 byte
Badan program penuh.
Cobalah online! (Tekan Ctrl + Enter untuk memulai, dan lagi untuk berhenti.)
⎕AI
Sebuah ccount Aku NFORMASI (user ID, menghitung waktu, waktu koneksi, keying waktu)s←
menetapkan kes
(untuk s tart waktu)⎕AI-s
kurangis
dari⎕AI
3⊃
pilih elemen ketiga (hubungkan waktu dalam milidetik)0 60 60 1E3⊤
konversikan ke campuran-radix ini3↑
ambil 3 pertama (tetes milidetik)100+
seratus ditambahkan ke masing-masing (untuk pad nol)':'@1∘⍕¨
ubah dengan tanda titik dua pada karakter pertama dari representasi string masing-masing∊
ϵ daftar (ratakan)1↓
jatuhkan usus besar pertama (dan secara implisit cetak ke stdout)⎕DL 1
D e l ay satu detik→2
pergi ke baris nomor duasumber
R ,
5944 byteF
dalam R defaultFALSE
, tetapi ini adalah variabel biasa dan dapat didefinisikan ulang. Ketika digunakan dalam aritmatika,FALSE
dipaksa untuk0
.F+1
Karena itu meminta kembali1
. Kami menetapkanF
untuk menjadiF+1
, memformatnya dengan baik, mencetak, dan menunggu satu detik. Berlanjut tanpa batas.Tidak berfungsi pada TIO (karena kurangnya
hms
paket), tapi inilah contoh keluaran dari mesin saya:sumber
bash + sleep + date,
juga 504947464541 byteUntuk mengambil waktu putaran, tekan ^ C dengan cepat, jalankan ini lalu jalankan kembali di atas:
Untuk mengatur ulang:
Sintaks $ [s ++] tampaknya masih berfungsi, tetapi tidak lagi (AFAICS) didokumentasikan di
bash
halaman manual. Dan itu masih satu byte lebih pendek daripada menggunakan for (()) loop, setelah saya menghapus tanda kutip di sekitarnya.sumber
$[]
adalah bentuk yang sudah usang / tidak terdokumentasi tetapi masih didukung$(())
. Saya tidak yakin apakah itu biasa digunakan dalam jawaban kode-golf, tetapi aturan umumnya adalah bahwa kode Anda hanya harus bekerja pada setidaknya satu versi juru bahasa untuk bahasa Anda. IMO baik-baik saja.s=0
tidak diperlukan, karena substitusi aritmatika akan memperlakukan variabel yang tidak disetel sebagai 0 .-u
juga tidak diperlukan jika Anda hanya mengasumsikan zona waktu default (UTC).Cepat , 144 byte
Penjelasan
sumber
JavaScript (ES6), 99 byte
sumber
Matlab (R2016b), 50 byte
Penjelasan:
Versi alternatif (50 byte juga: P):
sumber
:)
t
? Juga, inputnyadatestr
adalah dalam hitungan hari, jadi saya harus membaginya dengan86400
, yang akan meningkatkan jumlah byte menjadi dua ...Julia 0,6 ,
7568 byteCobalah online!
Dengan tidur (1) diizinkan, simpangan for-loop sederhana lebih pendek daripada menggunakan metode penanganan waktu bawaan Julias.
Solusi lama tanpa tidur (1) menggunakan DateTime
t
adalah jumlah waktu yang berlalu dari 'hari 0' hingga saat program dimulai.now()-t
adalah momen dalam waktu , yang kemudian diformat menggunakanDates.format()
.t0=now(); ...; now()-t0
akan menghasilkan perbedaan waktu , yang tidak dapat digunakan denganDates.format()
.Waktunya sendiri sepele dengan built-in
Timer
.sumber
Python 2 , 85 byte
Kredit
sumber
"%02d:%02d:%02d"
dengan(":%02d"*3)[1:]
%24
, perilaku tidak ditentukan setelah23:59:59
.JavaScript (ES6), 88 byte
Pada dasarnya pendekatan yang sama dengan jawaban @ darrylyeo , tetapi bekerja untuk semua zona waktu dan menggunakan cara yang sedikit berbeda untuk sampai ke 0.
[Sunting] Jawaban Darryl telah diperbaiki. Ini masih lebih pendek.
sumber
> <> , 82 + 7 = 89 byte
Cobalah online!
+7 byte untuk menggunakan flag
-t.0125
untuk membuat setiap instruksi membutuhkan 1/80 detik. Setiap loop memiliki 80 instruksi, membuat setiap loop panjangnya satu detik. Karena waktu perhitungan, ini sebenarnya lebih lama dalam praktek.Aku benar-benar harus penyangga ini semua jalan sampai ke 100 sampai aku melihat @Not A Tree jawaban yang memiliki cara 7 byte yang lebih baik dari saya untuk menghasilkan jam dan menit, pemangkasan di bawah 80. Mereka juga terinspirasi penggunaan
\/
yang dilaksanakan dua kali per loop.Bagaimana itu bekerja
Bonus:
Versi satu baris dengan ukuran yang sama, 80 + 9 byte:
Ini menggunakan
-a
bendera untuk menambahkan kutu untuk instruksi yang dilewati.sumber
PHP 4+,
7064 bytePHP 5.3+,
6963 bytesumber
Python 3 , 112 byte
Dengan asumsi menggunakan penundaan 1 detik tidak apa-apa, bahkan jika (jarang) mungkin melompati satu detik.
sumber
VBA, 90
berjalan di jendela langsung: titik kegagalan yang diharapkan di suatu tempat sekitar 23 juta tahun (resolusi titik mengambang gagal ~ 8,5e9 hari)
sumber
Jelly , 23 byte
Cobalah online!
sumber
AWK ,
1108786 byteTidak berfungsi di TIO.
sumber
00:00:00
pada saat itu dimulai.APL (Dyalog) , 37 byte
Cobalah online!
Program lengkap.
Cukup mirip dengan jawaban Adam, namun ditulis secara independen dan menggunakan pendekatan non-
⎕AI
berbasis.sumber
Bash + coreutils + tanggal GNU, 50 byte
Terinspirasi oleh @ Dennis, solusi ini tidak memerlukan waktu untuk diubah. Menyimpan toko offset awal dari sekarang ke zaman UNIX (1 Jan 1970 00:00:00 UTC), di 'o', dan kemudian menampilkan [-ud opsi] (waktu saat ini - offset), pada tanggal UTC, tetapi hanya [+% X opsi] HH: MM: SS. Ini harus bekerja di negara-negara di mana zona waktu saat ini bukan UTC.
sumber
Bersih ,
173172168 byteYang ini hanya berfungsi di bawah bundel Windows Clean.
Tambahkan 3 byte jika Anda ingin bekerja di Linux, seperti Bersihkan
CLK_PER_TICK :== 1000000
di * nix Jika Anda ingin menggunakan platform silang, tambahkan 8 byte sebagai gantinya, karena Anda harus menggunakanCLK_PER_TICK
alih-alih nilai yang ditetapkan. ( TIO tautan lebih besar karena di atas )Cobalah online!
sumber
Python 2 , 69 + 3 (
TZ=
) = 72 byteIni berjalan dalam loop terus menerus, tanpa tidur, memperbarui waktu pada baris yang sama daripada mencetak baris baru setiap detik. (Masih diizinkan oleh aturan, saya harap.)
Versi yang sedikit lebih panjang ini (72 + 3 = 75 byte) dicetak pada baris baru setiap detik sebagai gantinya:
Kedua hal ini mengharuskan Anda berada di zona waktu UTC. Di Linux Anda dapat mencapai ini dengan mengatur
TZ
variabel lingkungan. MisalnyaTZ= python
.sumber
> <> ,
106 byte82 + 9 = 91 byteTerima kasih kepada Jo King karena menyarankan
-a
bendera! Lihat jawaban mereka juga.Cobalah online! (tetapi Anda harus menunggu waktu tunggu 60 detik).
Saya harus menggunakan fitur> <> yang belum pernah saya butuhkan sebelumnya: kode ini memerlukan flag
-t.0125
, yang menetapkan kecepatan eksekusi menjadi 0,0125 detik per kutu, atau 80 kutu per detik. Ada juga-a
benderanya, yang menjadikan spasi putih dihitung sebagai tanda centang (dalam beberapa kasus - penerjemah agak aneh tentang ini).Pada dasarnya, kode menyimpan penghitung yang bertambah setiap kali ikan melewati loop, dan sisa dari loop mengubah penghitung untuk
hh:mm:ss
memformat dan mencetaknya. Loop ini membutuhkan 80 kutu.Ini seharusnya bekerja secara teori, tetapi dalam praktiknya, setiap centang sedikit lebih lama dari 0,0125 detik, karena waktu perhitungan. Mengubah
\\
baris kedua untuk<<
memberikan pengaturan waktu yang lebih akurat pada TIO.Anda juga dapat menonton kode ini dalam aksi di taman bermain ikan , kecuali bahwa juru bahasa ini memperlakukan ruang putih sedikit berbeda dari juru bahasa resmi. Atau, Anda dapat menghapus bendera di TIO untuk membuat kode berjalan dengan kecepatan tinggi, untuk memverifikasi perilaku selama satu menit setelah satu menit.
sumber
\!
dan menghapus dua ekstra<
. Beberapa byte lagi jika Anda menggunakan-a
flag, yang menghitung spasi dan melompati instruksi sebagai kutu-a
Bendera izinkan saya golf sedikit lagi, terima kasih! Saya pikir Anda dapat menggunakan\!
trik dalam kode Anda juga: Cobalah online!Java 8, program lengkap, 150 byte
Coba di sini (waktu habis setelah 60 detik, jadi saya telah mengatur tidur ke 1 untuk melihat lebih banyak output).
Penjelasan:
Java 8, fungsi, 94 byte
Coba di sini (waktu habis setelah 60 detik, jadi saya telah mengatur tidur ke 1 untuk melihat lebih banyak output).
Penjelasan:
Berikut adalah gif kecil untuk melihatnya berfungsi sebagaimana dimaksud ketika 1000 ms digunakan:
sumber
PHP,
5948 byteTerinspirasi oleh jawaban Darren H .
Versi lama :
sumber
-3600
semuanya, yang akan menghemat 5 byte.Shell , 177 byte
Perhatikan bahwa ini tidak sepenuhnya sesuai POSIX karena menggunakan
date +%s
, yang merupakandate
ekspansi umum .sumber
Ruby,
192117 byte (Kredit ke Dada)Bagaimana cara kerjanya?
Akan menggunakan versi yang diperluas (Konversi ke waktu diberikan sebagai fungsi terpisah dan menggunakan format output yang berbeda):
sumber
printf
bukannyaputs
dapat menyimpan beberapa byte lagi: Cobalah secara online! . Selamat bermain golf di PPCG!APL NARS,
109 6357 karakter3 + 3 + 48 + 3 = 57 (lihat solusi Apl lainnya juga)
konversikan INT string dalam string angka dengan cara jika panjang string itu adalah 1 daripada tambahkan satu '0' di depannya
menggabungkan array dalam ⍵ dengan array '::'
sumber
kode mesin x86-64 (panggilan sistem Linux): 78 byte
Waktu putar-putar RDTSC , Linux
sys_write
panggilan sistem .x86-64 tidak menyediakan cara yang nyaman untuk menanyakan frekuensi "jam referensi" RDTSC pada waktu berjalan. Anda dapat membaca MSR (dan melakukan perhitungan berdasarkan itu) , tetapi itu membutuhkan mode kernel, atau pembukaan root +
/dev/cpu/%d/msr
, jadi saya memutuskan untuk membuat frekuensi konstan-waktu build. (MenyesuaikanFREQ_RDTSC
seperlunya: konstanta 32-bit tidak akan mengubah ukuran kode mesin)Perhatikan bahwa CPU x86 selama beberapa tahun telah memperbaiki frekuensi RDTSC sehingga dapat digunakan sebagai sumber waktu, bukan penghitung kinerja siklus clock inti kecuali jika Anda mengambil langkah untuk menonaktifkan perubahan frekuensi. (Ada penghitung perf aktual untuk menghitung siklus CPU nyata.) Biasanya itu berdetak pada frekuensi stiker nominal, misalnya 4.0GHz untuk i7-6700k saya terlepas dari turbo atau hemat daya. Bagaimanapun, waktu tunggu yang sibuk ini tidak tergantung pada rata-rata beban (seperti loop penundaan yang dikalibrasi), dan juga tidak sensitif terhadap penghematan daya CPU.
Kode ini akan berfungsi untuk x86 apa pun dengan frekuensi referensi di bawah 2 ^ 32 Hz, yaitu hingga ~ 4,29 GHz. Di luar itu, timestamp 32 rendah akan membungkus semua jalan dalam 1 detik, jadi saya harus melihat
edx
32 bit hasil yang tinggi juga.Ringkasan :
dorong
00:00:00\n
tumpukan. Kemudian dalam satu lingkaran:sys_write
panggilan sistemcmp
/cmov
, dengan hasil CF menyediakan carry-in untuk digit berikutnya.rdtsc
dan menghemat waktu mulai.rdtsc
sampai delta>> kutu per detik dari frekuensi RDTSC.Daftar NASM:
Batalkan komentar pada
pause
instruksi untuk menghemat daya yang signifikan: ini memanaskan satu inti hingga ~ 15 derajat C tanpapause
, tetapi hanya pada ~ 9 denganpause
. (Di Skylake, di manapause
tidur untuk ~ 100 siklus, bukan ~ 5. Saya pikir itu akan menghemat lebih banyak jikardtsc
tidak juga lambat-ish sehingga CPU tidak melakukan banyak waktu).Versi 32-bit akan lebih pendek beberapa byte, misalnya menggunakan versi 32-bit ini untuk mendorong string awal 00: 00: 00 \ n.
Dan juga menggunakan 1 byte
dec edx
. Theint 0x80
system call ABI tidak akan menggunakan esi / edi, sehingga register setup untuk syscall vs lodsb / stosb mungkin lebih sederhana.sumber
nanosleep
system call, tapi ini lebih menarik. Dengan root di Linux, dimungkinkan untuk membaca MSR yang tepat dan secara terprogram mendapatkan frekuensi RDTSC.q / kdb + , 40 byte
Larutan:
Contoh:
Penjelasan:
Ada tiga perintah yang dieksekusi di sini:
.z.ts:{-1($)18h$a+:1}; / override timer function
a:-1; / initialise variable a to -1
(.)"\\t 1000" / start the timer with 1000ms precision
Rincian fungsi pengatur waktu:
Bonus:
Alternatif 1 untuk 41 byte :
Alternatif 2 untuk 26 + 7 byte = 33 byte
dan menambahkan
-t 1000
sebagai argumen ke q biner.sumber