Day14
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
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 kotlin.math.pow
|
||||
import org.eclipse.collections.impl.factory.primitive.IntObjectMaps
|
||||
import org.eclipse.collections.impl.factory.primitive.ObjectLongMaps
|
||||
|
||||
@Day(14)
|
||||
class Day14(@Lines val input: Input<List<String>>) {
|
||||
|
||||
private val memRe = "mem\\[(\\d+)] = (.*)$".toRegex()
|
||||
|
||||
private fun Long.toBin36() = toString(2).padStart(length = 36, padChar = '0')
|
||||
|
||||
fun part1(): Long {
|
||||
val mem = IntObjectMaps.mutable.empty<String>()
|
||||
|
||||
var currentMask: String = ""
|
||||
|
||||
for (line in input.value) {
|
||||
if (line.startsWith("mask")) {
|
||||
currentMask = line.removePrefix("mask = ")
|
||||
} else {
|
||||
val (address, value) = memRe.find(line)!!.destructured
|
||||
val bin = value.toLong().toBin36()
|
||||
|
||||
val result = bin.zip(currentMask)
|
||||
.map { (bin, mask) -> if (mask != 'X') mask else bin }
|
||||
.joinToString("")
|
||||
|
||||
mem.put(address.toInt(), result)
|
||||
}
|
||||
}
|
||||
|
||||
return mem.values()
|
||||
.map { it.dropWhile { it == '0' } }
|
||||
.map { it.toLong(2) }
|
||||
.sum()
|
||||
}
|
||||
|
||||
fun part2(): Long {
|
||||
val mem = ObjectLongMaps.mutable.empty<String>()
|
||||
|
||||
var currentMask: String = ""
|
||||
|
||||
for (line in input.value) {
|
||||
if (line.startsWith("mask")) {
|
||||
currentMask = line.removePrefix("mask = ")
|
||||
} else {
|
||||
val (address, value) = memRe.find(line)!!.destructured.let { (add, value) ->
|
||||
add.toLong().toBin36() to value.toLong()
|
||||
}
|
||||
|
||||
val addresses = address.zip(currentMask).map { (address, mask) ->
|
||||
when (mask) {
|
||||
'X' -> arrayOf('0', '1')
|
||||
'1' -> arrayOf('1')
|
||||
else -> arrayOf(address)
|
||||
}
|
||||
}
|
||||
|
||||
val mutations = currentMask.count { it == 'X' }.let { 2.0.pow(it.toDouble()).toInt() }
|
||||
val builders = Array(mutations) { StringBuilder() }
|
||||
|
||||
var groups = 1
|
||||
|
||||
for (address in addresses) {
|
||||
if (address.size > 1) {
|
||||
groups *= 2
|
||||
val groupSize = mutations / groups
|
||||
var j = 0
|
||||
for (i in 0 until mutations) {
|
||||
val flip = i % groupSize == 0
|
||||
if (flip) j = if (j == 0) 1 else 0
|
||||
builders[i].append(address[j])
|
||||
}
|
||||
} else {
|
||||
builders.forEach { it.append(address[0]) }
|
||||
}
|
||||
}
|
||||
|
||||
builders.map { it.toString() }.forEach { address ->
|
||||
mem.put(address, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mem.values().sum()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun main() = with(createDay<Day14>()) {
|
||||
println(part1())
|
||||
println(part2())
|
||||
}
|
||||
Reference in New Issue
Block a user