Created
February 6, 2022 22:35
-
-
Save mayonesa/33126282cf753b81aeb46297ca34cc85 to your computer and use it in GitHub Desktop.
Time using at most 2 numbers
This file contains 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
import java.text.SimpleDateFormat | |
import java.time.Instant | |
import java.util.Date | |
import java.util.concurrent.TimeUnit | |
import TimeUnit.{MILLISECONDS => Milliseconds} | |
import TimeUnit.{SECONDS => Seconds} | |
import scala.annotation.tailrec | |
/* | |
An interesting time is a local time string in the format of HH:mm:ss and using | |
only at most two numbers. | |
These are examples of interesting time: | |
- 00:00:00 // uses only 1 number, zero | |
- 02:02:20 // uses only 2 numbers, zero and two | |
- 11:12:22 // uses only 2 numbers, one and two | |
These are not examples of interesting time: | |
- 10:30:00 // uses zero, one and three | |
- 10:20:59 // uses zero, one, two, five and nine | |
Given two local time string in the format of HH:mm:ss (ex. "05:59:07") t1 and | |
t2, count all interesting time in between t1 and t2 including t1 and t2. | |
Correctness and not performance is the focus of the solution. | |
*/ | |
object InterestingTimes { | |
private val InFormat = new SimpleDateFormat("HH:mm:ss") | |
private val NumbersOnly = new SimpleDateFormat("HHmmss") | |
def numberOfInterestingTimes(fromStr: String, toStr: String): Int = { | |
val from = InFormat.parse(fromStr) | |
val to = InFormat.parse(toStr) | |
val diffInSeconds = Seconds.convert(to.getTime - from.getTime, Milliseconds).toInt | |
(0 to diffInSeconds).foldLeft(0) { case (nInterestingTimes, secondIncrement) => | |
val time = from.toInstant.plusSeconds(secondIncrement) | |
nInterestingTimes + (if (interesting(time)) 1 else 0) | |
} | |
} | |
private def interesting(time: Instant) = { | |
@tailrec | |
def loop(str: String, acc: Set[Char]): Boolean = | |
if (str.isEmpty) true | |
else { | |
val c = str.head | |
val newAcc = acc + c | |
if (newAcc.size > 2) false | |
else loop(str.tail, newAcc) | |
} | |
loop(NumbersOnly.format(Date.from(time)), Set()) | |
} | |
} |
This file contains 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
import org.scalatest.flatspec.AnyFlatSpec | |
class InterestingTimesSpec extends AnyFlatSpec { | |
"no interest" should "0" in { | |
assert(InterestingTimes.numberOfInterestingTimes("10:30:00", "10:59:59") === 0) | |
} | |
"inclusive interest" should "be inclusive" in { | |
assert(InterestingTimes.numberOfInterestingTimes("10:00:00", "10:00:01") === 2) | |
} | |
"inside interest" should "be included" in { | |
assert(InterestingTimes.numberOfInterestingTimes("10:00:02", "10:00:12") === 2) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment