80 lines
2.3 KiB
Swift
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)")
|
|
}
|
|
}
|