import Foundation struct Key : CustomStringConvertible { let pins: [Int] var description: String { return "(" + pins.map(String.init).joined(separator: ",") + ")" } init(_ block: ArraySlice<[Character]>) { var pins: [Int] = [0, 0, 0, 0, 0] ((block.startIndex+1)..<(block.endIndex-1)).forEach { i in for j in 0..<5 { if pins[j] == 0 && block[i][j] == "#" { pins[j] = 6 - (i - block.startIndex) } } } self.pins = pins } } struct Lock : CustomStringConvertible { let pins: [Int] var description: String { return "(" + pins.map(String.init).joined(separator: ",") + ")" } init(_ block: ArraySlice<[Character]>) { var pins: [Int] = [0, 0, 0, 0, 0] ((block.startIndex+1)..<(block.endIndex-1)).reversed().forEach { i in for j in 0..<5 { if pins[j] == 0 && block[i][j] == "#" { pins[j] = i - block.startIndex } } } self.pins = pins } } func readInput(_ filePath: String) throws -> ([Lock], [Key]) { let content = try String(contentsOfFile: filePath, encoding: .ascii) let lines = content.split(separator: "\n", omittingEmptySubsequences: false) var locks: [Lock] = [] var keys: [Key] = [] lines.map(Array.init).split(separator: []).forEach { block in if block[block.startIndex][0] == "#" { locks.append(Lock(block)) } else { keys.append(Key(block)) } } return (locks, keys) } let (locks, keys) = try readInput(CommandLine.arguments[1]) var answer = 0 for lock in locks { for key in keys { answer += zip(lock.pins, key.pins).contains { $0 + $1 > 5 } ? 0 : 1 } } print(answer)