This commit is contained in:
2018-12-07 14:06:59 +01:00
parent f1c31df8b4
commit fb730092b4
6 changed files with 274 additions and 2 deletions

View File

@@ -12,7 +12,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<kotlin.version>1.3.10</kotlin.version>
<kotlin.version>1.3.11</kotlin.version>
<kotlin.code.style>official</kotlin.code.style>
<junit.version>4.12</junit.version>
</properties>

View File

@@ -71,7 +71,7 @@ class Day4 {
private fun parseGuardDays(sortedLines: MutableList<Line>): List<GuardDay> {
val guardDays = mutableListOf<GuardDay>()
var currentDay = GuardDay(0, LocalDate.EPOCH, mutableListOf())
var currentDay = GuardDay(0, LocalDate.MIN, mutableListOf())
var sleepStartMinute = 0
for (line in sortedLines) {
if (line.event == GuardEventType.BEGIN_SHIFT) {

View File

@@ -0,0 +1,2 @@
package com.basdado.adventofcode

View File

@@ -0,0 +1,168 @@
package com.basdado.adventofcode
import java.lang.IllegalStateException
import java.lang.Integer.min
import java.util.Arrays.stream
import java.util.stream.Collectors
import java.util.stream.IntStream
fun main() {
val day = Day7()
day.puzzle1()
day.puzzle2()
}
class Day7 {
fun puzzle1() {
val graph = loadGraph()
val nodeOrder = mutableListOf<Node>()
val availableNodes = graph.nodes.filter { n -> n.previous.isEmpty() }.toMutableSet()
while (!availableNodes.isEmpty()) {
val nextNode = availableNodes.sortedBy { n -> n.id }[0]
nodeOrder.add(nextNode)
availableNodes.remove(nextNode)
availableNodes.addAll(nextNode.next
.filter { !nodeOrder.contains(it) }
.filter { nodeOrder.containsAll(it.previous) })
}
println(nodeOrder.stream().map{ it.id }.collect(Collectors.joining()))
}
fun puzzle2() {
val graph = loadGraph()
val timeline = TimeLine()
// The first timeslot is available
// timeline.add(Array(workerCount) { null })
var finished = emptySet<Node>()
var availableNodes = graph.nodes.filter { n -> n.previous.isEmpty() }.toMutableSet()
var time = 0
while (!finished.containsAll(graph.nodes)) {
val orderedAvailableNodes = availableNodes.sortedBy { n -> n.id }
val timeSlot = timeline.getSlot(time)
// Divide the available workers
for (availableNode in orderedAvailableNodes) {
val availableWorkerIndex = timeSlot.indexOfFirst { it == null }
if (availableWorkerIndex == -1) {
break
}
timeline.addJob(time, availableWorkerIndex, availableNode)
}
time++
finished = timeline.finishedNodes(time)
availableNodes = graph.nodes
.filter { finished.containsAll(it.previous) }
// Not finished
.filter { !finished.contains(it) }
// Not in progress
.filter { !timeline.getSlot(time).contains(it) }
.toMutableSet()
}
// println(timeline)
println(timeline.timeline.size)
}
private fun loadGraph(): Graph {
val graph = Graph()
val lineMatcher = Regex("""Step ([A-Z]) must be finished before step ([A-Z]) can begin.""")
lines("/day/7/input.txt")
.forEach {
val match = lineMatcher.matchEntire(it)!!
graph.addConnection(match.groupValues[1], match.groupValues[2])
}
return graph
}
class TimeLine(val workerCount: Int = 5) {
val timeline = mutableListOf<Array<Node?>>()
fun getSlot(time: Int): Array<Node?> {
extendUntil(time)
return timeline[time]
}
fun finishedNodes(time: Int): Set<Node> {
// All jobs that were active before "time" and are no longer active on "time" are finished
val finished = mutableSetOf<Node>()
for (t in 0 until min(time, timeline.size)) {
finished.addAll(timeline[t].filterNotNull())
}
if (timeline.size > time) {
finished.removeAll(timeline[time].filterNotNull())
}
return finished
}
fun addJob(startTime: Int, workerId: Int, node: Node) {
extendUntil(startTime + node.processTime())
for(time in startTime until startTime + node.processTime()) {
if (timeline[time][workerId] != null) {
throw IllegalStateException("Worker $workerId is already busy in timeslot $time")
}
timeline[time][workerId] = node
}
}
fun extendUntil(time: Int) {
if (timeline.size > time) {
return
}
for(t in timeline.size..time) {
timeline.add(Array(workerCount) { null })
}
}
override fun toString(): String {
return IntStream.range(0, timeline.size)
.mapToObj { "" + it + " " +
stream(timeline[it]).map{ n -> n?.toString() ?: "." }.collect(Collectors.joining(" ")) + " " +
finishedNodes(it).map{n -> n.id}.joinToString ( ", " )}
.collect(Collectors.joining("\r\n"))
}
}
class Graph {
val nodes: MutableSet<Node> = mutableSetOf()
fun addConnection(id1: String, id2: String) {
val node1 = findOrCreateNode(id1)
val node2 = findOrCreateNode(id2)
node1.next.add(node2)
node2.previous.add(node1)
}
fun findOrCreateNode(id: String): Node {
return nodes.stream().filter{ it.id == id }.findAny()
.orElseGet {
val newNode = Node(id)
nodes.add(newNode)
newNode
}
}
}
class Node(val id: String, val next: MutableSet<Node> = mutableSetOf(), val previous: MutableSet<Node> = mutableSetOf()) {
fun processTime() = 60 + (id[0] - 'A') + 1
override fun toString(): String = id
}
}

View File

View File

@@ -0,0 +1,102 @@
Step G must be finished before step S can begin.
Step T must be finished before step Q can begin.
Step A must be finished before step B can begin.
Step H must be finished before step X can begin.
Step V must be finished before step O can begin.
Step Z must be finished before step P can begin.
Step R must be finished before step J can begin.
Step L must be finished before step Y can begin.
Step Y must be finished before step E can begin.
Step W must be finished before step X can begin.
Step X must be finished before step B can begin.
Step K must be finished before step E can begin.
Step Q must be finished before step P can begin.
Step U must be finished before step B can begin.
Step M must be finished before step O can begin.
Step P must be finished before step N can begin.
Step I must be finished before step J can begin.
Step B must be finished before step C can begin.
Step C must be finished before step O can begin.
Step J must be finished before step F can begin.
Step F must be finished before step O can begin.
Step E must be finished before step D can begin.
Step D must be finished before step N can begin.
Step N must be finished before step S can begin.
Step S must be finished before step O can begin.
Step W must be finished before step O can begin.
Step L must be finished before step P can begin.
Step N must be finished before step O can begin.
Step T must be finished before step D can begin.
Step G must be finished before step I can begin.
Step V must be finished before step X can begin.
Step B must be finished before step N can begin.
Step R must be finished before step N can begin.
Step H must be finished before step J can begin.
Step B must be finished before step S can begin.
Step P must be finished before step I can begin.
Step A must be finished before step J can begin.
Step A must be finished before step U can begin.
Step B must be finished before step D can begin.
Step T must be finished before step A can begin.
Step U must be finished before step D can begin.
Step T must be finished before step L can begin.
Step I must be finished before step E can begin.
Step R must be finished before step U can begin.
Step H must be finished before step S can begin.
Step P must be finished before step F can begin.
Step Q must be finished before step C can begin.
Step A must be finished before step P can begin.
Step X must be finished before step E can begin.
Step Q must be finished before step N can begin.
Step E must be finished before step N can begin.
Step Q must be finished before step O can begin.
Step J must be finished before step S can begin.
Step X must be finished before step P can begin.
Step K must be finished before step U can begin.
Step F must be finished before step E can begin.
Step C must be finished before step E can begin.
Step H must be finished before step K can begin.
Step W must be finished before step B can begin.
Step G must be finished before step O can begin.
Step F must be finished before step N can begin.
Step I must be finished before step D can begin.
Step G must be finished before step V can begin.
Step E must be finished before step S can begin.
Step Y must be finished before step P can begin.
Step G must be finished before step E can begin.
Step P must be finished before step J can begin.
Step P must be finished before step J can begin.
Step U must be finished before step N can begin.
Step U must be finished before step F can begin.
Step X must be finished before step U can begin.
Step X must be finished before step C can begin.
Step R must be finished before step Q can begin.
Step Q must be finished before step E can begin.
Step Z must be finished before step E can begin.
Step X must be finished before step F can begin.
Step J must be finished before step D can begin.
Step X must be finished before step M can begin.
Step Y must be finished before step D can begin.
Step K must be finished before step J can begin.
Step Z must be finished before step J can begin.
Step M must be finished before step P can begin.
Step T must be finished before step M can begin.
Step F must be finished before step S can begin.
Step P must be finished before step S can begin.
Step X must be finished before step I can begin.
Step U must be finished before step J can begin.
Step M must be finished before step B can begin.
Step Q must be finished before step D can begin.
Step Z must be finished before step I can begin.
Step D must be finished before step S can begin.
Step J must be finished before step N can begin.
Step D must be finished before step O can begin.
Step T must be finished before step H can begin.
Step P must be finished before step D can begin.
Step M must be finished before step F can begin.
Step Y must be finished before step S can begin.
Step H must be finished before step I can begin.
Step Y must be finished before step W can begin.
Step X must be finished before step J can begin.
Step L must be finished before step W can begin.
Step G must be finished before step N can begin.