andreiz / advent-of-code-2023-swift

Copilot and ChatGPT assisted Advent of Code 2023 to learn Swift.
0 stars 0 forks source link

Day 9: Mirage Maintenance #9

Open andreiz opened 10 months ago

andreiz commented 10 months ago

https://adventofcode.com/2023/day/9

Input: https://adventofcode.com/2023/day/9/input

andreiz commented 10 months ago

First thing we need to do is calculate arrays of successive differences until all the numbers in the array are the same (or, equivalently, we reach an array where the first element is 0).

I asked ChatGPT to write me a function that determines whether all the elements in the array are the same and it gave me this:

func allElementsAreEqual<T: Equatable>(_ array: [T]) -> Bool {
    guard let firstElement = array.first else { return true } // Empty array is considered to have all equal elements
    return array.allSatisfy { $0 == firstElement }
}

So now I know how to templatize a function.

andreiz commented 10 months ago

Then we just iterate over the input array of numbers, computing differences and appending the resulting array to the result, until allElementsAreEqual gives us the stopping condition.

func calculateDifferences(_ input: [Int]) -> [[Int]] {
    var result = [input]
    var currentSequence = input

    while true {
        let newSequence = zip(currentSequence, currentSequence.dropFirst()).map { $1 - $0 }
        result.append(newSequence)
        if allElementsAreEqual(newSequence) {
            break
        }
        currentSequence = newSequence
    }
    return result
}
andreiz commented 10 months ago

Once we have this, part 1 is trivial. Taking extended arrays from the puzzle text:

10  13  16  21  30  45  *68*
   3   3   5   9  15  *23*
     0   2   4   6  *8*
       2   2   2  *2*

We can see that 8 is equal to 2+6, then 23 is equal to 2+6+15, then 68 is 2+6+15+45. So we just need to sum the last values of the array.

andreiz commented 10 months ago

Part 2 is almost as trivial.

*5*  10  13  16  21  30  45
  *5*   3   3   5   9  15
   *-2*   0   2   4   6
      *2*   2   2   2

Starting with 2, we calculate the previous line as 0 - 2 = -2, then the one before is 3 - (-2) = 5, then 10 - 5 = 5.

andreiz commented 10 months ago

Translated into code:

var sumLast = 0
var sumFirst = 0
for line in input {
    let differences = calculateDifferences(line)
    let lastValue = differences.reduce(0) { current, sequence in
        current + (sequence.last ?? 0)
    }
    let firstValue = differences.reversed().reduce(0) { current, sequence in
        -current + (sequence.first ?? 0)
    }
    print("lastValue: \(lastValue)")
    print("firstValue: \(firstValue)")
    sumLast += lastValue
    sumFirst += firstValue
}
andreiz commented 10 months ago

This passes with the test and actual inputs.