Skip to content

Instantly share code, notes, and snippets.

@wesscoby
Last active April 13, 2019 19:48
Show Gist options
  • Save wesscoby/7f619e8458ecf9689d55a3eb6e2990b2 to your computer and use it in GitHub Desktop.
Save wesscoby/7f619e8458ecf9689d55a3eb6e2990b2 to your computer and use it in GitHub Desktop.
Codewares Kata
/*
* You are the "computer expert" of a local Athletic Association (C.A.A.). Many teams of runners come to compete.
* Each time, you get a string of all race results of every team who has run.
* For example, here is string showing the individual results of a team of 5 runners: "01|15|59, 1|47|6, 01|17|20, 1|32|34, 2|3|17"
* Each part of the string is of the form: h|m|s where h,m,s (h for hour, m for minutes, s for seconds) are positive or null integers,
* (represented as strings) with one or two digits. There are no traps in this format.
* To compare the results of the teams you are asked for giving three statistics; range, average and median
*
* Range: difference between the lowest and highest values. In {4, 6, 9, 3, 7}, the lowest value is 3 and highest is 9 so the range is 9 - 3 = 6
*
* Mean or Average: To calculate the mean, add together all of the numbers in the set and then divide the sum by the total count of the numbers
*
* Median: In statistics, the median is the number separating the higher half of a data sample from the lower half.
* The median of a finite list of numbers can be found by arranging all the observations from the lowest value to the highest value and
* picking the middle one (e.g. the median of {3, 3, 5, 9, 11} is 5) when there is an odd number of observations.
* If there is an even number of observations, then there is no single middle value; the median is then defined to be the mean of the two
* middle values (the median of {3, 5, 6, 9} is (5 + 6) / 2 = 5.5).
*
* Your task is to return a string giving these 3 values. For the example given above, the string result will be:
* "Range: 00|47|18 Average: 01|35|15 Median: 01|32|34" of the form: "Range: hh|mm|ss Average: hh|mm|ss Median: hh|mm|ss"
* where hh, mm, ss are integers (represented by strings) with each 2 digits
*
* Remarks:
* 1. If a result in seconds is ab.xy..., it will be given truncated as ab.
* 2. If the given string is "" you will return "".
* */
const stat = givenString => {
// Adding zeros in the right place to properly format time strings
let add_leading_zero = number => {
if (number <= 9) {
number = '0' + number;
}
return number;
};
// convert time from hh:mm:ss to seconds and vice versa
let two_way_time_convert = time => {
if( /(\w{1,2}):(\w{1,2}):(\w{1,2})/.test(time)) {
// convert from hh:mm:ss to seconds
let timeArray = time.split(":");
return (parseInt(timeArray[0]) * 3600) + (parseInt(timeArray[1]) * 60) + parseInt(timeArray[2]);
} else {
// convert from seconds to hh:mm:ss
let hr = Math.floor(time / 3600),
min = Math.floor((time - (hr * 3600)) / 60),
sec = time - (hr * 3600) - (min * 60);
return `${add_leading_zero(hr)}:${add_leading_zero(min)}:${add_leading_zero(sec)}`
}
};
// Check length of string
if(givenString.length === 0) {
// return empty string
return "";
} else {
// Convert givenString to an array of time values (in seconds)
// using iife (Immediately invoked function expression)
let timeArray = (string_param =>
string_param.split(",")
.map(item => item.replace(/\|/g, ":"))
.map(two_way_time_convert))(givenString);
// find range, mean and median and convert result from seconds to hh:mm:ss
// using iife
let range = ((arr) =>
two_way_time_convert((Math.max.apply(Math, arr) - Math.min.apply(Math, arr))).replace(/:/g, "|"))(timeArray);
let median = (arr => {
// sort array in ascending order
arr.sort((a, b) => a - b);
// checking if length of array is even
if (arr.length % 2 === 0) {
// find the average of the 2 center numbers
let half = Math.floor(arr.length / 2);
let med1 = arr[half - 1],
med2 = arr[half];
return two_way_time_convert(((med1 + med2) / 2)).replace(/:/g, "|");
} else {
// return the number at the center
let half = Math.floor(arr.length / 2);
return two_way_time_convert(arr[half]).replace(/:/g, "|");
}
})(timeArray);
let mean = (arr => {
let sum = arr.reduce((prev, next) => prev + next),
quantity = arr.length;
return two_way_time_convert(Math.floor((sum / quantity))).replace(/:/g, "|");
})(timeArray);
// return the result
return `Range: ${range} Average: ${mean} Median: ${median}`;
}
};
console.log(stat("01|15|59, 1|47|6, 01|17|20, 1|32|34, 2|3|17"));
/* Output
* Range: 00|47|18 Average: 01|35|15 Median: 01|32|34
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment