Finde die nächsten Uhrzeiger

15

Herausforderung

Geben Sie nach Mitternacht den kleinsten Winkel zwischen zwei Zeigern auf einem Zifferblatt aus, und verwenden Sie dabei so wenige Bytes wie möglich.

Sie können davon ausgehen, dass die Anzahl der Sekunden immer kleiner als 86400 ist. Winkel können in Grad oder Bogenmaß angegeben werden.

Eine Referenzlösung finden Sie unter: http://ideone.com/eVdgC0

Testfälle (Ergebnisse in Grad)

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

Klarstellungen

  • Die Uhr hat 3 Zeiger: Stunden, Minuten und Sekunden.
  • Alle Zeiger bewegen sich kontinuierlich, so dass Stunden- und Minutenzeiger zwischen den Teilstrichen auf dem Zifferblatt zu finden sind.
toto
quelle
Verwandte Herausforderung (nur Minuten- und Stundenzeiger, in Grad)
Sp3000
1
Sie sollten wahrscheinlich genau wissen, dass es einen Sekundenzeiger auf der Uhr gibt.
Isaacg
Können Sie einige Testfälle hinzufügen?
Beta Decay
1
Bei einigen Uhren springt der Minutenzeiger zur nächsten Minute, wenn der Sekundenzeiger die Spitze erreicht. Bei anderen bewegt es sich kontinuierlich. Ich denke, das ist eine Uhr, bei der sie sich kontinuierlich bewegt. Auch wenn es klar ist, wenn Sie sorgfältig gelesen haben, fand ich "Sekundenzeiger" anfangs mehrdeutig, da die meisten Uhren sowieso mindestens zwei Zeiger haben, so dass das Hinzufügen des "Sekundenzeigers" wirklich einen dritten Zeiger hinzufügt.
Reto Koradi
1
Sicherlich. Ich hätte sagen können: "Die Uhr hat drei Zeiger: Stunden, Minuten und Sekunden."
Reto Koradi

Antworten:

10

CJam, 36 35 34 32 30 Bytes

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

Die Ausgabe erfolgt im Bogenmaß. Ich habe die Lösungen für alle 86400 möglichen Eingaben überprüft.

Probieren Sie es online im CJam-Interpreter aus .

Idee

Da Radiant eine volle Runde ist, ist jedes Minuten / Sekunden-Intervall auf der Uhr 2π / 60 = π / 30 Radiant breit.

Teilen Sie also die Anzahl der Sekunden durch π / 30 Position des Sekundenzeigers.

Der Minutenzeiger bewegt sich um ein Sechzigstel der Geschwindigkeit des Sekundenzeigers. Wenn Sie also das Ergebnis von oben durch 60 dividieren, erhalten Sie die Position des Minutenzeigers.

Ebenso ergibt die Division des letzten Ergebnisses durch 12 die Position des Stundenzeigers.

Beachten Sie, dass unsere drei Quotienten von oben nicht unbedingt im Bereich liegen [0,2π] liegt.

Durch Berechnung aller neun möglichen Unterschiede der Zeigerwinkel erhalten wir drei 0 ‚s (Winkelabstand zwischen einer Hand und selbst) und den sechs Abstände zwischen den verschiedenen Händen.

Wenn sich die nächsten Hände auf einer Hälfte befinden, die 12 nicht enthält , ist einer der Unterschiede von oben die gewünschte Ausgabe (mod ).

Um 01:55:30 (zum Beispiel) befindet sich der Stundenzeiger jedoch in einem Winkel von 1,008 rad (57,75 Grad) und der Minutenzeiger in einem Winkel von 5,812 rad (333,00 Grad) von 12 , was eine Differenz von 4,804 rad ergibt (275,25 Grad). Durch Subtrahieren dieses Ergebnisses von einer vollen Runde erhalten wir den "in der anderen Richtung" gemessenen Winkel, der 1,479 rad (84,75 rad) entspricht.

Anstatt nun jeden Winkel θ in [0,2π] abzubilden und das Ergebnis von π bedingt zu subtrahieren , können wir einfach Arccos (cos (θ)) berechnen , da cos sowohl periodisch als auch gerade ist und Arccos immer einen Wert in [ 0, π) .

Wenn Sie die drei kleinsten Ergebnisse (alle null) überspringen, ist das viertkleinste die gewünschte Ausgabe.

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.

Alternative Version (34 Byte)

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

Die Ausgabe erfolgt in Grad und es werden keine trigonometrischen Funktionen verwendet.

Probieren Sie es online im CJam-Interpreter aus .

Dennis
quelle
9

Mathematica, 40 Bytes

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

Erläuterung: Geben Sie tdie Anzahl der Sekunden seit Mitternacht an. Die Position jeder Hand ist

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

Um den absoluten Winkelabstand zwischen xGrad und yGrad zu berechnen , können wir y - xden Bereich um 360 modifizieren [-180, 180]und dann den absoluten Wert nehmen. (Beachten Sie, dass es keine Beschränkung xund y.) Also diese Funktion nur die Unterschiede paarweise berechnet t/10-t/120, 6t-t/10und 6t-t/120und das tut.

jcai
quelle
Traurig, nicht vertraut mit Mathematica, aber akzeptiert dieses tatsächlich ein Argument oder eine Variable für die Anzahl der Sekunden seit Mitternacht?
Winny
1
@Winny Ja, es ist eine reine Funktion (angezeigt durch &) und das erste Argument, das übergeben wird, wird als inside bezeichnet #.
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)

Die zurückgelegte Entfernung in Stunden, Minuten und Sekunden in Einheiten von 1/60 des Kreises h,m,s = n/720, n/60, n/1 . Wir können diese Mod 60 nehmen, um ihre Position im Kreis von 0bis zu erhalten60 .

Wenn wir ihren Differenz-Mod 60 nehmen, erhalten wir die Anzahl der Einheiten, die einer vor dem anderen liegt. Wir nehmen alle sechs möglichen Differenzen, finden die min und multiplizieren dann mit6 zu skalieren360 Grad .

Das zweilagige Liste Verständnis wählt zuerst die erste Hand , wie durch dargestellt 720,60 oder 1wählt dann die andere Hand aus diesem Satz aus, wobei die erste Auswahl über set xor entfernt wird.

Ich habe dies ausführlich anhand des Referenzcodes getestet.

xnor
quelle
6

C #, 163 152 Bytes

Auf diese Weise wird jede Hand zweimal erstellt, um für das Umwickeln zu zählen. Anschließend wird jede Kombination durchlaufen und der Mindestwinkel zwischen den Händen ermittelt. Berechnungen werden in 60 Divisionen durchgeführt und dann mit 6 multipliziert, um Grad zu erhalten.

Zur Verdeutlichung eingerückt:

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

Beispielausgabe:

    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
quelle
Nizza Lösung Konto für Wrap - around
toto
2

TI-BASIC, 17 Bytes

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

Verwendet Dennis arccos(cos(, um Entfernungen zu normalisieren. Anstatt jedoch alle paarweisen Abstände zu berechnen, werden nur die drei benötigten berechnetΔList([seconds],[minutes],[hours],[seconds] .

Dieses Programm erwartet Degree Modus und gibt die Antwort in Grad zurück.

EDIT: 5!ist ein Byte kürzer als 120.

Lirtosiast
quelle