1
0
Files
Advent-of-Code/2020/src/main/kotlin/Day21.kt
T
2020-12-30 18:01:52 +01:00

59 lines
2.3 KiB
Kotlin

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 org.eclipse.collections.api.factory.Bags
import org.eclipse.collections.api.multimap.set.MutableSetMultimap
import org.eclipse.collections.impl.factory.Multimaps
@Day(21)
class Day21(@Lines val input: Input<List<String>>) {
private val foods = input.value.map { line ->
val parOpen = line.indexOf('(')
val ingredients = line.substring(0 until parOpen - 1).split(" ")
val allergens = line.substring(parOpen + 1 until line.length - 1).removePrefix("contains ").split(", ")
ingredients to allergens
}
private val allIngredients = foods.flatMap { it.first }.toSet()
private val allAllergens = foods.flatMap { it.second }.toSet()
private val dangerousIngredients = dangerousIngredients()
fun part1(): Int {
val occurrences = Bags.mutable.empty<String>()
foods.forEach { (ingredients) -> occurrences.addAll(ingredients) }
return allIngredients.filter { !dangerousIngredients.containsValue(it) }
.map { ingredient -> occurrences.count { it == ingredient } }
.sum()
}
fun part2(): String {
while (!dangerousIngredients.multiValuesView().all { it.size() == 1 }) {
dangerousIngredients.multiValuesView()
.filter { it.size() == 1 }
.map { it.first() }
.forEach { removeMe ->
dangerousIngredients.keyMultiValuePairsView()
.filter { it.two.size() != 1 && it.two.contains(removeMe) }
.forEach { dangerousIngredients.remove(it.one, removeMe) }
}
}
return dangerousIngredients.keySet().sorted().joinToString(",") { dangerousIngredients.get(it).first() }
}
private fun dangerousIngredients(): MutableSetMultimap<String, String> {
val map = Multimaps.mutable.set.empty<String, String>()
allAllergens.forEach { map.putAll(it, allIngredients) }
foods.forEach { (ingredients, allergens) ->
allergens.forEach { allergen ->
allIngredients.forEach {
if (!ingredients.contains(it)) map.remove(allergen, it)
}
}
}
return map
}
}