Skip to content

Instantly share code, notes, and snippets.

@felix-larsen
Created December 7, 2020 20:20
Show Gist options
  • Save felix-larsen/52695bb1f8fcf37a364b10c602b3f192 to your computer and use it in GitHub Desktop.
Save felix-larsen/52695bb1f8fcf37a364b10c602b3f192 to your computer and use it in GitHub Desktop.
7th December solution - Advent of Code - swift
var list = listBagsContaining(with: bagMap, withBagName: "shinygold", allBagNames: [String]())
func listBagsContaining(with bags: [String : [Bag]], withBagName bagName: String, allBagNames: [String]) -> [String] {
let containingBagNames = bags.filter {
key, value in
value.map({ $0.name}).contains(bagName)
}
.compactMap { $0.key }
if containingBagNames.count == 0 {
return allBagNames + [bagName]
} else {
return allBagNames + containingBagNames.flatMap({ bag in
return listBagsContaining(with: bags, withBagName: bag, allBagNames: allBagNames + [bagName])
})
}
}
// subtract one as shiny gold bag is not counted
print(Set(list).count - 1)
var shinyGoldCount = countBagsContained(with: bagMap, in: Bag(name: "shinygold", count: 1), startCount: 0)
func countBagsContained(with bags : [String : [Bag]], in bag: Bag, startCount: Int) -> Int {
let containingBagNames = bags[bag.name]
if containingBagNames?.count == 0 || containingBagNames == nil {
return startCount
} else {
return startCount + bag.count * containingBagNames!.reduce(0,{ start, aBag in
return start + countBagsContained(with: bags, in: aBag, startCount: aBag.count)
})
}
}
print(shinyGoldCount)
let filename = "/Users/felix/xCodeProjects/AdventOfCode2020.playground/Resources/december07.txt"
let contents = try! String(contentsOfFile: filename)
let lines = contents.components(separatedBy: CharacterSet.newlines)
struct Bag : Hashable {
let name: String
let count: Int
}
var bagMap = [String : [Bag]]()
lines.forEach { (line) in
if !line.isEmpty {
let splittedFirstPart = line.components(separatedBy: " contain ")
let bagName = splittedFirstPart[0].components(separatedBy: " ")
let bag = bagName[0] + bagName[1]
var containingBags = [Bag]()
let containingBagsString = splittedFirstPart[1].components(separatedBy: ", ")
containingBagsString.forEach { (containingBagString) in
let bagParts = containingBagString.components(separatedBy: " ")
if !bagParts.contains("no") {
containingBags.append(Bag(name: bagParts[1] + bagParts[2], count: Int(bagParts[0])!))
}
}
bagMap[bag] = containingBags
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment