50 lines
1.4 KiB
Swift
50 lines
1.4 KiB
Swift
import Foundation
|
|
|
|
func readInput(_ filePath: String) throws -> [Equation] {
|
|
let content = try String(contentsOfFile: filePath, encoding: .ascii)
|
|
return content.split(separator: "\n").map { Equation(from: String($0)) }
|
|
}
|
|
|
|
struct Equation {
|
|
let left: Int
|
|
let right: [Int]
|
|
|
|
init(from s: String) {
|
|
let split = s.split(separator: " ")
|
|
left = Int(split[0].filter { $0 != ":" })!
|
|
right = split.dropFirst().map { Int($0)! }
|
|
}
|
|
|
|
func valid(with ops: [(Int, Int) -> Int]) -> Bool {
|
|
if ops.count != right.count - 1 {
|
|
return false
|
|
}
|
|
return left == ops.enumerated().reduce(right[0], { acc, op in
|
|
op.1(acc, right[op.0+1])
|
|
})
|
|
}
|
|
}
|
|
|
|
extension Int {
|
|
static func |(lhs: Int, rhs: Int) -> Int {
|
|
let order = String(rhs).count
|
|
return lhs * Int(truncating: pow(10, order) as NSNumber) + rhs
|
|
}
|
|
}
|
|
|
|
func combo<T>(of symbols: [T], len: Int) -> [[T]] {
|
|
if len == 0 {
|
|
return [[]]
|
|
}
|
|
let cdrs = combo(of: symbols, len: len - 1)
|
|
return symbols.flatMap { s in cdrs.map { cdr in [s] + cdr } }
|
|
}
|
|
|
|
let op: [(Int, Int) -> Int] = [(+), (*), (|)]
|
|
let eqs = try readInput(CommandLine.arguments[1])
|
|
let answer = eqs
|
|
.filter { eq in
|
|
combo(of: op, len: eq.right.count - 1).contains { eq.valid(with: $0) }
|
|
}.reduce(0, { s, eq in s + eq.left })
|
|
print(answer)
|