Что такое двоичное время?


14

Что такое двоичное время?

Все знают, что такое нормальное время. Это там, в правом верхнем углу (или там, где вы положили) вашего экрана. Но вопрос, который люди редко задают себе, таков: каково бинарное время?

Двоичное время

Двоичное время (True Binary Time) работает, сначала считывая старший значащий бит (MSB) числа. Если это число равно 0указанному времени до полудня. Если это число соответствует 1указанному времени после полудня. Следующий бит разделяет половину дня, когда первый бит выражается еще на две равные половины, на этот раз 6 часов. Следующий бит делится на 3 часа, следующие 90 минут и так далее. Времена, подобные тем 12:00:00, где, кажется, не должно быть и того, становятся 1.

Я могу понять только эту странную систему хронометража, поэтому мне нужна программа для конвертации в нее. Но поскольку двоичные числа - это Base-2, а 2 - небольшое число, ваша программа должна быть как можно короче.

Требования

  • Ваша программа должна принимать время (24-часовое время) в качестве входных данных и выводить соответствующее двоичное число времени.
  • Выходной номер должен иметь точность 16 бит (номер должен быть длиной 16 цифр).
  • Вы не можете использовать встроенную функцию, которая выполняет все эти преобразования за вас.
  • Вы должны пол, если он должен быть закруглен.

правила

Тестовые случаи

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

счет

Чтобы выиграть, как я упоминал ранее, у вас должно быть наименьшее количество байтов.

Материалы

Чтобы убедиться, что ваш ответ обнаружен, начните его с заголовка, используя следующий шаблон уценки:

# 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

Leaderboard

Вот фрагмент стека, который генерирует как регулярную таблицу лидеров, так и обзор победителей по языкам.


3
Могу ли я ввести как [hour, minute, second]? Нам не нравится ограничивать формат ввода.
Утренняя монахиня

2
Как 09:57:30сделать 0110110000000000?
Протекает Nun

2
16 бит могут представлять только 65536 значений. В дне 86400 секунд. Как мы должны представлять что-либо, что точно не соответствует двоичному представлению?
PurkkaKoodari

Можем ли мы вернуть результат в виде списка из 16 чисел?
Адам

@ Adám Да, можно.
Джордж Гибсон

Ответы:


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[

Тестирование.

объяснение

Используется тот факт, что 65536 (2 16 ) за 86400 (количество секунд в дне) упрощается до 512 за 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

Pyth, 31 27 байт

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

Тестирование.

Преобразует ввод в число пройденных секунд, умножив на коэффициент 2^16 / 24*60*60 , а затем на пол и преобразует в 16-разрядный двоичный код.

Сохранено 4 байта за счет упрощения 65536/86400 в 512/675(глупо меня).

Ввод, вывод

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 Что мне делать вместо этого?
Утренняя монахиня

4
Подождите, пока спецификация была устранена, прежде чем отправлять ответ.
Питер Тейлор

@PeterTaylor Правильный способ округления очевиден 10:33:06.
Адам

@ 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 @

Попробуйте онлайн

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 байт

Также включена другая версия без переменной @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 @

Это не выглядит в гольфе. Вы не можете удалить много пробелов?
Адам

@ Adám это очень глупо, я использовал методы, отличные от стандартных, чтобы сделать скрипт короче, и даже попробовал другой метод. Я только что вставил случайный пробел при копировании моего ответа в Codegolf (только один дополнительный). Я хотел поставить разрыв строки там, но решил поставить его после WHILE вместо этого. Убирая место и задаваясь вопросом, действительно ли вы отказались от меня за это единственное дополнительное место
t-clausen.dk

@ Adám и если вы смотрите на второй метод, это не игра в гольф (за исключением количества символов), так как это не мой фактический ответ. Просто другой, более расчетливый метод ее решения
t-clausen.dk

3
Нет, я не отрицал. Вероятно, это был кто-то, у кого есть принцип понизить все ответы, опубликованные до того, как ФП прояснит оставшиеся вопросы о правилах. У всех, кроме самого нового ответа, есть только одно отрицание. (Вероятно, это был Питер Тейлор, потому что он был здесь последний раз перед тем постом, и он жаловался на это.) Вы можете увидеть это, когда получите достаточно репутации. Вот, есть!
Адам

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-clausen.dk

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)
Нейл

Downvote без комментариев не круто, проголосовало
t-clausen.dk

@ Нейл спасибо большое! И с .map еще 1 байт сохранен
edc65

Да, мне было интересно, где вы собираетесь получить 0 для карты ...
Нил

1

APL (Дьялог) , 24 21 байт

Правила теперь уточнены.

Запрашивает время в виде 3-элементного списка.

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

Редактировать: Обновлено ( ), чтобы соответствовать новому результату для 10:33:06.

Попробуйте онлайн!

 запрос на ввод

60⊥ оценивать в базе-60

675÷⍨ разделить на 675

512× умножить на 512

 пол

()⊤ Преобразовать в (мнемосхема: перевернутая основа является антиосновой) следующую систему счисления:

16/2 повторить 2 шестнадцать раз (т.е. 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
  • Чтобы уменьшить помехи на экране, я предполагаю небольшое изменение исходного выражения, которое дает имя tлямбда- выражению

  • суффикс b указывает двоичный

объяснение

ПРИМЕЧАНИЕ. - читайте слева направо, оценивая справа налево

Читается как: 48 отбрасывается из двоичного представления пола 512 деления на 675 и умножается на 60 scalarFromVector на целочисленное приведение из разбиений в исходную строку ":"

Оценка:

":"\:x разбивает строку x (неявный аргумент лямбды) на символ ":" (Q использует "" для обозначения символа)

"I"$x приведение строки (строк) x к int (s) -> часы, минуты, секунды

60/:x использует базу 60 для вычисления одного значения из последовательности целых чисел -> всего секунд

(512%675)*x вычисляет коэффициент 512%675(% - это деление) и умножает секунды. 512% 675 - это упрощенная форма дроби (totalSecondsPerDay% 64K)

_ 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

Рубин, 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

Tweaks

  • Сохранение байта с использованием кодировки IBM-850.
  • Сохранено 3 байта с помощью $argn
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.