什么是二进制时间?


14

什么是二进制时间?

每个人都知道正常时间。它位于屏幕的右上角(或放置在任何位置)。但是人们似乎很少会问自己一个问题:这是二进制时间?

二进制时间

二进制时间(True Binary Time)通过首先读取数字的最高有效位(MSB)来工作。如果该数字为0,则表示的时间是中午之前。如果该数字为1,则表示的时间是中午之后。下一位将第一位表示的半天分成两个相等的一半,这次是6小时。接下来的部分分为3小时,接下来的90分钟,依此类推。12:00:00似乎不应该发生的时代变得如此1

我只能理解这种奇怪的计时系统,因此我需要一个程序来转换为我的程序。但是由于二进制数是Base-2,而2是小数,因此您的程序必须尽可能短。

要求

  • 您的程序应以一个时间(24小时制)作为输入,并输出相应的二进制时间数字。
  • 输出数字应具有16位精度(该数字应为16位长)。
  • 您不能使用为您完成所有转换的内置函数。
  • 如果需要四舍五入,则应设下限。

规则

  • 标准漏洞禁止出现。
  • 您的程序不应向写入任何内容STDERR

测试用例

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

计分

如前所述,要赢,您必须拥有最少的字节数。

意见书

为了确保您的答案显示出来,请使用以下Markdown模板以标题开头。

# Language Name, N bytes

N您提交的文件大小在哪里。如果您提高了分数,可以将旧分数保留在标题中,方法是将它们打掉。例如:

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

如果您想在标头中包含多个数字(例如,因为您的分数是两个文件的总和,或者您想单独列出解释器标志罚分),请确保实际分数是标头中的最后一个数字:

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

您还可以将语言名称设置为链接,然后该链接将显示在页首横幅代码段中:

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

排行榜

这是一个堆栈片段,用于按语言生成常规排行榜和获胜者概述。


3
我可以输入为[hour, minute, second]吗?我们不喜欢限制输入格式。
Leaky Nun

2
怎么09:57:300110110000000000
Leaky Nun

2
16位只能代表65536个值。一天有86400秒。我们应该如何表示与二进制表示不完全匹配的任何内容?
PurkkaKoodari'6

我们可以将结果作为16个数字的列表返回吗?
亚当

@Adám是的,可以。
George Gibson

Answers:


1

MATL,15字节

YOtk-KWW*k16&YB

使用内置函数将表示时间的字符串转换为挑战允许的日期/时间序列号。

在线尝试!

说明

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个字节

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

测试套件。

说明

利用了这样的事实:86400(一天中的秒数)上的65536(2 16)简化为675上的512。

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

Pyth,31 27字节

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

测试套件。

将输入转换为经过的秒数,再乘以2^16 / 24*60*60,然后进行下限并转换为16位二进制。

通过简化65536/86400512/675(愚蠢的我)节省了4个字节。

输入输出

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

你能证明“ 然后下楼 ”吗?
彼得·泰勒

@PeterTaylor我该怎么办?
Leaky Nun

4
等到规范已消除歧义后再发布答案。
彼得·泰勒

@PeterTaylor正确的舍入方式由表示10:33:06
ADAM

@Adám,不是真的,因为这样可以使上下限和最近舍入的结果相同。
彼得·泰勒

3

TSQL(sqlserver 2012),103字节

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

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

在线尝试

不打高尔夫球

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),119106字节

还包括一个不带变量@x的不同版本,但是它长了几个字节。包括那些感兴趣的人的非高尔夫版本:

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 @

那看起来并不打高尔夫球。您不能删除很多空格吗?
ADAM

@Adám非常糟糕,我使用了不同于标准的方法来简化脚本,甚至尝试了不同的方法。在将答案回答到代码高尔夫中时,我只是遇到了一个偶然的空格(只有一个)。我想在这里放一个换行符,但决定在WHILE之后放它。删除空间并想知道您是否真的对我那额外的空间
不满意

@Adám,如果您正在查看第二种方法,则它不打高尔夫球(字符数除外),因为这不是我的实际答案。只是一种解决问题的其他计算方法
t-clausen.dk

3
不,我没有投票。在OP澄清未解决的规则问题之前,可能有人会否决所有发布的答案。除最新答案外,所有答案都只有一票。(可能是Peter Taylor,因为他刚好在那篇文章之前就在这里,而他一直对此抱怨。)当您获得足够的代表时,您可以看到此信息。来吃吧
ADAM

2

JavaScript(ES6),72 76字节

编辑 4个字节保存thx @Neil

尚不清楚四舍五入。这一个被截断,没关系。

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

测试

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>


我试图弄清楚为什么这被
否决了

t=>([h,m,s]=t.split`:`,(+h+m/60+s/3600)*8192/3|65536).toString(2).slice(1)为您节省了2个字节,但又节省了reduce一个字节:t=>(t.split`:`.reduce((n,m)=>+m+n*60)*512/675|65536).toString(2).slice(1)
Neil

不加评论的不赞成
投票

@尼尔非常感谢你!并保存了.map 1个字节
edc65 '16

呵呵,我想知道您从哪里可以得到0 ...
Neil

1

APL(Dyalog)24 21字节

现在已经澄清了规则。

提示时间为3元素列表。

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

编辑:更新()以匹配10:33:06的新结果。

在线尝试!

 提示输入

60⊥ 以60为基数评估

675÷⍨ 除以675

512× 乘以512

 地板

()⊤ 将以下数字系统转换为(助记符:颠倒的基数为反基数):

16/2 复制2次16次(即16位二进制)   


0

Q,32字节

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

测试

   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
  • 为了减少显示混乱,我对原始表达式进行了少许修改,从而为tlambda 命名。

  • b后缀表示二进制

说明

注意。-从左到右阅读,从右到左评估

读取为:从512底限的二进制表示形式中减去48,除以675,再乘以60 scalarFromVector,将其从“:”原始字符串的分割处转换为整数

评价:

":"\:x 在“:”字符处分割字符串x(lambda的隐式arg)(Q使用“”表示char)

"I"$x 将字符串x转换为int->小时,分钟,秒

60/:x 使用以60为底的整数序列来计算单个值->总秒数

(512%675)*x 计算比率512%675(%除)并乘以秒。512%675是分数的简化形式(totalSecondsPerDay%64K)

_ x 表示浮点数x

0b\:x 计算x的二进制表示形式(64位)

48_ x 删除前48位,所以我们有16位表示

示例(x =“ 01:30:00”)。注意:-“ /”表示到行尾的注释

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


0

Ruby,75个字节

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

我觉得必须有一种将时间转换为秒的更短方法,但这就是我能想到的。


0

Python,45个字节

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

512/675我自己想出了这个因素,然后看到其他人也做了同样的事情。


0

C,91字节

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字节

使用IBM-850编码。

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

像这样运行:

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

调整

  • 通过使用IBM-850编码节省了一个字节。
  • 通过使用节省了3个字节 $argn
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.