What's the Binary Time?
Everybody knows what the normal time is. It's up there in the top-right (or wherever you put it) of your screen. But a question people rarely seem to ask themselves is this: What's the binary time?
Binary Time
Binary Time (True Binary Time) works by first reading the most significant bit (MSB) of the number. If that number is 0
, the time expressed is before noon. If that number is 1
, the time expressed is after noon. The next bit splits the half of the day the first bit expressed into two more equal halves, this time of 6 hours. The following bit splits into 3 hours, the next 90 minutes, and so on. Times like 12:00:00
, where it seems it should be neither, become 1
.
I can only understand this strange system of timing, so I need a program to convert to that for me. But as binary numbers are Base-2, and 2 is a small number, your program must be as short as possible.
Requirements
- Your program should take a time (as 24-hour-time) as input and output the corresponding binary time number.
- The output number should have 16-bit precision (the number should be 16 digits long).
- You cannot use a builtin that does all of that conversion for you.
- You should floor if it needs to be rounded.
Rules
- Standard loopholes are forbidden.
- Your program should not write anything to
STDERR
.
Test Cases
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
Scoring
To win, as I mentioned earlier, you must have the least bytes.
Submissions
To make sure that your answer shows up, please start your answer with a headline, using the following Markdown template:
# Language Name, N bytes
where N
is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:
# Ruby, <s>104</s> <s>101</s> 96 bytes
If there you want to include multiple numbers in your header (e.g. because your score is the sum of two files or you want to list interpreter flag penalties separately), make sure that the actual score is the last number in the header:
# Perl, 43 + 2 (-p flag) = 45 bytes
You can also make the language name a link which will then show up in the leaderboard snippet:
# [><>](http://esolangs.org/wiki/Fish), 121 bytes
Leaderboard
Here is a Stack Snippet to generate both a regular leaderboard and an overview of winners by language.
/* Configuration */
var QUESTION_ID = 81057; // Obtain this from the url
// It will be like https://XYZ.stackexchange.com/questions/QUESTION_ID/... on any question page
var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe";
var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk";
var OVERRIDE_USER = 53406; // This should be the user ID of the challenge author.
/* App */
var answers = [], answers_hash, answer_ids, answer_page = 1, more_answers = true, comment_page;
function answersUrl(index) {
return "https://api.stackexchange.com/2.2/questions/" + QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER;
}
function commentUrl(index, answers) {
return "https://api.stackexchange.com/2.2/answers/" + answers.join(';') + "/comments?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + COMMENT_FILTER;
}
function getAnswers() {
jQuery.ajax({
url: answersUrl(answer_page++),
method: "get",
dataType: "jsonp",
crossDomain: true,
success: function (data) {
answers.push.apply(answers, data.items);
answers_hash = [];
answer_ids = [];
data.items.forEach(function(a) {
a.comments = [];
var id = +a.share_link.match(/\d+/);
answer_ids.push(id);
answers_hash[id] = a;
});
if (!data.has_more) more_answers = false;
comment_page = 1;
getComments();
}
});
}
function getComments() {
jQuery.ajax({
url: commentUrl(comment_page++, answer_ids),
method: "get",
dataType: "jsonp",
crossDomain: true,
success: function (data) {
data.items.forEach(function(c) {
if (c.owner.user_id === OVERRIDE_USER)
answers_hash[c.post_id].comments.push(c);
});
if (data.has_more) getComments();
else if (more_answers) getAnswers();
else process();
}
});
}
getAnswers();
var SCORE_REG = /<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/;
var OVERRIDE_REG = /^Override\s*header:\s*/i;
function getAuthorName(a) {
return a.owner.display_name;
}
function process() {
var valid = [];
answers.forEach(function(a) {
var body = a.body;
a.comments.forEach(function(c) {
if(OVERRIDE_REG.test(c.body))
body = '<h1>' + c.body.replace(OVERRIDE_REG, '') + '</h1>';
});
var match = body.match(SCORE_REG);
if (match)
valid.push({
user: getAuthorName(a),
size: +match[2],
language: match[1],
link: a.share_link,
});
});
valid.sort(function (a, b) {
var aB = a.size,
bB = b.size;
return aB - bB
});
var languages = {};
var place = 1;
var lastSize = null;
var lastPlace = 1;
valid.forEach(function (a) {
if (a.size != lastSize)
lastPlace = place;
lastSize = a.size;
++place;
var answer = jQuery("#answer-template").html();
answer = answer.replace("{{PLACE}}", lastPlace + ".")
.replace("{{NAME}}", a.user)
.replace("{{LANGUAGE}}", a.language)
.replace("{{SIZE}}", a.size)
.replace("{{LINK}}", a.link);
answer = jQuery(answer);
jQuery("#answers").append(answer);
var lang = a.language;
if (/<a/.test(lang)) lang = jQuery(lang).text();
languages[lang] = languages[lang] || {lang: a.language, user: a.user, size: a.size, link: a.link};
});
var langs = [];
for (var lang in languages)
if (languages.hasOwnProperty(lang))
langs.push(languages[lang]);
langs.sort(function (a, b) {
if (a.lang > b.lang) return 1;
if (a.lang < b.lang) return -1;
return 0;
});
for (var i = 0; i < langs.length; ++i)
{
var language = jQuery("#language-template").html();
var lang = langs[i];
language = language.replace("{{LANGUAGE}}", lang.lang)
.replace("{{NAME}}", lang.user)
.replace("{{SIZE}}", lang.size)
.replace("{{LINK}}", lang.link);
language = jQuery(language);
jQuery("#languages").append(language);
}
}
body { text-align: left !important}
#answer-list {
padding: 10px;
width: 290px;
float: left;
}
#language-list {
padding: 10px;
width: 290px;
float: left;
}
table thead {
font-weight: bold;
}
table td {
padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b">
<div id="answer-list">
<h2>Leaderboard</h2>
<table class="answer-list">
<thead>
<tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr>
</thead>
<tbody id="answers">
</tbody>
</table>
</div>
<div id="language-list">
<h2>Winners by Language</h2>
<table class="language-list">
<thead>
<tr><td>Language</td><td>User</td><td>Score</td></tr>
</thead>
<tbody id="languages">
</tbody>
</table>
</div>
<table style="display: none">
<tbody id="answer-template">
<tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
</tbody>
</table>
<table style="display: none">
<tbody id="language-template">
<tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
</tbody>
</table>
11 Answers 11
CJam, 20 bytes
l':/60b9m<675/2bG0e[
Explanation
Makes use of the fact that 65536 (216) over 86400 (the number of seconds in a day) simplifies to 512 over 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.
Pyth, (削除) 31 (削除ここまで) 27 bytes
.[016円.Bs*512cisMcQ\:60 675
Converts the input into number of seconds passed, multiply by a factor of 2^16 / 24*60*60
, and then floor and convert to 16-bit binary.
Saved 4 bytes by simplifying 65536/86400
into 512/675
(stupid me).
Input/output
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
-
\$\begingroup\$ Can you justify "and then floor"? \$\endgroup\$Peter Taylor– Peter Taylor2016年06月01日 10:08:38 +00:00Commented Jun 1, 2016 at 10:08
-
\$\begingroup\$ @PeterTaylor What should I do instead? \$\endgroup\$Leaky Nun– Leaky Nun2016年06月01日 10:15:13 +00:00Commented Jun 1, 2016 at 10:15
-
4\$\begingroup\$ Wait until the spec has been disambiguated before posting an answer. \$\endgroup\$Peter Taylor– Peter Taylor2016年06月01日 10:16:05 +00:00Commented Jun 1, 2016 at 10:16
-
\$\begingroup\$ @PeterTaylor The right way of rounding is apparent by
10:33:06
. \$\endgroup\$Adám– Adám2016年06月01日 11:45:32 +00:00Commented Jun 1, 2016 at 11:45 -
\$\begingroup\$ @Adám, not really, because that gives the same output with floor and round-to-nearest. \$\endgroup\$Peter Taylor– Peter Taylor2016年06月01日 12:01:18 +00:00Commented Jun 1, 2016 at 12:01
TSQL(sqlserver 2012), 103 bytes
DECLARE @d datetime = '10:33:06'
DECLARE @ char(16)='',@x INT=cast(@d as real)*131072WHILE
len(@)<16SELECT @x/=2,@=concat(@x%2,@)PRINT @
Ungolfed
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 bytes
Also included a different version without the variable @x, however it was a few bytes longer. Including the ungolfed version for those interested:
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 @
-
\$\begingroup\$ That doesn't look golfed. Can't you remove a lot of whitespace? \$\endgroup\$Adám– Adám2016年06月01日 15:35:33 +00:00Commented Jun 1, 2016 at 15:35
-
\$\begingroup\$ @Adám it is very goolfed, I used different methods than the standard to make the script shorter and even tried a different method. I just had an accidental whitespace put in when coping my answer into codegolf(only one extra). I wanted to put a linebreak there, but decided to put it after WHILE instead. Removing the space and wondering if you really downvoted me for that single extra space \$\endgroup\$t-clausen.dk– t-clausen.dk2016年06月01日 16:14:25 +00:00Commented Jun 1, 2016 at 16:14
-
\$\begingroup\$ @Adám and if you are looking at the second method, it is not golfed(except the character count), since it is not my actual answer. Just a different more calculating method of solving it \$\endgroup\$t-clausen.dk– t-clausen.dk2016年06月01日 16:21:59 +00:00Commented Jun 1, 2016 at 16:21
-
3\$\begingroup\$ No, I didn't downvote. It was probably someone who has a principle to downvotes all answers that are posted before the OP clarifies outstanding rule questions. All but the very newest answer has exactly one downvote. (It was probably Peter Taylor, because he was last here just before that post, and he has been complaining about this.) You can see this when you get enough rep. Here, have some! \$\endgroup\$Adám– Adám2016年06月01日 17:36:38 +00:00Commented Jun 1, 2016 at 17:36
JavaScript (ES6), 72 (削除) 76 (削除ここまで) bytes
Edit 4 bytes save thx @Neil
(削除) Still unclear about the rounding. (削除ここまで)This one truncates and that's ok.
t=>(t.split`:`.map(v=>t=+v+60*~~t),t*512/675|65536).toString(2).slice(1)
Test
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>
-
\$\begingroup\$ am trying to figure out why this was downvoted \$\endgroup\$t-clausen.dk– t-clausen.dk2016年06月01日 14:01:18 +00:00Commented Jun 1, 2016 at 14:01
-
\$\begingroup\$
t=>([h,m,s]=t.split`:`,(+h+m/60+s/3600)*8192/3|65536).toString(2).slice(1)
saves you 2 bytes, butreduce
goes one byte further:t=>(t.split`:`.reduce((n,m)=>+m+n*60)*512/675|65536).toString(2).slice(1)
\$\endgroup\$Neil– Neil2016年06月01日 19:06:54 +00:00Commented Jun 1, 2016 at 19:06 -
\$\begingroup\$ Downvote without a comment is not cool, upvoted \$\endgroup\$t-clausen.dk– t-clausen.dk2016年06月01日 19:46:37 +00:00Commented Jun 1, 2016 at 19:46
-
\$\begingroup\$ @Neil thank you very much! And with .map 1 more byte saved \$\endgroup\$edc65– edc652016年06月01日 20:12:56 +00:00Commented Jun 1, 2016 at 20:12
-
\$\begingroup\$ Huh, I was wondering where you were going to get the 0 from for the map... \$\endgroup\$Neil– Neil2016年06月01日 20:52:57 +00:00Commented Jun 1, 2016 at 20:52
MATL, 15 bytes
YOtk-KWW*k16&YB
Uses a builtin for converting a string representing time to a serial date/time number, which is allowed by the challenge.
Explanation
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
C, 91 bytes
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++;}
APL (Dyalog), (削除) 24 (削除ここまで) 21 bytes
The rules have now been clarified.
Prompts for time as 3-element list.
(16/2)×ばつ675÷⍨60⊥⎕
Edit: Updated (⌈
→ ⌊
) to match new result for 10:33:06.
⎕
prompt for input
60⊥
evaluate in base-60
675÷⍨
divide by 675
×ばつ
multiply by 512
⌊
floor
(
...)⊤
convert to (mnemonic: upside-down base is anti-base) the following number system:
16/2
replicate 2 sixteen times (i.e. 16-bit binary)
Q, 32 Bytes
48_0b\:_(512%675)*60/:"I"$":"\:
Test
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
In order to reduce display cluttering, i assume a slight modification to the original expression, that gives name
t
to the lambdab suffix indicates binary
Explanation
NOTE.- read left to right, evaluates right to left
Reads as: 48 drop from binary representation of floor of 512 divideb by 675 and multiplied by 60 scalarFromVector over integer cast from splits at ":" original string
Evaluation:
":"\:x
splits string x (implicit arg of the lambda) at ":" character (Q uses "" to denote char)
"I"$x
cast string(s) x to int(s) -> hours, minutes, seconds
60/:x
uses base 60 to calculate a single value from a sequence of ints -> seconds total
(512%675)*x
calculates ratio 512%675
(% is divide) and multiplies seconds. 512%675 is the simplified form of the fraction (totalSecondsPerDay%64K)
_ x
indicates floor of float x
0b\:x
calculates binary representation of x (64 bits)
48_ x
drop first 48 bits, so we have our 16 bits representation
Example (x="01:30:00"). NOTE.- "/" indicates comment to end of line
":"\:"01:30:00" /-> ("01";"30";"00")
"I"$ /-> 1 30 0
60/: /-> 5400
(512%675)* /-> 4096.0
_ /-> 4096
0b\: /-> 0000000000000000000000000000000000000000000000000001000000000000b
48_ /-> 0001000000000000b
Ruby, 75 bytes
h,m,s=t.split(':').map &:to_i;((h*3600+m*60+s<<9)/675).to_s(2).rjust 16,'0'
I feel like there must be a shorter method of converting the time to seconds, but this is all I could think of.
Python, 45 bytes
lambda h,m,s:bin((s+m*60+h*3600)*512/675)[2:]
Came up with the 512/675
factor myself, then saw others did it the same.
PHP, (削除) 47 (削除ここまで) (削除) 46 (削除ここまで) 43 bytes
Uses IBM-850 encoding.
printf(~┌Ø,strtotime($argn.UTC,0)*512/675);
Run like this:
echo "18:00:00" | php -nR 'printf(~┌Ø,strtotime($argn.UTC,0)*512/675);';echo
Tweaks
- Saved a byte by using IBM-850 encoding.
- Saved 3 bytes by using
$argn
[hour, minute, second]
? We don't like restricting input format. \$\endgroup\$09:57:30
make0110110000000000
? \$\endgroup\$