From 705e05fbaba3932bbdbce2a36f0ca7fa6f68eb87 Mon Sep 17 00:00:00 2001 From: Stefan Forstenlechner Date: Sat, 19 Dec 2020 16:48:11 +0100 Subject: [PATCH] day16 --- day16.kt | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 day16.kt diff --git a/day16.kt b/day16.kt new file mode 100644 index 0000000..ee3b962 --- /dev/null +++ b/day16.kt @@ -0,0 +1,109 @@ +import java.io.File + +fun main(args: Array) { + println("Hello day16!") + solve() +} + +data class RuleRange(val min: Int, val max: Int) +data class Rule(val name: String, val ruleRangeFirst: RuleRange, val ruleRangeSecond: RuleRange) + +val numbersRegex = Regex("\\d+") + +fun readRules(ruleAsString: String): Rule { + val (ruleName, rest) = ruleAsString.split(":") + val ruleRanges = numbersRegex.findAll(rest) + .flatMap { match -> match.groupValues.map { it.toInt() } } + .chunked(2) + .map { pair -> RuleRange(pair[0], pair[1]) } + .toList() + + return Rule(ruleName, ruleRanges[0], ruleRanges[1]) +} + +fun checkRuleRange(v: Int, ruleRange: RuleRange): Boolean = v >= ruleRange.min && v <= ruleRange.max + +fun errorRateIfViolated(v: Int, rules: List): Long { + if (rules.any { rule -> checkRuleRange(v, rule.ruleRangeFirst) || checkRuleRange(v, rule.ruleRangeSecond) }) { + return 0 + } + return v.toLong() +} + +fun sumErrorRateOfViolations(ticket: String, rules: List): Long = + ticket.split(",") + .map { it.toInt() } + .map { errorRateIfViolated(it, rules) } + .sum() + +fun isValidValue(v: Int, rules: List): Boolean = + rules.any { rule -> checkRuleRange(v, rule.ruleRangeFirst) || checkRuleRange(v, rule.ruleRangeSecond) } + +fun isValidTicket(ticket: String, rules: List): Boolean = + ticket.split(",") + .map { it.toInt() } + .all { isValidValue(it, rules) } + +fun isRuleValidFor(rule: Rule, values: List): Boolean = values.all { v -> checkRuleRange(v, rule.ruleRangeFirst) || checkRuleRange(v, rule.ruleRangeSecond) } + +fun valuesForColumn(ticketValues: List>, col: Int) = ticketValues.map { it[col] } + +fun rulesPerColumn(ticketValues: List>, rules: List): MutableMap> { + val ruleValidForColumn = mutableMapOf>() + for (i in ticketValues[0].indices) { + val columnValues = valuesForColumn(ticketValues, i) + for (rule in rules) { + if (isRuleValidFor(rule, columnValues)) { + if (!ruleValidForColumn.containsKey(rule)) { + ruleValidForColumn[rule] = mutableSetOf() + } + ruleValidForColumn[rule]?.add(i) + } + } + } + + return ruleValidForColumn +} + +fun ruleToColumnAssignment(validRulesPerColumns: MutableMap>): Map { + val rulePerColumnAssignment = mutableMapOf() + while (validRulesPerColumns.isNotEmpty()) { + val currentAssignment = validRulesPerColumns.asSequence().filter { it.value.size == 1 }.first() + val column = currentAssignment.value.first() + rulePerColumnAssignment[currentAssignment.key] = column + + validRulesPerColumns.remove(currentAssignment.key) + for (validRulPerColumns in validRulesPerColumns) { + validRulPerColumns.value.remove(column) + } + } + + return rulePerColumnAssignment +} + +fun solve() { + val readLines = File("day16/input").readText(); + val (ruleText, ticketWithLabel, nearbyWithLabel) = readLines.split("\n\n") + val ticket = ticketWithLabel.split("\n")[1] + val nearby = nearbyWithLabel.split("\n").drop(1).filter { it.isNotEmpty() } + + val rules = ruleText.split("\n").filter { it.isNotEmpty() }.map { readRules(it) } + + val errorRate = nearby.map { sumErrorRateOfViolations(it, rules) }.sum() + println(errorRate) + + // part 2 + val nearbyValidTickets = nearby.filter { isValidTicket(it, rules) } + + val nearbyTicketValues = nearbyValidTickets.map { t -> t.split(",").map { it.toInt() } } + + val validRulesPerColumns = rulesPerColumn(nearbyTicketValues, rules) + + val ruleToColumnAssignment = ruleToColumnAssignment(validRulesPerColumns) + + val ticketValues = ticket.split(",").map { it.toLong() } + + val departureProduct = ruleToColumnAssignment.entries.filter { it.key.name.startsWith("departure") }.map { ticketValues[it.value] }.reduce { acc, i -> acc * i } + + println(departureProduct) +} \ No newline at end of file