Skip to the content.
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:

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)