DEV Community

Discussion on: Advent of Code 2019 Solution Megathread - Day 6: Universal Orbit Map

Collapse
 
rizzu26 profile image
Rizwan

Day dusted with swift

import Cocoa

func directAndImmediateOrbits(_ input: [String]) -> Int {
    var orbits: [String : String] = [:]
    input.forEach { (orbit) in
        let pair = orbit.components(separatedBy: ")")
        orbits[pair[1]] = pair[0]
    }

    let root = "COM"

    func depthForNode(_ node: String) -> Int {
        if node == root {
            return 0
        }
        var total = 0
        total = total + 1 + depthForNode(orbits[node]!)
        return total
    }
    depthForNode("COM")
    var total = 0
    orbits.keys.forEach { (key) in
        total += depthForNode(key)
    }
    return total
}

func orbitTransfersCount(_ input: [String], _ startAndEnd: (String,String)) -> Int {
    var orbits: [String : String] = [:]
    input.forEach { (orbit) in
        let pair = orbit.components(separatedBy: ")")
        orbits[pair[1]] = pair[0]
    }

    var parents : [String] = []
    func depthToRoot(_ node: String,_ root: String = "COM") -> Int {
        if node == root {
            return 0
        }
        var total = 0
        if let orbit = orbits[node] {
            parents.append(orbit)
            total = total + 1 + depthToRoot(orbit,root)
        }
        return total
    }

    func ancestors(_ node: String) -> [String] {
        parents.removeAll()
        depthToRoot(node,"COM")
        return parents
    }

    let p1 = ancestors(startAndEnd.0)
    let p2 = ancestors(startAndEnd.1)

    func getCommonParent(_ p1: [String], _ p2: [String]) -> String {
        let commonParent: String = ""
        for (index,p1) in p1.enumerated() {
            for (index,p2) in p2.enumerated() {
                if p1 == p2 {
                    return p1
                }
            }
        }
        return ""
    }

    let common = getCommonParent(p1, p2)
    var total = depthToRoot(startAndEnd.0,common) + depthToRoot(startAndEnd.1,common) - 2
    return total
}


func testCase1() -> Int {
    let input = """
        COM)B
        B)C
        C)D
        D)E
        E)F
        B)G
        G)H
        D)I
        E)J
        J)K
        K)L
        """.trimmingCharacters(in: .whitespacesAndNewlines).components(separatedBy: .newlines)
    return directAndImmediateOrbits(input)
}

func testCase2() -> Int {
    let input = """
           COM)B
           B)C
           C)D
           D)E
           E)F
           B)G
           G)H
           D)I
           E)J
           J)K
           K)L
           K)YOU
           I)SAN
           """.trimmingCharacters(in: .whitespacesAndNewlines).components(separatedBy: .newlines)
    return orbitTransfersCount(input, ("YOU","SAN"))
}

func allTestCases() {
    print(testCase1())
    print(testCase2())
}

allTestCases()
func partOne() -> Int {
    return directAndImmediateOrbits(input)
}

func partTwo() -> Int {
    return orbitTransfersCount(input, ("YOU","SAN"))
}

print(partOne())
print(partTwo())