Encuentra las manecillas del reloj más cercanas

15

Desafío

Dado un número de segundos después de la medianoche, emite el ángulo más pequeño entre dos manos en una esfera del reloj, utilizando la menor cantidad de bytes posible.

Puede suponer que el número de segundos siempre es menor que 86400. Los ángulos pueden representarse en grados o radianes.

Una solución de referencia está en: http://ideone.com/eVdgC0

Casos de prueba (resultados en grados)

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

Clarificarions

  • El reloj tiene 3 manecillas: horas, minutos y segundos.
  • Todas las manecillas se mueven continuamente, por lo tanto, se pueden encontrar manecillas de hora y minutos entre graduaciones en la esfera del reloj.
toto
fuente
Desafío relacionado (minutos y horas solamente, en grados)
Sp3000
1
Probablemente deberías especificar que hay una manecilla de segundos en el reloj.
isaacg
¿Puedes agregar algunos casos de prueba?
Beta Decay
1
En algunos relojes, la manecilla de los minutos salta al siguiente minuto cuando la manecilla de los segundos llega a la cima. En otros, se mueve continuamente. Me imagino que este es un reloj donde se mueve continuamente. Además, aunque está claro una vez que lees atentamente, inicialmente encontré ambiguo la "segunda mano", porque la mayoría de los relojes tienen al menos dos manos de todos modos, por lo que agregar la "segunda mano" realmente agrega una tercera mano.
Reto Koradi
1
@BetaDecay Ciertamente. Podría haber dicho algo como: "Los relojes tienen tres manecillas: horas, minutos y segundos".
Reto Koradi

Respuestas:

10

CJam, 36 35 34 32 30 bytes

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

La salida está en radianes. He verificado las soluciones para todas las 86400 entradas posibles.

Pruébelo en línea en el intérprete de CJam .

Idea

Dado que radianes es una vuelta completa, cada intervalo de minuto / segundo en el reloj es de 2π / 60 = π / 30 radianes de ancho.

Por lo tanto, dividiendo el número de segundos por π / 30 produce la posición de la manecilla de segundos.

La manecilla de minutos se mueve a la sexagésima parte del ritmo de la manecilla de segundos, dividiendo el resultado de arriba por 60 produce la posición de la manecilla de minutos.

Del mismo modo, dividiendo el último resultado por 12 produce la posición de la manecilla de la hora.

Tenga en cuenta que nuestros tres cocientes de arriba no están necesariamente en el rango [0,2π).

Al calcular las nueve diferencias posibles de los ángulos de las manos, obtenemos tres 0 (distancia angular entre una mano y sí mismo) y las seis distancias entre las diferentes manos.

Si las manos más cercanas están en una mitad que no incluye 12 , una de las diferencias de arriba será la salida deseada (mod ).

Sin embargo, a las 01:55:30 (por ejemplo), la manecilla de la hora está en un ángulo de 1.008 rad (57.75 grados) y la manecilla de los minutos en un ángulo de 5.812 rad (333.00 grados) desde 12 , dando una diferencia de 4.804 rad (275,25 grados). Al restar este resultado de una vuelta completa, obtenemos el ángulo medido "en la otra dirección", que equivale a 1.479 rad (84.75 rad).

Ahora, en lugar de mapear cada ángulo θ en [0,2π) y restar condicionalmente el resultado de π , simplemente podemos calcular arccos (cos (θ)) , ya que cos es tanto periódico como par, y arccos siempre produce un valor en [ 0, π) .

Saltando los tres resultados más pequeños (todos cero), el cuarto más pequeño será el resultado deseado.

Código

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.

Versión alternativa (34 bytes)

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

La salida está en grados y no se utilizan funciones trigonométricas.

Pruébelo en línea en el intérprete de CJam .

Dennis
fuente
9

Mathematica, 40 bytes

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

Explicación: Sea el tnúmero de segundos desde la medianoche. La posición de cada mano es

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

Para calcular la distancia angular absoluta entre xgrados y ygrados, podemos modificar y - x360 en el rango [-180, 180]y luego tomar el valor absoluto. (Tenga en cuenta que no hay ninguna restricción en xe y.) Así que esta función solo calcula las diferencias por pares t/10-t/120, 6t-t/10y 6t-t/120, y lo hace.

jcai
fuente
Lo sentimos, no estoy familiarizado con Mathematica, pero ¿esto realmente acepta un argumento o variable por la cantidad de segundos desde la medianoche?
Winny
1
@Winny Sí, es una función pura (indicada por &) y el primer argumento que se pasa se denomina adentro como #.
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)

La distancia recorrida por hora, minuto y segundero, en unidades de 1/60 del círculo, son h,m,s = n/720, n/60, n/1. Podemos tomar estos mod 60 para obtener su posición en el círculo de 0a 60.

Si tomamos su diferencia mod 60, obtenemos el número de unidades que una está frente a la otra. Tomamos las seis diferencias posibles, encontramos el mínimo y luego lo multiplicamos 6para reescalar a 360grados.

La comprensión de la lista de dos capas primero elige la primera mano como representada por 720, 60o 1, luego, elige la otra mano de ese conjunto con la primera opción eliminada a través del conjunto xor.

Probé esto exhaustivamente contra el código de referencia.

xnor
fuente
6

C #, 163 152 bytes

Esto crea cada mano dos veces para contar para envolver, luego recorre cada combinación y encuentra el ángulo mínimo entre manos. Los cálculos se realizan en 60 divisiones, luego se multiplican por 6 para obtener grados.

Sangrado por claridad:

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;
}

Salida de ejemplo:

    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
fuente
Buena solución para dar cuenta de la envoltura
toto
2

TI-BASIC, 17 bytes

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

Utiliza Dennis's arccos(cos( para normalizar distancias; sin embargo, en lugar de calcular todas las distancias por pares, solo calcula las tres necesarias usando ΔList([seconds],[minutes],[hours],[seconds].

Este programa espera Degree modo y devuelve la respuesta en grados.

EDITAR: 5!es un byte más corto que 120.

lirtosiast
fuente