Znajdź najbliższe wskazówki zegara

15

Wyzwanie

Biorąc pod uwagę liczbę sekund po północy, wyprowadzaj najmniejszy kąt między dowolnymi dwoma wskazówkami na tarczy zegara, używając możliwie jak najmniej bajtów.

Możesz założyć, że liczba sekund jest zawsze mniejsza niż 86400. Kąty mogą być reprezentowane w stopniach lub radianach.

Rozwiązanie referencyjne znajduje się na stronie: http://ideone.com/eVdgC0

Przypadki testowe (wyniki w stopniach)

0 -> 0
60 -> 0.5
600 -> 5
3600 -> 0
5400 -> 45
6930 -> 84.75
50000 -> 63.333

Clarificarions

  • Zegar ma 3 wskazówki: godziny, minuty i sekundy.
  • Wszystkie wskazówki poruszają się w sposób ciągły, dlatego wskazówki godzinowe i minutowe można znaleźć między podziałkami na tarczy zegara.
Toto
źródło
Powiązane wyzwanie (tylko
wskazówki
1
Prawdopodobnie powinieneś sprecyzować, że na zegarze jest sekundnik.
isaacg
Czy możesz dodać jakieś przypadki testowe?
Beta Decay
1
W przypadku niektórych zegarów wskazówka minutowa przeskakuje do następnej minuty, gdy wskazówka sekundowa osiągnie szczyt. Na innych porusza się w sposób ciągły. Myślę, że to zegar, w którym porusza się w sposób ciągły? Ponadto, chociaż jest jasne, że po dokładnym przeczytaniu, początkowo uznałem, że „druga ręka” jest niejednoznaczna, ponieważ większość zegarów i tak ma co najmniej dwie wskazówki, więc dodanie „drugiej ręki” naprawdę dodaje trzecią rękę.
Reto Koradi,
1
@BetaDecay Na pewno. Mógłbym powiedzieć coś takiego: „Zegary mają trzy wskazówki: godziny, minuty i sekundy”.
Reto Koradi,

Odpowiedzi:

10

CJam, 36 35 34 32 30 bajtów

riP*30/_60/_C/]2m*::-:mc:mC$3=

Dane wyjściowe są w radianach. Sprawdziłem rozwiązania dla wszystkich 86400 możliwych wejść.

Wypróbuj online w interpretatorze CJam .

Pomysł

Ponieważ radianów to pełne okrążenie, każda minuta / sekunda na zegarze ma szerokość 2π / 60 = π / 30 radianów.

Tak więc podzielenie liczby sekund przez π / 30 daje pozycję drugiej ręki.

Wskazówka minutowa porusza się o jedną szóstą tempa drugiej ręki, więc podzielenie wyniku z góry przez 60 daje pozycję wskazówki minutowej.

Podobnie podzielenie ostatniego wyniku przez 12 daje pozycję wskazówki godzinowej.

Zauważ, że nasze trzy iloraz z góry niekoniecznie mieszczą się w przedziale [0,2π).

Obliczając wszystkie dziewięć możliwych różnic kątów rąk, otrzymujemy trzy 0 (odległość kątowa między dłonią a sobą) i sześć odległości między różnymi rękami.

Jeśli najbliższe ręce znajdują się na połowie, która nie obejmuje 12 , jedną z różnic z góry będzie pożądana moc wyjściowa (mod ).

Jednak o 01:55:30 (na przykład) wskazówka godzinowa znajduje się pod kątem 1,008 rad (57,75 stopni), a wskazówka minutowa pod kątem 5,812 rad (333,00 stopni) od 12 , co daje różnicę 4,804 rad (275,25 °). Odejmując ten wynik od pełnego okrążenia, otrzymujemy kąt zmierzony „w innym kierunku”, który wynosi 1,479 rad (84,75 rad).

Teraz, zamiast mapować każdy kąt θ w [0,2π) i warunkowo odejmować wynik od π , możemy po prostu obliczyć arccos (cos (θ)) , ponieważ cos jest zarówno okresowe, jak i parzyste, a arccos zawsze daje wartość w [ 0, π) .

Pomijając trzy najmniejsze wyniki (wszystkie zero), czwarta najmniejsza będzie pożądanym wynikiem.

Kod

ri                             e# Read an integer from STDIN.
  P*30/                        e# Multiply by π and divide by 30.
       _60/                    e# Divide a copy by 60.
           _C/                 e# Divide a copy by 12.
              ]2m*             e# Push the array of all pairs of quotients.
                  ::-          e# Replace each pair by its difference.
                     :mc       e# Apply cosine to each difference.
                        :mC    e# Apply arccosine to each cosine.
                           $3= e# Sort and select the fourth smallest element.

Alternatywna wersja (34 bajty)

rd6*_60/_C/]360f%2m*::m360X$f-+$6=

Dane wyjściowe wyrażone są w stopniach i nie są używane żadne funkcje trygonometryczne.

Wypróbuj online w interpretatorze CJam .

Dennis
źródło
9

Mathematica, 40 bajtów

Min@Abs@Mod[#{11,708,719}/120,360,-180]&

Objaśnienie: Niech tbędzie liczba sekund od północy. Pozycja każdej ręki to

hour: t/120 (mod 360)
min:  t/10 (mod 360)
sec:  6t (mod 360)

Aby obliczyć bezwzględną odległość kątową między xstopniami i ystopniami, możemy zmienić y - xo 360 stopni w zakresie, [-180, 180]a następnie przyjąć wartość bezwzględną. (Należy pamiętać, że nie ma ograniczeń xi y.), Więc funkcja ta po prostu oblicza różnice w parach t/10-t/120, 6t-t/10i 6t-t/120i robi.

jcai
źródło
Przykro mi, ale nie znam Mathematiki, ale czy faktycznie akceptuje argument lub zmienną na liczbę sekund od północy?
Winny
1
@ Winny Tak, jest to czysta funkcja (wskazana przez &), a pierwszy argument, który przekazano, jest nazywany wewnątrz #.
jcai
7

Python, 65

lambda n,l={720,60,1}:6*min((n/x-n/y)%60for x in l for y in{x}^l)

Dystans pokonany przez godzinę, minutę i wskazówkę sekundową, w jednostkach 1/60 koła, wynosi h,m,s = n/720, n/60, n/1. Możemy wziąć te mod 60, aby uzyskać ich pozycję na okręgu od 0do 60.

Jeśli weźmiemy ich różnicę mod 60, otrzymamy liczbę jednostek, które jedna jest przed drugą. Bierzemy wszystkie sześć możliwych różnic, znajdujemy min, a następnie mnożymy przez6 aby przeskalować do 360stopni.

Dwuwarstwowe rozumienie listy najpierw wybiera pierwszą rękę reprezentowaną przez 720,60 lub 1, a następnie wybiera drugą rękę z tego zestawu, a pierwszy wybór jest usuwany za pomocą zestawu xor.

Dokładnie przetestowałem to pod kątem kodu referencyjnego.

xnor
źródło
6

DO#, 163 152 bajty

Tworzy to każdą rękę dwa razy, aby liczyć na zawijanie, a następnie przechodzi przez każdą kombinację i znajduje minimalny kąt między rękami. Obliczenia są wykonywane w 60 działach, a następnie mnożone przez 6, aby uzyskać stopnie.

Wcięte dla jasności:

float F(int s){
    float b=60,c;
    float[]a={c=s/b/b%12*5,c+b,c=s/b%b,c+b,s%=60,s+b};
    for(s=36;s-->0;)
        b=s%6!=s/6&(c=(c=a[s%6]-a[s/6])<0?-c:c)<b?c:b;
    return b*6;
}

Przykładowe dane wyjściowe:

    0 seconds, 00:00:00, smallest angle is 0°
43200 seconds, 12:00:00, smallest angle is 0°
86399 seconds, 23:59:59, smallest angle is 0.09164429°
 3330 seconds, 00:55:30, smallest angle is 54.75°
39930 seconds, 11:05:30, smallest angle is 60.25001°
21955 seconds, 06:05:55, smallest angle is 65.49998°
21305 seconds, 05:55:05, smallest angle is 59.50001°
 5455 seconds, 01:30:55, smallest angle is 75.45831°
41405 seconds, 11:30:05, smallest angle is 44.95834°
Hand-E-Food
źródło
Ładne rozwiązanie, aby uwzględnić zawijanie
toto
2

TI-BASIC, 17 bajtów

min(cos⁻¹(cos(ΔList(Ans{6,.1,5!⁻¹,6

Używa Dennisa arccos(cos(do normalizacji odległości; jednak zamiast obliczać wszystkie odległości parami, oblicza tylko trzy potrzebne za pomocą ΔList([seconds],[minutes],[hours],[seconds].

Ten program oczekuje Degree trybu i zwraca odpowiedź w stopniach.

EDYCJA: 5!jest o jeden bajt krótszy niż 120.

lirtosiast
źródło