Qual é o tempo binário?

14

Qual é o tempo binário?

Todo mundo sabe que horas são. Está lá em cima, no canto superior direito (ou onde quer que você o coloque) da tela. Mas uma pergunta que as pessoas raramente parecem se perguntar é: Qual é o tempo binário ?

Tempo binário

O tempo binário (tempo binário verdadeiro) funciona lendo primeiro o bit mais significativo (MSB) do número. Se esse número for 0, o horário expresso é antes do meio dia. Se esse número for 1, o tempo expresso será após o meio dia. O próximo bit divide a metade do dia em que o primeiro bit é expresso em mais duas metades iguais, desta vez de 6 horas. O bit a seguir se divide em 3 horas, nos próximos 90 minutos e assim por diante. Tempos como 12:00:00, onde parece que não deveria ser nenhum, se tornam 1.

Só consigo entender esse estranho sistema de tempo, então preciso de um programa para converter isso para mim. Mas como os números binários são Base-2 e 2 é um número pequeno, seu programa deve ser o mais curto possível.

Exigências

  • Seu programa deve levar um tempo (como 24 horas) como entrada e saída do número de tempo binário correspondente.
  • O número de saída deve ter precisão de 16 bits (o número deve ter 16 dígitos).
  • Você não pode usar um built-in que faça toda essa conversão para você.
  • Você deve andar se precisar ser arredondado.

Regras

Casos de teste

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

Pontuação

Para ganhar, como mencionei anteriormente, você deve ter o mínimo de bytes.

Submissões

Para garantir que sua resposta seja exibida, inicie-a com um título, usando o seguinte modelo de remarcação:

# Language Name, N bytes

onde Nestá o tamanho do seu envio. Se você melhorar sua pontuação, poderá manter as pontuações antigas no título, identificando-as. Por exemplo:

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

Se você quiser incluir vários números no cabeçalho (por exemplo, porque sua pontuação é a soma de dois arquivos ou você deseja listar as penalidades do sinalizador de intérpretes separadamente), verifique se a pontuação real é o último número no cabeçalho:

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

Você também pode transformar o nome do idioma em um link que será exibido no snippet do placar de líderes:

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

Entre os melhores

Aqui está um snippet de pilha para gerar uma classificação regular e uma visão geral dos vencedores por idioma.

George Gibson
fonte
3
Posso inserir como [hour, minute, second]? Não gostamos de restringir o formato de entrada.
Lea16 Freira
2
Como é que 09:57:30fazem 0110110000000000?
Lea16 Freira
2
16 bits podem representar apenas valores 65536. Existem 86400 segundos em um dia. Como devemos representar algo que não corresponde exatamente a uma representação binária?
PurkkaKoodari
Podemos retornar o resultado como uma lista de 16 números?
Adám 01/06/19
@ Adám Sim, você pode.
George Gibson

Respostas:

1

MATL , 15 bytes

YOtk-KWW*k16&YB

Usa um builtin para converter uma sequência que representa a hora em um número de data / hora de série, o que é permitido pelo desafio.

Experimente online!

Explicação

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
Luis Mendo
fonte
5

CJam, 20 bytes

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

Suíte de teste.

Explicação

Utiliza o fato de que 65536 (2 16 ) acima de 86400 (o número de segundos em um dia) simplifica para 512 acima de 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.
Martin Ender
fonte
3

Pitão, 31 27 bytes

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

Suíte de teste.

Converte a entrada em um número de segundos passados, multiplique por um fator de 2^16 / 24*60*60e, em seguida, aplique e converta em binário de 16 bits.

Salvo 4 bytes, simplificando 65536/86400em 512/675(me estúpido).

Entrada / saída

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
Freira Furada
fonte
Você pode justificar " e depois andar "?
27568 Peter
@PeterTaylor O que devo fazer?
Lea16 Freira
4
Aguarde até que a especificação seja desambiguada antes de postar uma resposta.
22868 Peter
@ Petereteray A maneira correta de arredondar é aparente por 10:33:06.
Adám
@ Adám, na verdade não, porque isso dá a mesma saída com andar e arredondar para o mais próximo.
27568 Peter
3

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 @

Experimente online

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

Também incluiu uma versão diferente sem a variável @x, porém foi mais alguns bytes. Incluindo a versão ungolfed para os interessados:

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 @
t-clausen.dk
fonte
Isso não parece jogar golfe. Você não pode remover muitos espaços em branco?
Adám
@ Adám é muito goolfed, usei métodos diferentes do padrão para tornar o script mais curto e até tentei um método diferente. Acabei de colocar um espaço em branco acidental ao lidar com a minha resposta no codegolf (apenas um extra). Eu queria colocar uma quebra de linha lá, mas decidi colocá-la depois de WHILE. Remover o espaço e se perguntando se você realmente me downvoted para esse único espaço extra
t-clausen.dk
@ Adám e se você estiver olhando para o segundo método, ele não é jogado de golfe (exceto a contagem de caracteres), pois não é a minha resposta real. Apenas um método mais cálculo diferente de resolvê-lo
t-clausen.dk
3
Não, eu não voto negativo. Provavelmente foi alguém que tem um princípio para reduzir a votação de todas as respostas postadas antes do OP esclarecer questões pendentes sobre regras. Todos, exceto a resposta mais recente, têm exatamente um voto negativo. (Provavelmente foi Peter Taylor, porque ele esteve aqui pela última vez antes desse post, e está reclamando disso.) Você pode ver isso quando obtiver representantes suficientes. Aqui, tem alguns!
Adám
2

JavaScript (ES6), 72 76 bytes

Editar 4 bytes, salvar thx @Neil

Ainda não está claro sobre o arredondamento. Este trunca e tudo bem.

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

Teste

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>

edc65
fonte
estou tentando descobrir por que isso foi
rebaixado
t=>([h,m,s]=t.split`:`,(+h+m/60+s/3600)*8192/3|65536).toString(2).slice(1)economiza 2 bytes, mas reducevai mais um byte:t=>(t.split`:`.reduce((n,m)=>+m+n*60)*512/675|65536).toString(2).slice(1)
Neil
O voto
negativo
@ Neil muito obrigado! E com .map mais 1 byte salvo
edc65
Huh, eu queria saber onde estava indo para obter o 0 a partir do mapa ...
Neil
1

APL (Dyalog) , 24 21 bytes

As regras já foram esclarecidas.

Solicita tempo como lista de 3 elementos.

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

Editar: Atualizado ( ) para corresponder a um novo resultado para 10:33:06.

Experimente online!

 solicitação de entrada

60⊥ avaliar na base-60

675÷⍨ dividir por 675

512× multiplicar por 512

 chão

()⊤ Converter para (mnemônico: a base invertida é anti-base) o seguinte sistema numérico:

16/2 replicar 2 dezesseis vezes (ou seja, binário de 16 bits)   

Adão
fonte
0

Q, 32 bytes

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

Teste

   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
  • Para reduzir a desordem da exibição, assumo uma ligeira modificação na expressão original, que dá nome tao lambda

  • O sufixo b indica binário

Explicação

NOTA.- leia da esquerda para a direita, avalia da direita para a esquerda

Lê como: 48 são eliminados da representação binária do piso de 512 divideb por 675 e multiplicados por 60 scalarFromVector sobre o número inteiro convertido das divisões na sequência original ":"

Avaliação:

":"\:x divide a string x (argumento implícito do lambda) no caractere ":" (Q usa "" para indicar char)

"I"$x converter string (s) x para int (s) -> horas, minutos, segundos

60/:x usa a base 60 para calcular um único valor a partir de uma sequência de entradas -> total de segundos

(512%675)*x calcula a proporção 512%675(% é dividida) e multiplica segundos. 512% 675 é a forma simplificada da fração (totalSecondsPerDay% 64K)

_ x indica piso da bóia x

0b\:x calcula a representação binária de x (64 bits)

48_ x soltar os primeiros 48 bits, então temos nossa representação de 16 bits

Exemplo (x = "01:30:00"). NOTA.- "/" indica o comentário no final da linha

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

J. Sendra
fonte
0

Ruby, 75 bytes

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

Eu sinto que deve haver um método mais curto de converter o tempo em segundos, mas isso é tudo que eu conseguia pensar.

mrwillihog
fonte
0

Python, 45 bytes

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

Eu mesmo inventei o 512/675fator e vi os outros fazerem o mesmo.

Karl Napf
fonte
0

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++;}
Coates
fonte
0

PHP, 47 46 43 bytes

Usa a codificação IBM-850.

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

Execute assim:

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

Tweaks

  • Salve um byte usando a codificação IBM-850.
  • Salva 3 bytes usando $argn
aross
fonte