Advent of Code Day2: Red-Nosed Reports
Today’s (1)https://adventofcode.com/2024/day/2 challenge was only slightly more complicated than yesterday’s, and one where brute(ish) force was enough. My solution is on Github (2)https://github.com/Abizern/aoc-swift-2024/blob/main/Sources/Day02.swift .
Part 1 #
To check if a report (a list of numbers) is safe; see if they are all increasing or all decreasing and the difference is inclusively between 1 and 3.
I used the adjacentPairs()
method from the Swift-Algorithms package
(3)https://github.com/apple/swift-algorithms
rather than zip
to get a sequence of pairs of numbers.
After checking whether the differences should be increasing or decreasing, I made sure that all the pairs satisfied the condition by using the allSatisfy()
method.
func isSafe(_ report: [Int]) -> Bool {
guard let start = report.first,
let end = report.last,
start != end
else { return false }
let shouldIncrease = start < end ? true : false
return report.adjacentPairs().allSatisfy { a, b in
(shouldIncrease ? a < b : a > b) && (1 ... 3).contains(abs(a - b))
}
}
I used this to filter and count the input to get my answer.
Part 2 #
To check if a report is correctable, see if removing a single number from the list makes it safe. After a few minutes thought about complexity, I used a brute(ish) force solution.
If a report is not safe, I removed one of the numbers and checked again:
func isSafeOrCorrectable(_ report: [Int]) -> Bool {
guard !isSafe(report) else { return true }
let length = report.count
var i = 0
var correctable = false
while i < length, !correctable {
var arr = report
arr.remove(at: i)
correctable = isSafe(arr)
i += 1
}
return correctable
}
And, again, a filter and count gives me the answer.
Complexity #
My completely unscientific assessment of the complexity of removing an element and checking the array again:
The adjacentPairs()
method has \(\mathcal{O}(1)\) complexity, and I’m going through the elements in a single pass which is \(\mathcal{O}(n)\)
Removing and checking the list again means another \(\mathcal{O}(n)\) operation, taking it up to \(\mathcal{O}(n^2)\), which is not good, but at least it’s not exponential.
Looking at the full problem input there are 1000 lines, each with around 10-ish numbers. Each line will require about 100 to 1000 operations. So the full input is around 1 million operations; not a lot.
So, no need to do anything clever, and my solutions are still output in milliseconds.