DEV Community

Discussion on: AoC Day 2: Inventory Management System

Collapse
 
macshome profile image
Josh Wisenbaker

I'm not super thrilled with my Day 2 code, but I haven't really had the time to tweak it with everything going on at work currently.

Swift Solutions
Part 1

This one was fairly simple. Just count how many times each letter appears in each String and act appropriately. I do like the fact that a Swift String type is really an Array of Characters.

// Part 1: Find the checksums
func calculateChecksum(_ idCodes: [String]) -> Int {
    var doubles = 0
    var triples = 0

    idCodes.map { (boxID) in
        var doubleTrue = false
        var tripleTrue = false
        for char in boxID {
            let count = boxID.filter { $0 == char }.count
            if count == 2 {
                doubleTrue = true
            }
            if count == 3 {
                tripleTrue = true
            }
        }
        doubles += doubleTrue ? 1 : 0
        triples += tripleTrue ? 1 : 0
    }
    return doubles * triples
}

let checksum = calculateChecksum(boxIDs)
print("Boxes checksum is: \(checksum)")

Part 2
This one feels clunky, if I get a chance I'll revisit it.

I break on the first hit for a solution to short circuit everything and return the answer, this can help a lot with so many Characters to test.

I use zip(_:_:) with a filter and count to quickly test how many differences there are in the same positions. When I see two strings that differ by one character in the same position I move to the next step.

In the second part I cast the Arrays into Set types so that I can use the Collection Algebra features to quickly find the actual character to remove by subtracting one collection from the other. With that done I can just remove it from the source Array and return what's left.

// Part 2: Box finder
func findTheBoxes(_ idCodes: [String]) -> String {
    var result = ""
    var differceCount = 0

    for boxID in idCodes {
        if differceCount == 1 {
            break
        }
        for code in idCodes {
            differceCount = zip(boxID, code).filter{$0 != $1}.count
            if differceCount == 1 {
                let diff = Set(boxID).subtracting(code)
                if let charToRemove = diff.first {
                    result = boxID
                    if let foo = result.index(of: charToRemove) {
                        result.remove(at: foo)
                        break
                    }
                }
            }
        }
    }
    return result
}

let theBoxes = findTheBoxes(boxIDs)
print("Matching box ID is: \(theBoxes)")

Normally I would import Foundation here so that I could just use NSOrderedSet and skip a few steps. I wanted to try and keep it all in the Swift Standard Library though, so I didn't!