Trouver les aiguilles de l'horloge les plus proches

15

Défi

Étant donné un certain nombre de secondes après minuit, affichez le plus petit angle entre deux aiguilles sur un cadran d'horloge en utilisant le moins d'octets possible.

Vous pouvez supposer que le nombre de secondes est toujours inférieur à 86 400. Les angles peuvent être représentés en degrés ou en radians.

Une solution de référence se trouve sur: http://ideone.com/eVdgC0

Cas de test (résultats en degrés)

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

Clarifications

  • L'horloge a 3 aiguilles: heures, minutes et secondes.
  • Toutes les aiguilles bougent continuellement, ainsi les aiguilles des heures et des minutes peuvent être trouvées entre les graduations sur le cadran de l'horloge.
toto
la source
Défi associé (aiguilles des minutes et des heures uniquement, en degrés)
Sp3000
1
Vous devriez probablement préciser qu'il y a une trotteuse sur l'horloge.
isaacg
Pouvez-vous ajouter des cas de test?
Beta Decay
1
Sur certaines horloges, l'aiguille des minutes passe à la minute suivante lorsque l'aiguille des secondes atteint le sommet. Sur d'autres, il se déplace continuellement. Je pense que c'est une horloge où elle bouge continuellement? De plus, bien qu'il soit clair une fois que vous avez lu attentivement, j'ai d'abord trouvé ambiguë "seconde main", car la plupart des horloges ont au moins deux mains, donc l'ajout de la "seconde main" ajoute vraiment une troisième main.
Reto Koradi
1
@BetaDecay Certainement. J'aurais peut-être dit quelque chose comme: "Les horloges ont trois aiguilles: heures, minutes et secondes."
Reto Koradi

Réponses:

10

CJam, 36 35 34 32 30 octets

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

La sortie est en radians. J'ai vérifié les solutions pour toutes les 86400 entrées possibles.

Essayez-le en ligne dans l' interpréteur CJam .

Idée

Étant donné que radians est un tour complet, chaque intervalle minute / seconde sur l'horloge a une largeur de 2π / 60 = π / 30 radians.

Ainsi, la division du nombre de secondes par π / 30 donne la position de la trotteuse.

L'aiguille des minutes se déplace à un soixantième du rythme de l'aiguille des secondes, donc diviser le résultat par le haut par 60 donne la position de l'aiguille des minutes.

De même, la division du dernier résultat par 12 donne la position de l'aiguille des heures.

Notez que nos trois quotients ci-dessus ne sont pas nécessairement dans la plage [0,2π).

En calculant les neuf différences possibles d'angles des mains, nous obtenons trois 0 (distance angulaire entre une main et elle-même) et les six distances entre les différentes mains.

Si les mains les plus proches sont sur une moitié qui n'inclut pas 12 , l'une des différences par rapport au dessus sera la sortie souhaitée (mod ).

Cependant, à 01:55:30 (par exemple), l'aiguille des heures est à un angle de 1,008 rad (57,75 degrés) et l'aiguille des minutes à un angle de 5,812 rad (333,00 degrés) de 12 , ce qui donne une différence de 4,804 rad (275,25 degrés). En soustrayant ce résultat d'un tour complet, nous obtenons l'angle mesuré "dans l'autre sens", ce qui équivaut à 1,479 rad (84,75 rad).

Maintenant, plutôt que de cartographier chaque angle θ dans [0,2π) et de soustraire conditionnellement le résultat de π , nous pouvons simplement calculer arccos (cos (θ)) , car cos est à la fois périodique et pair, et arccos donne toujours une valeur dans [ 0, π) .

En sautant les trois plus petits résultats (tous à zéro), le quatrième plus petit sera la sortie souhaitée.

Code

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.

Version alternative (34 octets)

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

La sortie est en degrés et aucune fonction trigonométrique n'est utilisée.

Essayez-le en ligne dans l' interpréteur CJam .

Dennis
la source
9

Mathematica, 40 octets

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

Explication: Soit tun nombre de secondes depuis minuit. La position de chaque main est

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

Pour calculer la distance angulaire absolue entre xdegrés et ydegrés, nous pouvons modifier y - xde 360 degrés dans la plage [-180, 180], puis prendre la valeur absolue. (Notez qu'il n'y a aucune restriction sur xet y.) Donc, cette fonction calcule simplement les différences par pairet/10-t/120 , 6t-t/10et 6t-t/120et le fait.

jcai
la source
Désolé, pas familier avec Mathematica, mais cela accepte-t-il réellement un argument ou une variable pour le nombre de secondes depuis minuit?
Winny
1
@ Winin Oui, c'est une fonction pure (indiquée par &) et le premier argument qui lui est transmis est appelé à l'intérieur #.
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 distance parcourue par les heures, les minutes et les secondes, en unités de 1/60 du cercle, est h,m,s = n/720, n/60, n/1 . On peut prendre ces mod 60 pour obtenir leur position sur le cercle de 0à 60.

Si on prend leur différence mod 60, on obtient le nombre d'unités que l'une est devant l'autre. Nous prenons les six différences possibles, trouvons le min, puis multiplions par 6pour redimensionner en 360degrés.

La compréhension de liste à deux couches choisit d'abord la première main comme représenté par 720,60 ou 1, puis choisit l'autre main de cet ensemble avec le premier choix supprimé via l'ensemble xor.

J'ai testé cela de manière exhaustive par rapport au code de référence.

xnor
la source
6

C #, 163 152 octets

Cela crée chaque main deux fois pour compter pour l'encerclement, puis parcourt chaque combinaison et trouve l'angle minimum entre les mains. Les calculs sont effectués en 60 divisions, puis multipliés par 6 pour obtenir des degrés.

En retrait pour plus de clarté:

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

Exemple de sortie:

    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
la source
Belle solution pour prendre en compte le bouclage
toto
2

TI-BASIC, 17 octets

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

Utilise Dennis arccos(cos(pour normaliser les distances; cependant, plutôt que de calculer toutes les distances par paires, il ne calcule que les trois nécessaires en utilisantΔList([seconds],[minutes],[hours],[seconds] .

Ce programme attend le Degreemode et renvoie la réponse en degrés.

EDIT: 5!est un octet plus court que 120.

lirtosiast
la source