// // File.swift // // // Created by Max Nuding on 05.12.21. // import Foundation import Runner import Collections struct Day10: Runnable { let inputPath: String public func run() { let input = try! String(contentsOfFile: inputPath) let lines = input .trimmingCharacters(in: .newlines) .components(separatedBy: .newlines) var s = Deque() var illegalCharacters = [String.Element]() var autocompleteScores = [Int]() for line in lines { s = Deque() var isIllegalLine = false for char in line { if char.isClosing { guard let popped = s.popFirst() else { fatalError() } guard let shouldBeClosedBy = popped.closedBy else { fatalError() } if shouldBeClosedBy == char { continue // Valid chunk } //print("Line: \(lineNumber): Expected \(shouldBeClosedBy), but found \(char) instead") illegalCharacters.append(char) isIllegalLine = true break } s.prepend(char) } if !isIllegalLine { var lineScore = 0 s.reverse() while let last = s.popLast() { let charValue = last.closedBy!.autocompleteScore! lineScore = lineScore * 5 + charValue } autocompleteScores.append(lineScore) } } print(illegalCharacters.map{$0.score!}.reduce(0,+)) print(autocompleteScores.sorted()[autocompleteScores.count / 2]) } } extension String.Element { var isClosing: Bool { self == "]" || self == ")" || self == ">" || self == "}" } var closedBy: String.Element? { switch self { case "[": return "]" case "(": return ")" case "{": return "}" case "<": return ">" default: return nil } } var score: Int? { switch self { case ")": return 3 case "]": return 57 case "}": return 1197 case ">": return 25137 default: return nil } } var autocompleteScore: Int? { switch self { case ")": return 1 case "]": return 2 case "}": return 3 case ">": return 4 default: return nil } } }