import java.io.File
import java.io.BufferedReader
val puzzle = File("puzzle.aoc").readLines()
Day 7: Some Assembly Required
Part 1
This year, Santa brought little Bobby Tables a set of wires and bitwise logic gates! Unfortunately, little Bobby is a little under the recommended age range, and he needs help assembling the circuit.
Each wire has an identifier (some lowercase letters) and can carry a 16-bit signal (a number from 0 to 65535). A signal is provided to each wire by a gate, another wire, or some specific value. Each wire can only get a signal from one source, but can provide its signal to multiple destinations. A gate provides no signal until all of its inputs have a signal.
The included instructions booklet describes how to connect the parts together: x AND y -> z means to connect wires x and y to an AND gate, and then connect its output to wire z.
For example:
123 -> xmeans that the signal123is provided to wirex.x AND y -> zmeans that the bitwiseANDof wirexand wireyis provided to wirez.p LSHIFT 2 -> qmeans that the value from wirepis left-shifted by2and then provided to wireq.NOT e -> fmeans that the bitwise complement of the value from wireeis provided to wiref.
Other possible gates include OR (bitwise OR) and RSHIFT (right-shift). If, for some reason, you’d like to emulate the circuit instead, almost all programming languages (for example, C, JavaScript, or Python) provide operators for these gates.
For example, here is a simple circuit:
123 -> x
456 -> y
x AND y -> d
x OR y -> e
x LSHIFT 2 -> f
y RSHIFT 2 -> g
NOT x -> h
NOT y -> i
After it is run, these are the signals on the wires:
d: 72
e: 507
f: 492
g: 114
h: 65412
i: 65079
x: 123
y: 456
sealed class Exp()
class Num(val n : Int) : Exp()
class Id(val name : String) : Exp()
class Not(val wire : Exp) : Exp()
class And(val l: Exp, val r: Exp) : Exp()
class Or (val l: Exp, val r: Exp) : Exp()
class LShift(val wire : Exp, val amount : Int) : Exp()
class RShift(val wire : Exp, val amount : Int) : Exp()
class Nil() : Exp()
fun eval(e : Exp?, env : Map<String,Exp>) : Exp {
println(e)
when (e) {
null -> error("Error")
is Num -> return e
is Id -> return eval(env.get(e.name), env)
is Not -> when (val erg = eval(e.wire, env)) {
is Num -> return Num(erg.n.inv())
else -> error("No number")
}
is And -> when (val l = eval(e.l, env)) {
is Num -> when (val r = eval(e.r, env)) {
is Num -> return Num(l.n and r.n)
else -> error("Not a number")
}
else -> error("Not a number")
}
is Or -> when (val l = eval(e.l, env)) {
is Num -> when (val r = eval(e.r, env)) {
is Num -> return Num(l.n or r.n)
else -> error("Not a number")
}
else -> error("Not a number")
}
is LShift -> when (val x = eval(e.wire, env)) {
is Num -> Num(x.n shl e.amount)
else -> error("Not a number")
}
is RShift -> when (val x = eval(e.wire, env)) {
is Num -> Num(x.n shr e.amount)
else -> error("Not a number")
}
is Nil -> error("Could not be evaluated")
else -> error("For whatever reason didn't evaluate")
}
return Nil()
}
fun stringToExp(input : String) : Exp {
val split = input.split(" ")
when (split.size) {
1 -> when (split[0].contains(Regex("[0-9]"))) {
true -> return Num(split[0].toInt())
false -> return Id(split[0])
}
2 -> return Not(Id(split[1]))
3 -> when (split[1]) {
"AND" -> return And(Id(split[0]), Id(split[2]))
"OR" -> return Or(Id(split[0]), Id(split[2]))
"LShift" -> return LShift(Id(split[0]), split[2].toInt())
"RShift" -> return RShift(Id(split[0]), split[2].toInt())
}
}
return Nil()
}
Task 1: In little Bobby’s kit’s instructions booklet (provided as your puzzle input), what signal is ultimately provided to wire a?
val map : Map<String,Exp> = mutableMapOf()
for (l in puzzle) {
val x = l.split(" -> ")
map.plus(mapOf(x[1] to stringToExp(x[0])))
print(x[1] + '.')
}
eval(Id("a"), map)