Files
aoc24/day14/d14p2.swift
2024-12-15 21:09:15 -08:00

80 lines
2.3 KiB
Swift

import Foundation
let (w, h) = (101, 103)
infix operator %%: MultiplicationPrecedence
func %%<T: BinaryInteger>(lhs: T, rhs: T) -> T {
return (lhs % rhs + rhs) % rhs
}
struct Robot : CustomStringConvertible {
var (x, y): (Int, Int)
let (vx, vy): (Int, Int)
var description: String { return "p=(\(x), \(y)) v=(\(vx), \(vy))" }
mutating func move() {
x = (x + vx) %% w
y = (y + vy) %% h
}
}
func readInput(_ filePath: String) throws -> [Robot] {
let robot = try Regex(#"p=([0-9]+),([0-9]+) v=([0-9-]+),([0-9-]+)"#)
var robots: [Robot] = []
let content = try String(contentsOfFile: filePath, encoding: .ascii)
content.split(separator: "\n").forEach { line in
if let m = line.wholeMatch(of: robot) {
robots.append(Robot(
x: Int(m.output[1].substring!)!,
y: Int(m.output[2].substring!)!,
vx: Int(m.output[3].substring!)!,
vy: Int(m.output[4].substring!)!
))
}
}
return robots
}
func variance(_ bots: [Robot]) -> Int {
let (sX, sY) = bots.reduce((0, 0)) { s, bot in (s.0 + bot.x, s.1 + bot.y) }
let (mX, mY) = (sX/bots.count, sY/bots.count)
return bots.reduce(0) { s, bot in
s + (mX-bot.x)*(mX-bot.x) + (mY-bot.y)*(mY-bot.y) }
}
func printRobots(_ bots: [Robot]) -> String {
var screen: [[String]] = Array(
repeating: Array(repeating: " ", count: 101),
count: 52
)
bots.forEach { bot in
let (q, r) = bot.y.quotientAndRemainder(dividingBy: 2)
if screen[q][bot.x] == " " {
screen[q][bot.x] = (r == 0) ? "" : ""
} else {
screen[q][bot.x] = ""
}
}
return "" + String(repeating: "", count: w) + "\n" +
screen.map { row in "" + row.joined() + "" }.joined(separator: "\n") +
"\n" + String(repeating: "", count: w) + ""
}
var bots = try readInput(CommandLine.arguments[1])
var i = 0
var minSigma = Int.max
while true {
i += 1
for i in 0..<bots.count {
bots[i].move()
}
let printout = printRobots(bots)
let sigma = variance(bots)
if sigma < minSigma {
minSigma = sigma
//print("\u{001B}[2J")
print(printout)
print("i=\(i) s²=\(sigma)")
}
}