Skip to content

Instantly share code, notes, and snippets.

@vlad-bezden
Created November 12, 2016 12:26
Show Gist options
  • Save vlad-bezden/41c25fa1632f5fa8fd1e8dcdda0c4b05 to your computer and use it in GitHub Desktop.
Save vlad-bezden/41c25fa1632f5fa8fd1e8dcdda0c4b05 to your computer and use it in GitHub Desktop.
Clock Angle

Clock Angle

Analog clocks display time with an analog clock face, which consists of a round dial with the numbers 1 through 12, the hours in the day, around the outside. The hours are indicated with an hour hand, which makes two revolutions in a day, while the minutes are indicated by a minute hand, which makes one revolution per hour. In this mission we will use a clock without second hand. The hour hand moves smoothly and the minute hand moves step by step. You are given a time in 24-hour format and you should calculate a lesser angle between the hour and minute hands in degrees. Don't forget that clock has numbers from 1 to 12, so 23 == 11. The time is given as a string with the follow format "HH:MM", where HH is hours and MM is minutes. Hours and minutes are given in two digits format, so "1" will be written as "01". The result should be given in degrees with precision ±0.1.

For example, on the given image we see "02:30" or "14:30" at the left part and "01:42" or "13:42" at the right part. We need to find the lesser angle. Input: A time as a string. Output: The lesser angle as an integer or a float.

Precondition: re.match("\A((2[0-3])|([0-1][0-9])):[0-5][0-9]\Z", time)

A Pen by Vlad Bezden on CodePen.

License.

<div id="mocha"></div>
'use strict'
const circleDegrees = 360
const minutesInHour = 60
const hoursInCircle = 12
const ticksInHour = minutesInHour / hoursInCircle
const oneMinuteAngle = circleDegrees / minutesInHour
const oneHourAngle = circleDegrees / hoursInCircle
/**
* Gets angle based on the passed time
*
* @param {number} time - number between 0 - 60
* @return {number} - angle based on the time
*/
function getAngle(time) {
return time * oneMinuteAngle
}
/**
* Finds offset for hours based on minutes. For instance for 30 minutes there will be 15 degrees offset
*
* @param {number} - minutes for which offset has to be found
* @return {number} - angle offset for number of minutes
*/
function hoursOffsetAngle(minutes) {
return getAngle(minutes) / circleDegrees * oneHourAngle
}
/**
* Parses string and gets hours and minutes
*
* @param {string} - time in 'MM:HH' format
* @return {object} - object that contains time information
*/
function parseTime(time) {
const [hours, minutes] = time.split(':')
return {
hours: parseInt(hours) % hoursInCircle,
minutes: parseInt(minutes)
}
}
/**
* There are two angles between hours and minutes hands.
* This function finds lesser angle between them
*
* @param {number} hoursAngle - hourse angle
* @param {number} minutesAngle - minutes angle
* @return {number} - lesser angle between minutes and house hands
*/
function lesserAngle(hoursAngle, minutesAngle) {
const angle = Math.abs(minutesAngle - hoursAngle)
return Math.min(angle, circleDegrees - angle)
}
/**
* Main driver of the program.
*
* @param {string} time - time in 'HH:MM' format
* @return {number} - lesser angle between minutes and hours hand
*/
function clockAngle(time) {
const parsedTime = parseTime(time)
const minutesAngle = getAngle(parsedTime.minutes)
const hoursAngle = getAngle(parsedTime.hours * ticksInHour) + hoursOffsetAngle(parsedTime.minutes)
return lesserAngle(hoursAngle, minutesAngle)
}
mocha.setup('bdd')
const assert = chai.assert
describe('Assertions', () => {
it('02:30', () => assert.equal(clockAngle('02:30'), 105))
it('13:42', () => assert.equal(clockAngle("13:42"), 159))
it('01:42', () => assert.equal(clockAngle('01:42'), 159))
it('01:43', () => assert.equal(clockAngle('01:43'), 153.5))
it('Zero', () => assert.equal(clockAngle('00:00'), 0))
it('Little later', () => assert.equal(clockAngle('12:01'), 5.5))
it('Opposite', () => assert.equal(clockAngle('18:00'), 180))
console.log("Coding complete? Click 'Check' to review your tests and earn cool rewards!")
})
mocha.run()
<script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/3.1.1/mocha.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/3.5.0/chai.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/mocha/3.1.1/mocha.min.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment