1
0
This commit is contained in:
2020-12-16 09:00:18 +01:00
parent 2aa4226083
commit 90c9961d72
2 changed files with 401 additions and 0 deletions
+138
View File
@@ -0,0 +1,138 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Day
import be.vandewalleh.aoc.utils.input.Input
import be.vandewalleh.aoc.utils.input.Lines
import be.vandewalleh.aoc.utils.input.createDay
import org.eclipse.collections.api.RichIterable
import org.eclipse.collections.impl.factory.Multimaps
import org.eclipse.collections.impl.factory.primitive.IntSets
@Day(16)
class Day16(@Lines val input: Input<List<String>>) {
fun part1(): Int {
val minMax = mutableListOf<IntRange>()
val re = "(\\d+)-(\\d+)".toRegex()
for (line in input.value) {
re.findAll(line).forEach {
val (min, max) = it.destructured
minMax.add(min.toInt()..max.toInt())
}
if (line.startsWith("your ticket")) break
}
var ok = false
val nearbyTickets = mutableListOf<Int>()
for (line in input.value) {
if (!ok && line.startsWith("nearby tickets:")) {
ok = true
continue
}
if (!ok) continue
line.splitToSequence(",").forEach { nearbyTickets.add(it.toInt()) }
}
val invalid = mutableListOf<Int>()
nearbyTickets.forEach { number ->
if (minMax.none { number in it }) invalid.add(number)
}
return invalid.sum()
}
private fun isTicketValid(ticket: List<Int>, ranges: List<IntRange>): Boolean {
for (number in ticket) {
if (!ranges.any { number in it }) return false
}
return true
}
private fun inRanges(value: Int, ranges: List<IntRange>) = ranges.any { value in it }
fun part2(): Long {
val minMax = Multimaps.mutable.list.empty<String, IntRange>()
val re = "(\\d+)-(\\d+)".toRegex()
for (line in input.value) {
if (line.startsWith("your ticket")) break
val name = line.split(':')[0]
re.findAll(line)!!.forEach {
val (min, max) = it.destructured
minMax.put(name, min.toInt()..max.toInt())
}
}
var ok = false
val validTickets = mutableListOf<List<Int>>()
for (line in input.value) {
if (!ok && line.startsWith("nearby tickets:")) {
ok = true
continue
}
if (!ok) continue
val ticket = line.splitToSequence(",").map { it.toInt() }.toList()
if (isTicketValid(ticket, minMax.valuesView().toList())) {
validTickets.add(ticket)
}
}
val catMap = Multimaps.mutable.list.empty<String, Int>()
for (a in minMax.keyMultiValuePairsView()) {
val category = a.one
val ranges = a.two.toList()
for (i in validTickets.first().indices) {
val allInRange = validTickets
.asSequence()
.map { it[i] }
.all { inRanges(it, ranges) }
if (allInRange) catMap.put(category, i)
}
}
val removed = IntSets.mutable.empty()
while (!catMap.multiValuesView().all { it.size() == 1 }) {
val values = catMap.multiValuesView()
val categoriesToRemove = mutableListOf<String>()
val one = values.filter { it.size() == 1 }
.map { it.first() }
.find { !removed.contains(it) }
?.also { removed.add(it) }
?: error("???")
for (v in catMap.keyMultiValuePairsView()) {
val cat = v.one
val values: RichIterable<Int> = v.two
if (values.size() < 2) continue
if (values.find { it == one } != null) categoriesToRemove.add(cat)
}
for (cat in categoriesToRemove) {
catMap.remove(cat, one)
}
}
// TODO
val myTicket = "173,191,61,199,101,179,257,79,193,223,139,97,83,197,251,53,89,149,181,59"
val myTicketValues = myTicket.split(",").map { it.toInt() }
var mult = 1L
catMap.forEachKeyValue { category, index ->
if (category.startsWith("departure")) {
mult *= myTicketValues[index]
}
}
return mult
}
}
fun main() = with(createDay<Day16>()) {
println(part1())
println(part2())
}