struct Hand { let dominos: Set func trains(startingWith: Int) -> Array { var t = Array() let starts = dominos.filter { $0.connectsTo(startingWith) } for start in starts { let remaining = dominos.subtracting([start]) let train = Train(start: startingWith, path: [start]) t.append(contentsOf: buildTrains(train, remaining: remaining)) } return t } private func buildTrains(_ soFar: Train, remaining: Set) -> Array { var built = [soFar] let start = soFar.final let connections = remaining.filter { $0.connectsTo(start) } for connect in connections { let remainingForTrain = remaining.subtracting([connect]) let thisTrain = Train(start: soFar.start, path: soFar.path + [connect]) let trains = buildTrains(thisTrain, remaining: remainingForTrain) built.append(contentsOf: trains) } return built } func print() { let hasVertical = dominos.filter { $0.isDouble }.count > 0 var printedLines = Array>(repeating: [], count: hasVertical ? 5 : 3) for t in dominos { var lines = t.tile().split(separator: "\n").map { Array($0) } if hasVertical == true && t.isDouble == false { lines.insert(Array(repeating: " ", count: Domino.horizontalTileWidth), at: 0) lines.append(Array(repeating: " ", count: Domino.horizontalTileWidth)) } // append a space after this tile printedLines = printedLines.enumerated().map { $1 + lines[$0] + [" "] } } for l in printedLines { Swift.print(String(l)) } } }