Skip to content

Instantly share code, notes, and snippets.

@ole
Last active December 13, 2024 19:59
Show Gist options
  • Save ole/0eb0906421f68cc5f6d0734f6de90d5f to your computer and use it in GitHub Desktop.
Save ole/0eb0906421f68cc5f6d0734f6de90d5f to your computer and use it in GitHub Desktop.
Solving a system of linear equations with Cocoa Autolayout (Advent of Code 2024 Day 13)
// https://adventofcode.com/2024/day/13
import AppKit
// Button A: X+94, Y+34
// Button B: X+22, Y+67
// Prize: X=8400, Y=5400
let X: CGFloat = 8400
let Y: CGFloat = 5400
let x_a: CGFloat = 94
let x_b: CGFloat = 22
let y_a: CGFloat = 34
let y_b: CGFloat = 67
// Equation 1:
// a * x_a + b * x_b = X
// a = (X - b * x_b) / x_a
// a = X/x_a - b * x_b/x_a
// a = -x_b/x_a * b + X/x_a
// Equation 2:
// a * y_a + b * y_b = Y
// … (solve for a in the same way as eq. 1)
let va = NSView()
va.translatesAutoresizingMaskIntoConstraints = false
let vb = NSView()
vb.translatesAutoresizingMaskIntoConstraints = false
let container = NSView()
container.addSubview(va)
container.addSubview(vb)
let c1 = NSLayoutConstraint(
item: va,
attribute: .width,
relatedBy: .equal,
toItem: vb,
attribute: .width,
multiplier: -x_b/x_a,
constant: X/x_a
)
let c2 = NSLayoutConstraint(
item: va,
attribute: .width,
relatedBy: .equal,
toItem: vb,
attribute: .width,
multiplier: -y_b/y_a,
constant: Y/y_a
)
NSLayoutConstraint.activate([c1, c2])
container.layoutSubtreeIfNeeded()
va.frame.width // A = 80 ✅
vb.frame.width // B = 40 ✅
// A = 80 and B = 40 is the correct solution:
// "The cheapest way to win the prize is by pushing the A button 80 times and the B button 40 times."
//
// (This code only shows that A = 80 and B = 40 is a valid solution, not that it's the cheapest.
// But it's good enough for a proof of concept.)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment