2022 Day 11 part 1
This commit is contained in:
parent
38e4d396e1
commit
b378808cda
1 changed files with 136 additions and 0 deletions
136
2022/day11.swift
Normal file
136
2022/day11.swift
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
typealias Item = Int
|
||||||
|
|
||||||
|
class Monkey {
|
||||||
|
var items: [Item]
|
||||||
|
var operation: Operation
|
||||||
|
var operand: Operand
|
||||||
|
var test: Int
|
||||||
|
var trueTarget: Int
|
||||||
|
var falseTarget: Int
|
||||||
|
var inspectCount = 0
|
||||||
|
|
||||||
|
init(items: [Item], operation: Operation, operand: Operand, test: Int, trueTarget: Int, falseTarget: Int) {
|
||||||
|
self.items = items
|
||||||
|
self.operation = operation
|
||||||
|
self.operand = operand
|
||||||
|
self.test = test
|
||||||
|
self.trueTarget = trueTarget
|
||||||
|
self.falseTarget = falseTarget
|
||||||
|
}
|
||||||
|
|
||||||
|
func run() {
|
||||||
|
for item in items {
|
||||||
|
inspectCount += 1
|
||||||
|
let newLevel = operation.apply(item, operand.value(item: item)) / 3
|
||||||
|
let target = newLevel.isMultiple(of: test) ? trueTarget : falseTarget
|
||||||
|
monkeys[target].add(newLevel)
|
||||||
|
}
|
||||||
|
items.removeAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
func add(_ item: Item) {
|
||||||
|
items.append(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Monkey {
|
||||||
|
convenience init?(scanner: Scanner) {
|
||||||
|
guard scanner.scanString("Monkey") != nil, scanner.scanInt() != nil, scanner.scanString(":") != nil else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
guard scanner.scanString("Starting items:") != nil else { return nil }
|
||||||
|
let items = scanner.scanList().map(Item.init(_:))
|
||||||
|
|
||||||
|
guard scanner.scanString("Operation: new = old") != nil, let operation = scanner.scanOperation(), let operand = scanner.scanOperand() else { return nil }
|
||||||
|
|
||||||
|
guard scanner.scanString("Test: divisible by") != nil, let test = scanner.scanInt() else { return nil }
|
||||||
|
guard scanner.scanString("If true: throw to monkey") != nil, let trueTarget = scanner.scanInt() else { return nil }
|
||||||
|
guard scanner.scanString("If false: throw to monkey") != nil, let falseTarget = scanner.scanInt() else { return nil }
|
||||||
|
|
||||||
|
self.init(items: items, operation: operation, operand: operand, test: test, trueTarget: trueTarget, falseTarget: falseTarget)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum Operation: String, CaseIterable {
|
||||||
|
case add = "+"
|
||||||
|
case multiply = "*"
|
||||||
|
|
||||||
|
func apply(_ lhs: Item, _ rhs: Item) -> Item {
|
||||||
|
switch self {
|
||||||
|
case .add: return lhs + rhs
|
||||||
|
case .multiply: return lhs * rhs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Operand {
|
||||||
|
case number(Int)
|
||||||
|
case old
|
||||||
|
|
||||||
|
func value(item: Item) -> Item {
|
||||||
|
switch self {
|
||||||
|
case .number(let number): return Item(number)
|
||||||
|
case .old: return item
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Scanner {
|
||||||
|
func scanList() -> [Int] {
|
||||||
|
var result: [Int] = []
|
||||||
|
while true {
|
||||||
|
guard let int = scanInt() else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
result.append(int)
|
||||||
|
guard scanString(",") != nil else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func scanOperation() -> Operation? {
|
||||||
|
for op in Operation.allCases {
|
||||||
|
if scanString(op.rawValue) != nil {
|
||||||
|
return op
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func scanOperand() -> Operand? {
|
||||||
|
if let int = scanInt() {
|
||||||
|
return .number(int)
|
||||||
|
}
|
||||||
|
|
||||||
|
if scanString("old") != nil {
|
||||||
|
return .old
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let input = try String(contentsOf: URL(fileURLWithPath: "day11.input"))
|
||||||
|
let scanner = Scanner(string: input)
|
||||||
|
var monkeys: [Monkey] = []
|
||||||
|
|
||||||
|
while !scanner.isAtEnd, let monkey = Monkey(scanner: scanner) {
|
||||||
|
monkeys.append(monkey)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for _ in 0..<20 {
|
||||||
|
for monkey in monkeys {
|
||||||
|
monkey.run()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let monkeyBusiness = monkeys.map(\.inspectCount).sorted(by: >).prefix(2).reduce(1, *)
|
||||||
|
print("Part 1:", monkeyBusiness)
|
Loading…
Add table
Reference in a new issue