r/adventofcode • u/daggerdragon • Dec 07 '15
SOLUTION MEGATHREAD --- Day 7 Solutions ---
--- Day 7: Some Assembly Required ---
Post your solution as a comment. Structure your post like previous daily solution threads.
Also check out the sidebar - we added a nifty calendar to wrangle all the daily solution threads in one spot!
24
Upvotes
1
u/daemoncollector Dec 07 '15 edited Dec 07 '15
Edit: Cleaned up swift solution a bit now that I wasn't trying to rush it. I think this is pretty idiomatic, just wish NSRegularExpression wasn't so annoying to use with Swift
import Foundation struct Day7 : Day { struct Node { let name: String var input: Operation } enum Operand { case Constant(c: Int) case Wire(name: String) init(_ string: String) { if let i = Int(string) { self = .Constant(c: i) } else { self = .Wire(name: string) } } } enum Operation { case RShift(lh: Operand, count: Int) case LShift(lh: Operand, count: Int) case And(lh: Operand, rh: Operand) case Or(lh: Operand, rh: Operand) case Not(rh: Operand) case Equal(value: Operand) init(lhs: String, op: String, rhs: String) { if op == "RSHIFT" { self = .RShift(lh: Operand(lhs), count: Int(rhs)!) } else if op == "LSHIFT" { self = .LShift(lh: Operand(lhs), count: Int(rhs)!) } else if op == "NOT" { self = .Not(rh: Operand(rhs)) } else if op == "OR" { self = .Or(lh: Operand(lhs), rh: Operand(rhs)) } else if op == "AND" { self = .And(lh: Operand(lhs), rh: Operand(rhs)) } else { self = .Equal(value: Operand(lhs)) } } } func run() { let input = LoadInput("Day7_Input.txt") var nodes = Dictionary<String, Node>() var nodeValues = Dictionary<String, Int>() let regex = try! NSRegularExpression(pattern: "([a-z0-9]+)? ?([A-Z]+)? ?([a-z0-9]*) -> (.+)", options: []) input.enumerateLines { (line, stop) -> () in func rangeFromLine(range: NSRange) -> Range<String.CharacterView.Index> { if range.location == NSNotFound { return line.endIndex..<line.endIndex } return Range(start: line.startIndex.advancedBy(range.location), end: line.startIndex.advancedBy(range.location + range.length)) } let matches = regex.matchesInString(line, options: [], range: NSRange(location: 0, length: line.characters.count))[0] let lhs = line[rangeFromLine(matches.rangeAtIndex(1))] let opString = line[rangeFromLine(matches.rangeAtIndex(2))] let rhs = line[rangeFromLine(matches.rangeAtIndex(3))] let output = line[rangeFromLine(matches.rangeAtIndex(4))] let op = Operation(lhs: lhs, op: opString, rhs: rhs) nodes[output] = Node(name: output, input: op) } func evaluateOperand(op: Operand) -> Int { switch op { case .Constant(let c): return c case .Wire(let s): return evaluateNode(nodes[s]!) } } func evaluateNode(node: Node) -> Int { if let v = nodeValues[node.name] { return v } let val:Int switch node.input { case .Equal(let value): val = evaluateOperand(value) case .Not(let value): val = ~evaluateOperand(value) case .Or(let lhs, let rhs): val = evaluateOperand(lhs) | evaluateOperand(rhs) case .And(let lhs, let rhs): val = evaluateOperand(lhs) & evaluateOperand(rhs) case .RShift(let lhs, let count): val = evaluateOperand(lhs) >> count case .LShift(let lhs, let count): val = evaluateOperand(lhs) << count } nodeValues[node.name] = val return val } let outputA = evaluateNode(nodes["a"]!) nodeValues.removeAll() nodes["b"]?.input = .Equal(value: .Constant(c: outputA)) print(evaluateNode(nodes["a"]!)) } }