d24p1
This commit is contained in:
73
day24/d24p1.swift
Normal file
73
day24/d24p1.swift
Normal file
@@ -0,0 +1,73 @@
|
||||
import Foundation
|
||||
|
||||
typealias Op = (Bool, Bool) -> Bool
|
||||
typealias Gate = (String, Op, String, String)
|
||||
|
||||
struct Circuit : CustomStringConvertible {
|
||||
let gates: [Gate]
|
||||
var nodes: [String: Bool]
|
||||
var pendingEndNodes: Set<String>
|
||||
var description: String {
|
||||
nodes.map { "\($0): \($1 ? 1 : 0)" }.sorted().joined(separator: "\n") +
|
||||
"\n\(pendingEndNodes)"
|
||||
}
|
||||
var value: Int? {
|
||||
if pendingEndNodes.count > 0 { return nil }
|
||||
return nodes.keys.filter { $0.starts(with: "z") }
|
||||
.sorted().reversed().reduce(0) { $0*2 + (nodes[$1]! ? 1 : 0) }
|
||||
}
|
||||
mutating func run(gate: Gate) {
|
||||
let (in1, op, in2, out) = gate
|
||||
if let v1 = nodes[in1], let v2 = nodes[in2] {
|
||||
nodes[out] = op(v1, v2)
|
||||
pendingEndNodes.remove(out)
|
||||
}
|
||||
}
|
||||
mutating func run() {
|
||||
gates.forEach { run(gate: $0) }
|
||||
}
|
||||
}
|
||||
|
||||
func readInput(_ filePath: String) throws -> Circuit {
|
||||
let content = try String(contentsOfFile: filePath, encoding: .ascii)
|
||||
let nodeRe = try Regex(#"([a-z0-9]+): (0|1)"#)
|
||||
let gateRe = try Regex(#"([a-z0-9]+) (AND|OR|XOR) ([a-z0-9]+) -> ([a-z0-9]+)"#)
|
||||
let opMap: [String: Op] = [
|
||||
"AND": { $0 && $1 },
|
||||
"OR": { $0 || $1 },
|
||||
"XOR": { $0 != $1 }
|
||||
]
|
||||
var nodes: [String: Bool] = [:]
|
||||
var gates: [Gate] = []
|
||||
var endNodes: Set<String> = []
|
||||
for line in content.split(separator: "\n") {
|
||||
if let m = line.wholeMatch(of: nodeRe) {
|
||||
let node = String(m.output[1].substring!)
|
||||
let val = m.output[2].substring! == "1"
|
||||
nodes[node] = val
|
||||
}
|
||||
if let m = line.wholeMatch(of: gateRe) {
|
||||
let in1 = String(m.output[1].substring!)
|
||||
let op = opMap[String(m.output[2].substring!)]!
|
||||
let in2 = String(m.output[3].substring!)
|
||||
let out = String(m.output[4].substring!)
|
||||
gates.append((in1, op, in2, out))
|
||||
if out.starts(with: "z") {
|
||||
endNodes.insert(out)
|
||||
}
|
||||
}
|
||||
}
|
||||
return Circuit(gates: gates, nodes: nodes, pendingEndNodes: endNodes)
|
||||
}
|
||||
|
||||
var circuit = try readInput(CommandLine.arguments[1])
|
||||
//print(circuit)
|
||||
while true {
|
||||
if let res = circuit.value {
|
||||
print("answer: \(res)")
|
||||
break
|
||||
}
|
||||
circuit.run()
|
||||
//print(circuit)
|
||||
}
|
||||
|
Reference in New Issue
Block a user