Add 2019 solutions
This commit is contained in:
parent
43a2ee8414
commit
4d5c8ee8ce
27 changed files with 3198 additions and 0 deletions
118
2019/AoC.playground/Sources/IntCode.swift
Normal file
118
2019/AoC.playground/Sources/IntCode.swift
Normal file
|
@ -0,0 +1,118 @@
|
|||
|
||||
|
||||
func pow(base: Int = 10, _ n: Int) -> Int {
|
||||
precondition( n >= 0 )
|
||||
switch n {
|
||||
case 0: return 1
|
||||
case 1: return base
|
||||
case _ where n.isMultiple(of: 2):
|
||||
return pow(base: base * base, n / 2)
|
||||
default:
|
||||
return base * pow(base: base * base, n / 2)
|
||||
}
|
||||
}
|
||||
|
||||
public protocol IO: class {
|
||||
func input() -> Int
|
||||
func output(_ value: Int)
|
||||
}
|
||||
|
||||
public class IntCode {
|
||||
var memory: [Int]
|
||||
|
||||
var pc = 0
|
||||
var base = 0
|
||||
|
||||
var io: IO
|
||||
|
||||
public init(program: [Int], io: IO) {
|
||||
self.memory = program
|
||||
self.io = io
|
||||
}
|
||||
|
||||
func address(_ index: Int) -> Int {
|
||||
let mode = (memory[pc] / pow(2 + index - 1)) % 10
|
||||
|
||||
switch mode {
|
||||
case 0: return memory[pc + index]
|
||||
case 1: return pc + index
|
||||
case 2: return memory[pc + index] + base
|
||||
default: preconditionFailure("Unknown mode \(mode)")
|
||||
}
|
||||
}
|
||||
|
||||
func get(_ index: Int) -> Int {
|
||||
let addr = address(index)
|
||||
return addr < memory.count ? memory[addr] : 0
|
||||
}
|
||||
|
||||
func put(_ index: Int, value: Int) {
|
||||
|
||||
let addr = address(index)
|
||||
|
||||
let toAdd = addr - memory.count + 1
|
||||
if toAdd > 0 {
|
||||
memory.append(contentsOf: Array(repeating: 0, count: toAdd))
|
||||
}
|
||||
|
||||
memory[addr] = value
|
||||
}
|
||||
|
||||
|
||||
public func run() {
|
||||
loop: while(true) {
|
||||
let opcode = memory[pc] % 100
|
||||
|
||||
switch opcode {
|
||||
case 1:
|
||||
put(3, value: get(1) + get(2))
|
||||
pc += 4
|
||||
|
||||
case 2:
|
||||
put(3, value: get(1) * get(2))
|
||||
pc += 4
|
||||
|
||||
case 3:
|
||||
put(1, value: io.input())
|
||||
pc += 2
|
||||
|
||||
case 4:
|
||||
io.output(get(1))
|
||||
pc += 2
|
||||
|
||||
case 5:
|
||||
if get(1) != 0 {
|
||||
pc = get(2)
|
||||
} else {
|
||||
pc += 3
|
||||
}
|
||||
|
||||
case 6:
|
||||
if get(1) == 0 {
|
||||
pc = get(2)
|
||||
} else {
|
||||
pc += 3
|
||||
}
|
||||
|
||||
case 7:
|
||||
put(3, value: get(1) < get(2) ? 1 : 0)
|
||||
pc += 4
|
||||
|
||||
case 8:
|
||||
put(3, value: get(1) == get(2) ? 1 : 0)
|
||||
pc += 4
|
||||
|
||||
case 9:
|
||||
base += get(1)
|
||||
pc += 2
|
||||
|
||||
case 99:
|
||||
break loop
|
||||
|
||||
default:
|
||||
preconditionFailure("Unknown opcode \(opcode)")
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
28
2019/AoC.playground/Sources/Tools.swift
Normal file
28
2019/AoC.playground/Sources/Tools.swift
Normal file
|
@ -0,0 +1,28 @@
|
|||
public struct Array2d<T> {
|
||||
public let width: Int
|
||||
public let height: Int
|
||||
private(set) public var data: [T]
|
||||
|
||||
public init(initial: T, width: Int, height: Int) {
|
||||
precondition(width > 0 && height > 0)
|
||||
|
||||
self.width = width
|
||||
self.height = height
|
||||
data = Array(repeating: initial, count: width * height)
|
||||
}
|
||||
|
||||
public subscript(pos: (Int, Int)) -> T {
|
||||
get {
|
||||
let (x, y) = pos
|
||||
precondition(0..<width ~= x)
|
||||
precondition(0..<height ~= y)
|
||||
return data[x + y * width]
|
||||
}
|
||||
set(newValue) {
|
||||
let (x, y) = pos
|
||||
precondition(0..<width ~= x)
|
||||
precondition(0..<height ~= y)
|
||||
data[x + y * width] = newValue
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue