Day 7
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -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>
|
||||
|
||||
@@ -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) {
|
||||
|
||||
2
src/main/kotlin/com/basdado/adventofcode/Day6Extra.kt
Normal file
2
src/main/kotlin/com/basdado/adventofcode/Day6Extra.kt
Normal file
@@ -0,0 +1,2 @@
|
||||
package com.basdado.adventofcode
|
||||
|
||||
168
src/main/kotlin/com/basdado/adventofcode/Day7.kt
Normal file
168
src/main/kotlin/com/basdado/adventofcode/Day7.kt
Normal 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
|
||||
}
|
||||
}
|
||||
0
src/main/resources/day/6/extra/input.txt
Normal file
0
src/main/resources/day/6/extra/input.txt
Normal file
102
src/main/resources/day/7/input.txt
Normal file
102
src/main/resources/day/7/input.txt
Normal 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.
|
||||
Reference in New Issue
Block a user