Thời gian nhị phân là gì?


14

Thời gian nhị phân là gì?

Mọi người đều biết thời gian bình thường là gì. Nó ở trên cùng bên phải (hoặc bất cứ nơi nào bạn đặt nó) trên màn hình của bạn. Nhưng một câu hỏi mà mọi người dường như hiếm khi tự hỏi mình là: Thời gian nhị phân là gì?

Thời gian nhị phân

Thời gian nhị phân (Thời gian nhị phân thực) hoạt động bằng cách trước tiên đọc bit có ý nghĩa nhất (MSB) của số. Nếu số đó là 0, thời gian thể hiện là trước buổi trưa. Nếu số đó là 1, thời gian thể hiện là sau buổi trưa. Bit tiếp theo chia nửa ngày, bit đầu tiên được biểu thị thành hai nửa bằng nhau hơn, lần này là 6 giờ. Các bit sau chia thành 3 giờ, 90 phút tiếp theo, v.v. Thời gian như thế 12:00:00, nơi dường như không nên, trở thành 1.

Tôi chỉ có thể hiểu hệ thống thời gian kỳ lạ này, vì vậy tôi cần một chương trình để chuyển đổi sang hệ thống đó cho tôi. Nhưng vì số nhị phân là Base-2 và 2 là số nhỏ, chương trình của bạn phải càng ngắn càng tốt.

Yêu cầu

  • Chương trình của bạn sẽ mất một thời gian (dưới dạng 24 giờ) làm đầu vào và đầu ra số thời gian nhị phân tương ứng.
  • Số đầu ra phải có độ chính xác 16 bit (số phải dài 16 chữ số).
  • Bạn không thể sử dụng một nội dung thực hiện tất cả các chuyển đổi đó cho bạn.
  • Bạn nên sàn nếu nó cần phải được làm tròn.

Quy tắc

  • Sơ hở tiêu chuẩn bị cấm.
  • Chương trình của bạn không nên viết bất cứ điều gì STDERR.

Các trường hợp thử nghiệm

00:00:00==> 0000000000000000
12:00:00==> 1000000000000000
01:30:00==> 0001000000000000
10:33:06==> 0111000010001101
09:57:30==> 0110101000111000
06:00:00==> 0100000000000000
18:00:00==>1100000000000000

Chấm điểm

Để giành chiến thắng, như tôi đã đề cập trước đó, bạn phải có ít byte nhất.

Đệ trình

Để đảm bảo rằng câu trả lời của bạn hiển thị, vui lòng bắt đầu câu trả lời của bạn bằng một tiêu đề, sử dụng mẫu Markdown sau:

# Language Name, N bytes

nơi Nlà kích thước của trình của bạn. Nếu bạn cải thiện điểm số của mình, bạn có thể giữ điểm số cũ trong tiêu đề, bằng cách đánh chúng qua. Ví dụ:

# Ruby, <s>104</s> <s>101</s> 96 bytes

Nếu ở đó bạn muốn bao gồm nhiều số trong tiêu đề của mình (ví dụ: vì điểm của bạn là tổng của hai tệp hoặc bạn muốn liệt kê riêng các hình phạt cờ phiên dịch), hãy đảm bảo rằng điểm thực tế là số cuối cùng trong tiêu đề:

# Perl, 43 + 2 (-p flag) = 45 bytes

Bạn cũng có thể đặt tên ngôn ngữ thành liên kết sau đó sẽ hiển thị trong đoạn trích bảng xếp hạng:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes

Bảng xếp hạng

Dưới đây là một Stack Snippet để tạo cả bảng xếp hạng thông thường và tổng quan về người chiến thắng theo ngôn ngữ.


3
Tôi có thể nhập như là [hour, minute, second]? Chúng tôi không thích hạn chế định dạng đầu vào.
Rò rỉ Nun

2
Làm thế nào để 09:57:30làm 0110110000000000?
Leaky Nun

2
16 bit chỉ có thể đại diện cho 65536 giá trị. Có 86400 giây trong một ngày. Làm thế nào chúng ta nên đại diện cho bất cứ điều gì không chính xác phù hợp với một đại diện nhị phân?
PurkkaKoodari

Chúng tôi có thể trả về kết quả dưới dạng danh sách 16 số không?
Adám

@ Adám Có, bạn có thể.
George Gibson

Câu trả lời:


1

MATL , 15 byte

YOtk-KWW*k16&YB

Sử dụng một nội dung để chuyển đổi một chuỗi biểu thị thời gian thành một số ngày / thời gian nối tiếp, được cho phép bởi thử thách.

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

Giải trình

YO       % Input time string. Convert to serial date/time. Time is fractional part
tk-      % Duplicate, round down, subtract. This keeps fractional part only
KWW      % 34, 2 raised to, 2 raised to (`16W` would require an extra space)
*        % Multiply
k        % Round down
16&YB    % Convert to binary string with 16 digits. Display

5

CJam, 20 byte

l':/60b9m<675/2bG0e[

Bộ thử nghiệm.

Giải trình

Làm cho việc sử dụng thực tế là 65536 (2 16 ) trên 86400 (số giây trong một ngày) đơn giản hóa thành 512 trên 675.

l     e# Read input.
':/   e# Split around ':', so we get ["hh" "mm" "ss"].
60b   e# Interpret as base-60 digits, which computes hh*60^2 + mm*60 + ss,
      e# i.e. it computes the total number of seconds. Note that this implicitly
      e# converts all three strings to integers.
9m<   e# Bitwise left-shift by 9 positions, which is the same as multiplying by
      e# 2^9 = 512.
675/  e# Divide by 675, flooring the result.
2b    e# Convert to binary.
G0e[  e# Left-pad with zeros to 16 digits.

3

Bình thường, 31 27 byte

.[\016.Bs*512cisMcQ\:60 675

Bộ thử nghiệm.

Chuyển đổi đầu vào thành số giây được truyền, nhân với hệ số 2^16 / 24*60*60, sau đó chuyển tầng và chuyển đổi thành nhị phân 16 bit.

Đã lưu 4 byte bằng cách đơn giản hóa 65536/86400thành 512/675(ngu tôi).

Đầu ra đầu vào

00:00:00    0000000000000000
11:00:00    0111010101010101
12:00:00    1000000000000000
01:30:00    0001000000000000
10:33:06    0111000010001101
09:57:30    0110101000111000
06:00:00    0100000000000000
18:00:00    1100000000000000
23:59:59    1111111111111111

Bạn có thể biện minh cho " và sau đó sàn "?
Peter Taylor

@PeterTaylor Tôi nên làm gì thay thế?
Leaky Nun

4
Đợi cho đến khi thông số kỹ thuật đã được định hướng trước khi đăng câu trả lời.
Peter Taylor

@PeterTaylor Cách làm tròn đúng là rõ ràng bởi 10:33:06.
Adám

@ Adám, không thực sự, bởi vì điều đó cho cùng một đầu ra với sàn và vòng gần nhất.
Peter Taylor

3

TSQL (sqlserver 2012), 103 byte

DECLARE @d datetime = '10:33:06'

DECLARE @ char(16)='',@x INT=cast(@d as real)*131072WHILE
len(@)<16SELECT @x/=2,@=concat(@x%2,@)PRINT @

Dùng thử trực tuyến

Ung dung

DECLARE @d datetime = '10:33:06'

DECLARE @ char(16)='',
        @x INT=cast(@d as real)*131072
WHILE len(@)<16
SELECT @x/=2,@=concat(@x%2,@)
PRINT @

TSQL (sqlserver 2012), 119 106 byte

Cũng bao gồm một phiên bản khác không có biến @x, tuy nhiên nó dài hơn một vài byte. Bao gồm cả phiên bản chưa được chỉnh sửa cho những người quan tâm:

DECLARE @d datetime = '23:59:59'

DECLARE @ varchar(16) =''
WHILE LEN(@)<16
SET @+=LEFT(CAST(@d as decimal(9,9))*2*POWER(2,LEN(@))%2,1)
PRINT @

Trông nó không được đánh gôn. Bạn có thể loại bỏ rất nhiều khoảng trắng?
Adám

@ Adám nó rất goolfed, tôi đã sử dụng các phương thức khác với tiêu chuẩn để làm cho tập lệnh ngắn hơn và thậm chí đã thử một phương thức khác. Tôi chỉ có một khoảng trắng tình cờ được đưa vào khi đối phó câu trả lời của tôi với codegolf (chỉ có một phần phụ). Tôi muốn đặt một linebreak ở đó, nhưng quyết định đặt nó sau WHILE thay thế. Xóa không gian và tự hỏi liệu bạn có thực sự đánh giá thấp tôi về không gian thừa đó không
t-clausen.dk

@ Adám và nếu bạn đang xem phương pháp thứ hai, nó không được đánh gôn (ngoại trừ số lượng ký tự), vì đó không phải là câu trả lời thực tế của tôi. Chỉ là một phương pháp tính toán khác để giải quyết nó
t-clausen.dk

3
Không, tôi đã không downvote. Có lẽ ai đó có một nguyên tắc để hạ thấp tất cả các câu trả lời được đăng trước khi OP làm rõ các câu hỏi về quy tắc nổi bật. Tất cả trừ câu trả lời mới nhất có chính xác một downvote. (Có lẽ đó là Peter Taylor, bởi vì anh ấy đã ở đây ngay trước bài đăng đó, và anh ấy đã phàn nàn về điều này.) Bạn có thể thấy điều này khi bạn có đủ đại diện. Ở đây, có một số!
Adám

2

JavaScript (ES6), 72 76 byte

Chỉnh sửa 4 byte lưu thx @Neil

Vẫn chưa rõ về làm tròn. Điều này cắt ngắn và đó là ok.

t=>(t.split`:`.map(v=>t=+v+60*~~t),t*512/675|65536).toString(2).slice(1)

Kiểm tra

f=t=>(t.split`:`.map(v=>t=+v+60*~~t),t*512/675|65536).toString(2).slice(1)

function test() {
  var v=I.value
  R.textContent=f(v)
}

test()


;`00:00:00 ==> 0000000000000000
12:00:00 ==> 1000000000000000
01:30:00 ==> 0001000000000000
10:33:06 ==> 0111000010001101
09:57:30 ==> 0110101000111000
06:00:00 ==> 0100000000000000
18:00:00 ==> 1100000000000000`
.split('\n').forEach(t=>{
  [i,k]=t.split(' ==> ')
  r=f(i)
  ok=r==k
  O.textContent += (ok ? 'OK ':'KO ')+ i + ' -> ' + r + (ok? '\n' : ' Expected '+k+'\n')
})
<input id=I value='12:34:56' oninput=test()>
<span id=R></span>
<pre id=O></pre>


đang cố gắng tìm ra lý do tại sao điều này bị hạ cấp
t-clausen.dk

t=>([h,m,s]=t.split`:`,(+h+m/60+s/3600)*8192/3|65536).toString(2).slice(1)giúp bạn tiết kiệm 2 byte, nhưng reduceđi xa hơn một byte:t=>(t.split`:`.reduce((n,m)=>+m+n*60)*512/675|65536).toString(2).slice(1)
Neil

Downvote mà không có bình luận là không hay, được nâng cấp
t-clausen.dk

@Neil cảm ơn bạn rất nhiều! Và với .map thêm 1 byte được lưu
edc65

Huh, tôi đã tự hỏi bạn sẽ lấy 0 từ đâu cho bản đồ ...
Neil

1

APL (Dyalog) , 24 21 byte

Các quy tắc đã được làm rõ.

Nhắc thời gian là danh sách 3 yếu tố.

(16/2)⊤⌊512×675÷⍨60⊥⎕

Chỉnh sửa: Đã cập nhật ( ) để phù hợp với kết quả mới cho 10:33:06.

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

 nhắc nhở cho đầu vào

60⊥ đánh giá trong cơ sở-60

675÷⍨ chia cho 675

512× nhân với 512

 sàn nhà

(Giáo dục)⊤  chuyển đổi sang (ghi nhớ: căn cứ lộn ngược là chống-base) hệ thống số sau:

16/2 sao chép 2 mười sáu lần (tức là nhị phân 16 bit)   


0

Q, 32 byte

48_0b\:_(512%675)*60/:"I"$":"\:

Kiểm tra

   t "00:00:00"
0000000000000000b
   t "12:00:00"
1000000000000000b
   t "01:30:00"
0001000000000000b
   t "10:33:06"
0111000010001101b
   t "09:57:30"
0110101000111000b
   t "06:00:00"
0100000000000000b
   t "18:00:00"
1100000000000000b
  • Để giảm sự lộn xộn hiển thị, tôi giả sử một sửa đổi nhỏ cho biểu thức ban đầu, đặt tên tcho lambda

  • hậu tố b chỉ ra nhị phân

Giải trình

LƯU Ý.- đọc từ trái sang phải, đánh giá từ phải sang trái

Đọc là: 48 giảm từ biểu diễn nhị phân của sàn 512 dải phân cách 675 và nhân với 60 scalarFromVector trên số nguyên được đúc từ các phân tách tại ":" chuỗi gốc

Đánh giá:

":"\:x tách chuỗi x (ẩn arg của lambda) tại ký tự ":" (Q sử dụng "" để biểu thị char)

"I"$x chuỗi (x) x đến int (s) -> giờ, phút, giây

60/:x sử dụng cơ sở 60 để tính một giá trị từ chuỗi ints - tổng số giây>

(512%675)*x tính tỷ lệ 512%675(% là chia) và nhân giây. 512% 675 là dạng đơn giản của phân số (TotalSecondsPerDay% 64K)

_ x chỉ sàn phao x

0b\:x tính toán biểu diễn nhị phân của x (64 bit)

48_ x giảm 48 bit đầu tiên, vì vậy chúng tôi có đại diện 16 bit của chúng tôi

Ví dụ (x = "01:30:00"). LƯU Ý.- "/" biểu thị nhận xét đến cuối dòng

":"\:"01:30:00" /-> ("01";"30";"00") "I"$ /-> 1 30 0 60/: /-> 5400 (512%675)* /-> 4096.0 _ /-> 4096 0b\: /-> 0000000000000000000000000000000000000000000000000001000000000000b 48_ /-> 0001000000000000b


0

Ruby, 75 byte

h,m,s=t.split(':').map &:to_i;((h*3600+m*60+s<<9)/675).to_s(2).rjust 16,'0'

Tôi cảm thấy như phải có một phương pháp ngắn hơn để chuyển đổi thời gian thành giây, nhưng đây là tất cả những gì tôi có thể nghĩ ra.


0

Python, 45 byte

lambda h,m,s:bin((s+m*60+h*3600)*512/675)[2:]

Đến với chính 512/675yếu tố này, rồi thấy những người khác cũng làm như vậy.


0

C, 91 byte

f(h,m,s,n,i){i=0;n=(s+m*60+h*3600)*512/675;while(i<16)printf((n&32768)?"1":"0"),n<<=1,i++;}

0

PHP, 47 46 43 byte

Sử dụng mã hóa IBM-850.

printf(~┌Ø,strtotime($argn.UTC,0)*512/675);

Chạy như thế này:

echo "18:00:00" | php -nR 'printf(~┌Ø,strtotime($argn.UTC,0)*512/675);';echo

Tinh chỉnh

  • Đã lưu một byte bằng cách sử dụng mã hóa IBM-850.
  • Đã lưu 3 byte bằng cách sử dụng $argn
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.