Last active
February 4, 2022 17:26
-
-
Save mayonesa/c9dff6d4980a5884ad870b43cc14a843 to your computer and use it in GitHub Desktop.
Given individual schedules and the endpoints of time, it will return all the free times.
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
import scala.collection.parallel.immutable.ParRange | |
import scala.collection.GenSeq | |
object Solution extends App { | |
private val NoTimes = Seq.empty[(Int, Int)] | |
private val NoStart = Option.empty[Int] | |
private val StdListStart = "[" | |
private val StdListEnd = "]" | |
private val Sample = (-5, 60, Seq(Seq((0, 5), (15, 30), (45, 60)), Seq((5, 15), (30, 40)))) | |
private val stdin = "" // """\[(\d+), (\d+)\]""".r | |
private val (start, end, schedules) = Sample | |
private def markBusy(acc: Vector[Boolean], time: (Int, Int)) = { | |
val (s, e) = time | |
val patchSize = e - s | |
val busyPatch = Vector.fill(patchSize)(false) | |
val i = s - start | |
acc patch (i, busyPatch, patchSize) | |
} | |
private def freePerSched(acc: Vector[Boolean], sched: Seq[(Int, Int)]) = sched.foldLeft(acc)(markBusy) | |
// adds falsehoods on both ends to properly downstream-process potential boolean transitions | |
private def bookend(xs: GenSeq[(Int, Boolean)]) = (start - 1, false) +: xs :+ (end, false) | |
private def toFreeInterval(accAndLastStartOpt: (Seq[(Int, Int)], Option[Int]), | |
timeAndFree: (Int, Boolean)) = { | |
val (acc, lastStartOpt) = accAndLastStartOpt | |
val (time, free) = timeAndFree | |
lastStartOpt match { | |
case Some(lastStart) => | |
if (free) (acc, lastStartOpt) | |
else (acc :+ (lastStart, time), NoStart) | |
case _ => | |
if (free) (acc, Option(time)) | |
else (acc, NoStart) | |
} | |
} | |
private val nTimes = end - start | |
private val freeMask = Vector.fill(nTimes)(true) | |
private val freeIndicator = schedules.foldLeft(freeMask)(freePerSched) | |
private val timesInParallel = ParRange(0, nTimes, 1, false) | |
private val freeTimeAggs = timesInParallel map { i => | |
val startTime = i + start | |
(startTime, freeIndicator(i)) | |
} | |
private val intervalReadyFreeTimes = bookend(freeTimeAggs) | |
private val freeIntervals = (intervalReadyFreeTimes.foldLeft((NoTimes, NoStart))(toFreeInterval))._1 | |
println(StdListStart + (freeIntervals mkString " ") + StdListEnd) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment