From 09911c195c0a2272fe114fd9cf1f20e47af6f6d6 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Fri, 7 Dec 2018 15:00:59 +0100 Subject: [PATCH] Adding day 7 --- day7/part1.scala | 30 ++++++++++++++++++++++++++++ day7/part2.scala | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 day7/part1.scala create mode 100644 day7/part2.scala diff --git a/day7/part1.scala b/day7/part1.scala new file mode 100644 index 0000000..252abd4 --- /dev/null +++ b/day7/part1.scala @@ -0,0 +1,30 @@ +import scala.io.StdIn.readLine + +// "Step A must be finished before step B can begin." +// 0 1 2 3 4 5 6 7 8 9 +val PREREQ_STEP_INDEX: Int = 1 +val STEP_INDEX: Int = 7 + +val stepsWithParents = Iterator.continually(readLine) + .takeWhile(_ != null) + .map { l => + val ws = l.split(" ") + ws(PREREQ_STEP_INDEX).head -> ws(STEP_INDEX).head } + .foldLeft(Map.empty[Char, Set[Char]]){ + case (acc, (parent, child)) => acc + + (child -> (acc.getOrElse(child, Set.empty[Char]) + parent)) + + (parent -> (acc.getOrElse(parent, Set.empty[Char])))} + .toList + +def walkGraph(g: List[(Char, Set[Char])], result: String = ""): String = g match { + case Nil => result + case _ => + val chosenParent = g.filter(_._2.isEmpty).map(_._1).min + walkGraph( + g + .filter(_._1 != chosenParent) + .map { case (k, v) => k -> v.filter(_ != chosenParent) }, + result + chosenParent.toString) +} + +println(walkGraph(stepsWithParents)) diff --git a/day7/part2.scala b/day7/part2.scala new file mode 100644 index 0000000..420645d --- /dev/null +++ b/day7/part2.scala @@ -0,0 +1,51 @@ +import scala.io.StdIn.readLine + +// "Step A must be finished before step B can begin." +// 0 1 2 3 4 5 6 7 8 9 +val PREREQ_STEP_INDEX: Int = 1 +val STEP_INDEX: Int = 7 + +val BASE_TIME_TO_COMPLETE: Int = 61 // 60 + 1 because index of letter starting at 0. +val WORKERS_NB: Int = 4 + +val stepsWithParents = Iterator.continually(readLine) + .takeWhile(_ != null) + .map { l => + val ws = l.split(" ") + ws(PREREQ_STEP_INDEX).head -> ws(STEP_INDEX).head } + .foldLeft(Map.empty[Char, Set[Char]]){ + case (acc, (parent, child)) => acc + + (child -> (acc.getOrElse(child, Set.empty[Char]) + parent)) + + (parent -> (acc.getOrElse(parent, Set.empty[Char])))} + .toList + +def timeToComplete(c: Char): Int = BASE_TIME_TO_COMPLETE + (c - 'A') + +def updateResult(chosenParents: Seq[Char], children: Map[Char, Set[Char]], initial: Map[Char, Int]): Map[Char, Int] = { + val updatedParents = initial.map { + case (k, v) if chosenParents.contains(k) => + k -> (v + timeToComplete(k)) + case (k, v) => k -> v + } + + updatedParents.map { + case (k, v) if children.contains(k) && children(k).exists(chosenParents.contains) => + k -> (children(k).filter(chosenParents.contains).map(p => updatedParents(p)) + v).max + case (k, v) => k -> v + } +} + +def walkGraph(g: List[(Char, Set[Char])], result: Map[Char, Int]): Map[Char, Int] = + g match { + case Nil => result + case _ => + val chosenParents = g.filter(_._2.isEmpty).map(_._1).sorted.take(WORKERS_NB) + walkGraph( + g.filter(e => !chosenParents.contains(e._1)) + .map { case (k, v) => k -> v.filterNot(chosenParents.contains) }, + updateResult(chosenParents, g.toMap, result)) +} + +val timesToCompletion = walkGraph(stepsWithParents, stepsWithParents.map(_._1 -> 0).toMap) + +println(timesToCompletion('C'))