public struct KnapsackItem: Hashable { public var name: String public var weight: Int public var value: Int public init(name: String, weight: Int, value: Int) { self.name = name self.weight = weight self.value = value } } public func knapsack(items: [KnapsackItem], limit: Int) -> [KnapsackItem] { var table = Array(repeating: Array(repeating: 0, count: limit + 1), count: items.count + 1) for j in 1...items.count { let item = items[j-1] for w in 1...limit { if item.weight > w { table[j][w] = table[j-1][w] } else { table[j][w] = max(table[j-1][w], table[j-1][w-item.weight] + item.value) } } } var result = [KnapsackItem]() var w = limit for j in stride(from: items.count, to: 0, by: -1) where table[j][w] != table[j-1][w] { let item = items[j-1] result.append(item) w -= item.weight } return result } typealias GroupedItem = (name: String, weight: Int, val: Int, n: Int) let groupedItems: [GroupedItem] = [ ("map", 9, 150, 1), ("compass", 13, 35, 1), ("water", 153, 200, 3), ("sandwich", 50, 60, 2), ("glucose", 15, 60, 2), ("tin", 68, 45, 3), ("banana", 27, 60, 3), ("apple", 39, 40, 3), ("cheese", 23, 30, 1), ("beer", 52, 10, 3), ("suntan cream", 11, 70, 1), ("camera", 32, 30, 1), ("t-shirt", 24, 15, 2), ("trousers", 48, 10, 2), ("umbrella", 73, 40, 1), ("waterproof trousers", 42, 70, 1), ("waterproof overclothes", 43, 75, 1), ("note-case", 22, 80, 1), ("sunglasses", 7, 20, 1), ("towel", 18, 12, 2), ("socks", 4, 50, 1), ("book", 30, 10, 2) ] let items = groupedItems.flatMap({item in (0..