Last active
July 25, 2023 21:24
-
-
Save louis-young/418bdf014c338568eb40d4fdc49c7576 to your computer and use it in GitHub Desktop.
Lunchtime LINQ challenges
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* https://markheath.net/post/lunchtime-linq-challenge | |
*/ | |
interface GetSecondsFromMinutesAndSecondsParameters { | |
minutes: number; | |
seconds: number; | |
} | |
const getSecondsFromMinutesAndSeconds = ({ | |
minutes, | |
seconds, | |
}: GetSecondsFromMinutesAndSecondsParameters) => { | |
const minutesInSeconds = minutes * 60; | |
return minutesInSeconds + seconds; | |
}; | |
const formatSecondsAsMinutesAndSeconds = (secondsToFormat: number) => { | |
const minutes = Math.floor(((secondsToFormat % 60) * 60) / 60); | |
const minutesPaddedString = String(minutes).padStart(2, "0"); | |
const seconds = Math.floor(secondsToFormat % 60); | |
const secondsPaddedString = String(seconds).padStart(2, "0"); | |
return `${minutesPaddedString}:${secondsPaddedString}`; | |
}; | |
const calculateAgeFromBirthDate = (birthDate: Date) => { | |
const birthDateTimestamp = birthDate.getTime(); | |
const currentDateTimestamp = new Date().getTime(); | |
const timestampDifferenceInMilliseconds = | |
(currentDateTimestamp - birthDateTimestamp) / 1000; | |
const ONE_YEAR_IN_MILLISECONDS = 60 * 60 * 24 * 365.25; | |
return Math.floor( | |
timestampDifferenceInMilliseconds / ONE_YEAR_IN_MILLISECONDS | |
); | |
}; | |
/** | |
* 1. | |
*/ | |
const inputOne = | |
"Davis, Clyne, Fonte, Hooiveld, Shaw, Davis, Schneiderlin, Cork, Lallana, Rodriguez, Lambert"; | |
const resultOne = inputOne | |
.split(", ") | |
.map((playerName, playerIndex) => { | |
const playerNumber = playerIndex + 1; // Off by one. | |
return `${playerNumber}. ${playerName}`; | |
}) | |
.join(", "); | |
console.log(resultOne); | |
/** | |
* 2. | |
*/ | |
const inputTwo = | |
"Jason Puncheon, 26/06/1986; Jos Hooiveld, 22/04/1983; Kelvin Davis, 29/09/1976; Luke Shaw, 12/07/1995; Gaston Ramirez, 02/12/1990; Adam Lallana, 10/05/1988"; | |
const resultTwo = inputTwo | |
.split("; ") | |
.map((player) => { | |
const [name, birthDateString] = player.split(", "); | |
const [birthDateDay, birthDateMonth, birthDateYear] = birthDateString | |
.split("/") | |
.map((string) => Number(string)); | |
const birthDate = new Date(birthDateYear, birthDateMonth, birthDateDay); | |
const age = calculateAgeFromBirthDate(birthDate); | |
return { | |
name, | |
birthDate, | |
age, | |
}; | |
}) | |
.sort( | |
(playerA, playerB) => | |
playerB.birthDate.getTime() - playerA.birthDate.getTime() | |
); | |
console.log(resultTwo); | |
/** | |
* 3. | |
*/ | |
const inputThree = "4:12,2:43,3:51,4:29,3:24,3:14,4:46,3:25,4:52,3:27"; | |
const resultThree = formatSecondsAsMinutesAndSeconds( | |
inputThree.split(",").reduce((totalAlbumDuration, songDuration) => { | |
const [minutes, seconds] = songDuration | |
.split(":") | |
.map((string) => Number(string)); | |
const songDurationInSeconds = getSecondsFromMinutesAndSeconds({ | |
minutes, | |
seconds, | |
}); | |
return totalAlbumDuration + songDurationInSeconds; | |
}, 0) | |
); | |
console.log(resultThree); | |
/** | |
* 4. | |
*/ | |
const inputFour = 3; | |
const resultFour = Array.from({ length: inputFour }) | |
.flatMap((rowValue, rowIndex) => { | |
return Array.from({ length: inputFour }).map( | |
(columnValue, columnIndex) => `${rowIndex},${columnIndex}` | |
); | |
}) | |
.join(" "); | |
console.log(resultFour); | |
/** | |
* 5. | |
*/ | |
const inputFive = "00:45,01:32,02:18,03:01,03:44,04:31,05:19,06:01,06:47,07:35"; | |
type Accumulator = { | |
lengthTimes: number[]; | |
previousLengthCompletedAt: number; | |
}; | |
const resultFive = inputFive | |
.split(",") | |
.map((lengthCompletedAtMinutesAndSeconds) => { | |
const [minutes, seconds] = lengthCompletedAtMinutesAndSeconds | |
.split(":") | |
.map((string) => Number(string)); | |
return getSecondsFromMinutesAndSeconds({ | |
minutes, | |
seconds, | |
}); | |
}) | |
.reduce<Accumulator>( | |
({ lengthTimes, previousLengthCompletedAt }, currentLengthCompletedAt) => { | |
const currentLengthTime = | |
currentLengthCompletedAt - previousLengthCompletedAt; | |
return { | |
lengthTimes: [...lengthTimes, currentLengthTime], | |
previousLengthCompletedAt: currentLengthCompletedAt, | |
}; | |
}, | |
{ | |
lengthTimes: [], | |
previousLengthCompletedAt: 0, | |
} | |
); | |
console.log(resultFive.lengthTimes); | |
/** | |
* 6. | |
*/ | |
const inputSix = "2,5,7-10,11,17-18"; | |
const resultSix = inputSix.split(",").flatMap((numberOrRange) => { | |
const isNumberRange = numberOrRange.includes("-"); | |
if (!isNumberRange) { | |
return Number(numberOrRange); | |
} | |
const [startNumber, endNumber] = numberOrRange | |
.split("-") | |
.map((string) => Number(string)); | |
const numberRangeSize = endNumber - startNumber + 1; // Off by one. | |
return Array.from({ length: numberRangeSize }).map( | |
(number, numberIndex) => startNumber + numberIndex | |
); | |
}); | |
console.log(resultSix); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment