#23 En el 6 la clave es que cada objeto solo orbita directamente alrededor de otro objeto. Buscar las orbitas indirectas al final es buscar recursivamente orbitas directas, así que la clave es poder hacer busquedas de orbitas directas rápido. Guardando en un diccionario/hashmap las orbitas directas, siendo la key el objecto que orbita y el value el target, se pueden hacer queries y resolver el ejercicio fácil.
Mi solucion en Swift// Input
let map = try String(
contentsOfFile: Bundle.main.path(forResource: "OrbitsMap", ofType: "txt")!,
encoding: String.Encoding.utf8
).split(separator: "\n").map(String.init)
/// Put the orbits in a dictionary where key is the orbiting plannet and the value is the target. This allows to quickly search orbits.
func computeOrbitsDict(forMap map: [String]) -> [String: String] {
map.reduce([String: String]()) { dict, rule in
let rulePieces = rule.split(separator: ")").map(String.init)
var dict = dict
dict[rulePieces[1]] = rulePieces[0]
return dict
}
}
/// Returns the full hierarchy of orbits starting from the given object.
func orbits(from: String, inOrbitsDict orbitsDict: [String: String]) -> [String] {
var orbits: [String] = []
var target = orbitsDict[from]
while target != nil {
orbits.append(target!)
target = orbitsDict[target!]
}
return orbits
}
/// Counts all orbits on a map.
func countOrbits(map: [String]) -> Int {
let orbitsDict = computeOrbitsDict(forMap: map)
return orbitsDict.keys
.map { orbits(from: $0, inOrbitsDict: orbitsDict) }
.map { $0.count }
.reduce(0, +)
}
let totalOrbits = countOrbits(map: map)
/// --- Part Two ---
func transfersRequired(from: String, to: String, inMap map: [String]) -> Int {
let orbitsDict = computeOrbitsDict(forMap: map)
let fromOrbits = orbits(from: from, inOrbitsDict: orbitsDict)
let toOrbits = orbits(from: to, inOrbitsDict: orbitsDict)
let intersections = Set(fromOrbits).intersection(toOrbits)
return intersections.map {
fromOrbits.firstIndex(of: $0)! + toOrbits.firstIndex(of: $0)!
}.min()!
}
let transfers = transfersRequired(from: "YOU", to: "SAN", inMap: map)
#17 El refactor para el 7 parte 2 me ha costado un rato, ya que mi IntcodeComputer era una función con array de inputs que devolvía array de outputs y he tenido que cambiar bastantes cosas para hacer el feedback loop. ¿Como estructuras el proyecto? Yo estaba intentando separar cada día en un archivo, pero con esta cadena de ejercicios está gracioso extraer y compartir el código de la IntcodeComputer, que así se puede seguir mejorando por separado y se debería poder usar esta última version para resolver los ejercicios 2 y 5 sin problema!