Trova le lancette dell'orologio più vicine


15

Sfida

Dato un numero di secondi trascorsi a mezzanotte, emette l'angolo più piccolo tra due lancette su un quadrante di orologio, usando il minor numero di byte possibile.

Si può presumere che il numero di secondi sia sempre inferiore a 86400. Gli angoli possono essere rappresentati in gradi o radianti.

Una soluzione di riferimento è disponibile all'indirizzo: http://ideone.com/eVdgC0

Casi di prova (risultati in gradi)

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

Clarificarions

  • L'orologio ha 3 lancette: ore, minuti e secondi.
  • Tutte le lancette si muovono continuamente, quindi le lancette delle ore e dei minuti si trovano tra le graduazioni sul quadrante dell'orologio.

Sfida correlata (solo lancette dei minuti e delle ore, in gradi)
Sp3000,

1
Probabilmente dovresti specificare che c'è una lancetta dei secondi sull'orologio.
isaacg,

Puoi aggiungere alcuni casi di test?
Decadimento beta

1
In alcuni orologi, la lancetta dei minuti passa al minuto successivo quando la lancetta dei secondi raggiunge la cima. Su altri, si muove continuamente. Immagino che questo sia un orologio in cui si muove continuamente? Inoltre, mentre è chiaro una volta che leggi attentamente, inizialmente ho trovato ambigua la "lancetta dei secondi", perché la maggior parte degli orologi ha almeno due lancette, quindi l'aggiunta della "lancetta dei secondi" aggiunge davvero una terza lancetta.
Reto Koradi,

1
@BetaDecay Certamente. Avrei potuto dire qualcosa del tipo: "Gli orologi hanno tre lancette: ore, minuti e secondi".
Reto Koradi,

Risposte:


10

CJam, 36 35 34 32 30 byte

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

L'output è in radianti. Ho verificato le soluzioni per tutti gli 86400 possibili input.

Provalo online nell'interprete CJam .

Idea

Poiché i radianti sono un giro completo, ogni intervallo minuto / secondo dell'orologio è largo 2π / 60 = π / 30 radianti.

Pertanto, dividendo il numero di secondi per π / 30 si ottiene la posizione della lancetta dei secondi.

La lancetta dei minuti si sposta di un sessantesimo del ritmo della lancetta dei secondi, quindi dividendo il risultato dall'alto per 60 si ottiene la posizione della lancetta dei minuti.

Allo stesso modo, dividendo l'ultimo risultato per 12 si ottiene la posizione della lancetta delle ore.

Si noti che i nostri tre quozienti dall'alto non sono necessariamente nell'intervallo [0,2π).

Calcolando tutte e nove le possibili differenze degli angoli delle mani, otteniamo tre 0 (distanza angolare tra una mano e se stessa) e le sei distanze tra le diverse mani.

Se le mani più vicine sono su una metà che non include 12 , una delle differenze dall'alto sarà l'output desiderato (mod ).

Tuttavia, alle 01:55:30 (ad esempio), la lancetta delle ore si trova ad un angolo di 1,008 rad (57,75 gradi) e la lancetta dei minuti ad un angolo di 5,812 rad (333,00 gradi) da 12 , dando una differenza di 4,804 rad (275,25 gradi). Sottraendo questo risultato da un giro completo, otteniamo l'angolo misurato "nell'altra direzione", che equivale a 1.479 rad (84.75 rad).

Ora, invece di mappare ogni angolo θ in [0,2π) e sottrarre condizionalmente il risultato da π , possiamo semplicemente calcolare arccos (cos (θ)) , poiché cos è sia periodico che uniforme, e arccos produce sempre un valore in [ 0, π) .

Saltando i tre risultati più piccoli (tutti zero), il quarto più piccolo sarà l'output desiderato.

Codice

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.

Versione alternativa (34 byte)

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

L'output è in gradi e non vengono utilizzate funzioni trigonometriche.

Provalo online nell'interprete CJam .


9

Mathematica, 40 byte

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

Spiegazione: Lasciare tessere il numero di secondi dalla mezzanotte. La posizione di ogni mano è

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

Per calcolare la distanza angolare assoluta tra xgradi e ygradi, possiamo mod y - xdi 360 nell'intervallo [-180, 180]e quindi prendere il valore assoluto. (Si noti che non v'è alcuna limitazione xe y.) Quindi, questa funzione è sufficiente calcola le differenze a coppie t/10-t/120, 6t-t/10e 6t-t/120e lo fa.


Siamo spiacenti, non ho familiarità con Mathematica, ma questo accetta effettivamente un argomento o una variabile per il numero di secondi dalla mezzanotte?
Winny,

1
@Winny Sì, è una funzione pura (indicata da &) e il primo argomento che viene passato viene chiamato dentro come #.
jcai,

7

Python, 65 anni

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

La distanza percorsa dall'ora, dai minuti e dalla lancetta dei secondi, in unità di 1/60 del cerchio, è h,m,s = n/720, n/60, n/1. Possiamo prendere questi mod 60 per ottenere la loro posizione sul cerchio da 0a 60.

Se prendiamo la loro differenza mod 60, otteniamo il numero di unità che uno è di fronte all'altro. Prendiamo tutte e sei le differenze possibili, troviamo il minimo, quindi moltiplichiamo 6per ridimensionare in 360gradi.

La comprensione dell'elenco a due livelli prima sceglie la prima mano come rappresentata da 720, 60o 1, quindi sceglie l'altra mano da quella serie con la prima scelta rimossa tramite la serie xor.

L'ho provato esaurientemente rispetto al codice di riferimento.


6

C #, 163 152 byte

Questo crea ogni mano due volte per contare per avvolgersi, quindi scorre attraverso ogni combinazione e trova l'angolo minimo tra le mani. I calcoli vengono eseguiti in 60 divisioni, quindi moltiplicati per 6 per ottenere gradi.

Rientrato per chiarezza:

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

Esempio di output:

    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°

Bella soluzione per tenere conto di wrap around
Toto

2

TI-BASIC, 17 byte

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

Usa Dennis arccos(cos(per normalizzare le distanze; tuttavia, anziché calcolare tutte le distanze a coppie, calcola solo le tre necessarie usando ΔList([seconds],[minutes],[hours],[seconds].

Questo programma prevede la Degreemodalità e restituisce la risposta in gradi.

EDIT: 5!è un byte più corto di 120.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.