import Foundation typealias Network = [String: Set] func readInput(_ filePath: String) throws -> Network { var map: Network = [:] try String(contentsOfFile: filePath, encoding: .ascii) .split(separator: "\n").map { $0.split(separator: "-") } .map { (String($0[0]), String($0[1])) }.forEach { m1, m2 in map[m1, default: []].insert(m2) map[m2, default: []].insert(m1) } return map } func bronkerbosch( _ network: Network, r: Set, p: Set, x: Set ) -> Set? { if p.count == 0 { return x.count == 0 ? r : nil } var maxClique: Set? = nil var nextP = p var nextX = x let u = p.union(x).first! // can also choose highest degree node for v in p.subtracting(network[u]!) { if let clique = bronkerbosch(network, r: r.union([v]), p: nextP.intersection(network[v]!), x: nextX.intersection(network[v]!) ) { if clique.count > (maxClique ?? []).count { maxClique = clique } } nextP.remove(v) nextX.insert(v) } return maxClique } let conns = try readInput(CommandLine.arguments[1]) let clique = bronkerbosch(conns, r: [], p: Set(conns.keys), x: []) print(Array(clique ?? []).sorted().joined(separator: ","))