Day16
This commit is contained in:
@@ -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())
|
||||
}
|
||||
Reference in New Issue
Block a user