Jaki jest czas binarny?

14

Jaki jest czas binarny?

Wszyscy wiedzą, jaki jest normalny czas. Jest tam w prawym górnym rogu (lub gdziekolwiek go umieścisz) na ekranie. Ale pytanie, które ludzie rzadko zadają sobie, brzmi: co to jest czas binarny ?

Czas binarny

Czas binarny (True Binary Time) działa, czytając najpierw najbardziej znaczący bit (MSB) z liczby. Jeśli ta liczba jest 0, wyrażony czas jest przed południem. Jeśli ta liczba to 1, wyrażony czas jest po południu. Następny bit dzieli połowę dnia, gdy pierwszy bit jest wyrażony w dwóch kolejnych równych połówkach, tym razem 6 godzin. Następujący bit dzieli się na 3 godziny, następne 90 minut i tak dalej. Czasy takie jak 12:00:00tam, gdzie wydaje się, że nie powinno tak być, stają się 1.

Rozumiem tylko ten dziwny system pomiaru czasu, dlatego potrzebuję programu, który by go przekonwertował. Ale ponieważ liczby binarne to Base-2, a 2 to mała liczba, twój program musi być jak najkrótszy.

Wymagania

  • Twój program powinien zająć trochę czasu (tak jak 24 godziny) jako dane wejściowe i wyjściowe odpowiadającej im liczby binarnej.
  • Numer wyjściowy powinien mieć 16-bitową dokładność (liczba powinna składać się z 16 cyfr).
  • Nie możesz użyć wbudowanego, który wykonuje całą konwersję za Ciebie.
  • Powinieneś podłogę, jeśli trzeba ją zaokrąglić.

Zasady

  • Standardowe luki są zabronione.
  • Twój program nie powinien nic pisać STDERR.

Przypadki testowe

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

Punktacja

Aby wygrać, jak wspomniałem wcześniej, musisz mieć najmniej bajtów.

Zgłoszenia

Aby upewnić się, że twoja odpowiedź się pojawi, zacznij od nagłówka, korzystając z następującego szablonu Markdown:

# Language Name, N bytes

gdzie Njest rozmiar twojego zgłoszenia. Jeśli poprawić swój wynik, to może zachować stare porachunki w nagłówku, uderzając je przez. Na przykład:

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

Jeśli chcesz umieścić w nagłówku wiele liczb (np. Ponieważ twój wynik to suma dwóch plików lub chcesz osobno wymienić kary za flagi tłumacza), upewnij się, że rzeczywisty wynik jest ostatnią liczbą w nagłówku:

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

Możesz także ustawić nazwę języka jako link, który pojawi się we fragmencie tabeli wyników:

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

Tabela liderów

Oto fragment kodu, który pozwala wygenerować zarówno zwykłą tabelę wyników, jak i przegląd zwycięzców według języka.

George Gibson
źródło
3
Czy mogę wprowadzić jako [hour, minute, second]? Nie lubimy ograniczać formatu wejściowego.
Leaky Nun
2
Jak robi 09:57:30się 0110110000000000?
Leaky Nun
2
16 bitów może reprezentować tylko 65536 wartości. Dziennie jest 86400 sekund. Jak powinniśmy reprezentować wszystko, co nie pasuje dokładnie do reprezentacji binarnej?
PurkkaKoodari
Czy możemy zwrócić wynik jako listę 16 liczb?
Adám
@ Adám Tak, możesz.
George Gibson

Odpowiedzi:

1

MATL , 15 bajtów

YOtk-KWW*k16&YB

Używa wbudowanego do konwertowania ciągu reprezentującego czas na szeregową datę / godzinę, co jest dozwolone przez wyzwanie.

Wypróbuj online!

Wyjaśnienie

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
źródło
5

CJam, 20 bajtów

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

Zestaw testowy.

Wyjaśnienie

Wykorzystuje fakt, że 65536 (2 16 ) powyżej 86400 (liczba sekund w ciągu dnia) upraszcza się do 512 w stosunku do 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
źródło
3

Pyth, 31 27 bajtów

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

Zestaw testowy.

Konwertuje dane wejściowe na liczbę sekund, które pomnożono przez współczynnik 2^16 / 24*60*60 , a następnie piętro i przekonwertuj na 16-bitowy plik binarny.

Zaoszczędzono 4 bajty, upraszczając 65536/86400do512/675 (głupie mnie).

Wejście wyjście

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
Leaky Nun
źródło
Czy możesz uzasadnić „ a potem piętro ”?
Peter Taylor
@PeterTaylor Co powinienem zamiast tego zrobić?
Leaky Nun
4
Poczekaj, aż specyfikacja zostanie ujednoznaczniona, zanim opublikujesz odpowiedź.
Peter Taylor
@PeterTaylor Właściwy sposób zaokrąglania jest widoczny przez 10:33:06.
Adám
@ Adám, niezupełnie, ponieważ daje to tę samą wydajność przy podłodze i zaokrągleniu do najbliższego.
Peter Taylor
3

TSQL (sqlserver 2012), 103 bajty

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

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

Wypróbuj online

Nie golfił

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 bajtów

Zawiera także inną wersję bez zmiennej @x, ale była ona o kilka bajtów dłuższa. W tym wersja bez golfa dla zainteresowanych:

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
źródło
To nie wygląda na golfa. Nie możesz usunąć dużej ilości białych znaków?
Adám
@ Adám jest bardzo nieprzyzwoity, użyłem innych metod niż standardowe, aby skrócić skrypt, a nawet wypróbowałem inną metodę. Właśnie przypadkowo wstawiłem spację podczas kopiowania mojej odpowiedzi do codegolf (tylko jeden dodatkowy). Chciałem umieścić tam podział linii, ale zamiast tego zdecydowałem się go umieścić po KILKU. Usuwanie przestrzeni i zastanawianie się, czy naprawdę przegłosowałeś mnie dla tej dodatkowej przestrzeni
t-clausen.dk
@ Adám, a jeśli patrzysz na drugą metodę, nie jest ona golfa (z wyjątkiem liczby znaków), ponieważ nie jest to moja rzeczywista odpowiedź. Po prostu inna, bardziej obliczeniowa metoda rozwiązania tego problemu
t-clausen.dk
3
Nie, nie przegłosowałem. Prawdopodobnie był to ktoś, kto ma zasadę głosowania za odrzuceniem wszystkich odpowiedzi, które zostały opublikowane, zanim PO wyjaśni wyjaśnienia nierozstrzygniętych pytań dotyczących zasad. Wszystkie oprócz najnowszej odpowiedzi mają dokładnie jedną opinię. (Prawdopodobnie był to Peter Taylor, ponieważ był tu ostatni przed tym postem i narzekał na to.) Możesz to zobaczyć, gdy dostaniesz wystarczającą liczbę powtórzeń. Masz trochę!
Adám
2

JavaScript (ES6), 72 76 bajtów

Edytuj 4 bajty, zapisz thx @Neil

Nadal niejasne co do zaokrąglenia. Ten zostaje obcięty i jest w porządku.

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>

edc65
źródło
próbuję dowiedzieć się, dlaczego zostało to przegłosowane
t-clausen.dk
t=>([h,m,s]=t.split`:`,(+h+m/60+s/3600)*8192/3|65536).toString(2).slice(1)oszczędza 2 bajty, ale reduceidzie o jeden bajt dalej:t=>(t.split`:`.reduce((n,m)=>+m+n*60)*512/675|65536).toString(2).slice(1)
Neil
Głosowanie bez komentarza nie jest fajne, głosowanie pozytywne
t-clausen.dk
@ Nee bardzo dziękuję! I przy zapisanym jeszcze 1 bajcie
.mapy
Huh, zastanawiałem się, skąd weźmiesz 0 dla mapy ...
Neil
1

APL (Dyalog) , 24 21 bajtów

Zasady zostały teraz wyjaśnione.

Monity o czas w postaci listy 3-elementowej.

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

Edycja: Zaktualizowano ( ), aby dopasować nowy wynik dla 10:33:06.

Wypróbuj online!

 monit o wprowadzenie

60⊥ ocenić w podstawie 60

675÷⍨ podzielić przez 675

512× pomnóż przez 512

 piętro

()⊤ Przekonwertuj na (mnemonic: odwrócona baza jest anty-bazowa) na następujący system liczbowy:

16/2 replikacja 2 szesnaście razy (tj. 16-bitowy plik binarny)   

Adám
źródło
0

P, 32 bajty

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
  • Aby zmniejszyć bałagan na wyświetlaczu, zakładam niewielką modyfikację pierwotnego wyrażenia, które nadaje nazwę tlambdzie

  • Przyrostek b wskazuje na binarny

Wyjaśnienie

UWAGA. - czytaj od lewej do prawej, ocenia od prawej do lewej

Odczytuje jako: 48 upuszczenie z binarnej reprezentacji piętra 512 podzielonych przez 675 i pomnożonych przez 60 scalarFromVector przez liczbę całkowitą rzutowaną z podziałów na oryginalny ciąg „:”

Ocena:

":"\:x dzieli ciąg x (niejawny argument lambda) na znak „:” (Q używa znaku „” do oznaczenia znaku)

"I"$x Rzuć ciąg (y) x na int (s) -> godziny, minuty, sekundy

60/:x używa podstawy 60 do obliczenia pojedynczej wartości z sekwencji liczb całkowitych -> sekund łącznie

(512%675)*x oblicza stosunek 512%675(% jest dzieleniem) i mnoży sekundy. 512% 675 to uproszczona forma ułamka (totalSecondsPerDay% 64K)

_ x wskazuje podłogę pływaka x

0b\:x oblicza binarną reprezentację x (64 bity)

48_ x upuszczamy pierwsze 48 bitów, więc mamy naszą reprezentację 16 bitów

Przykład (x = „01:30:00”). UWAGA. - „/” oznacza komentarz do końca wiersza

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

J. Sendra
źródło
0

Rubinowy, 75 bajtów

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

Wydaje mi się, że musi istnieć krótsza metoda przeliczania czasu na sekundy, ale to wszystko, co mogłem wymyślić.

mrwillihog
źródło
0

Python, 45 bajtów

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

Wpadłem na ten 512/675czynnik, a potem zobaczyłem, że inni zrobili to samo.

Karl Napf
źródło
0

C, 91 bajtów

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
źródło
0

PHP, 47 46 43 bajtów

Wykorzystuje kodowanie IBM-850.

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

Uruchom tak:

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

Poprawki

  • Zapisano bajt przy użyciu kodowania IBM-850.
  • Zaoszczędzono 3 bajty $argn
aross
źródło