Day 7
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<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>
|
<kotlin.code.style>official</kotlin.code.style>
|
||||||
<junit.version>4.12</junit.version>
|
<junit.version>4.12</junit.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ class Day4 {
|
|||||||
|
|
||||||
private fun parseGuardDays(sortedLines: MutableList<Line>): List<GuardDay> {
|
private fun parseGuardDays(sortedLines: MutableList<Line>): List<GuardDay> {
|
||||||
val guardDays = mutableListOf<GuardDay>()
|
val guardDays = mutableListOf<GuardDay>()
|
||||||
var currentDay = GuardDay(0, LocalDate.EPOCH, mutableListOf())
|
var currentDay = GuardDay(0, LocalDate.MIN, mutableListOf())
|
||||||
var sleepStartMinute = 0
|
var sleepStartMinute = 0
|
||||||
for (line in sortedLines) {
|
for (line in sortedLines) {
|
||||||
if (line.event == GuardEventType.BEGIN_SHIFT) {
|
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