Add 2019 solutions
This commit is contained in:
parent
43a2ee8414
commit
4d5c8ee8ce
27 changed files with 3198 additions and 0 deletions
BIN
2019/AoC.playground/Contents.o
Normal file
BIN
2019/AoC.playground/Contents.o
Normal file
Binary file not shown.
BIN
2019/AoC.playground/IntCode.o
Normal file
BIN
2019/AoC.playground/IntCode.o
Normal file
Binary file not shown.
2
2019/AoC.playground/IntCode.remap
Normal file
2
2019/AoC.playground/IntCode.remap
Normal file
|
@ -0,0 +1,2 @@
|
|||
[
|
||||
]
|
120
2019/AoC.playground/Pages/Day 1.xcplaygroundpage/Contents.swift
Normal file
120
2019/AoC.playground/Pages/Day 1.xcplaygroundpage/Contents.swift
Normal file
|
@ -0,0 +1,120 @@
|
|||
import Foundation
|
||||
|
||||
let input = """
|
||||
110321
|
||||
61817
|
||||
107271
|
||||
126609
|
||||
84016
|
||||
119187
|
||||
53199
|
||||
117553
|
||||
83163
|
||||
69434
|
||||
62734
|
||||
76774
|
||||
75016
|
||||
126859
|
||||
114626
|
||||
70782
|
||||
102903
|
||||
105871
|
||||
108500
|
||||
149367
|
||||
99266
|
||||
131731
|
||||
86778
|
||||
110561
|
||||
116521
|
||||
138216
|
||||
55347
|
||||
135516
|
||||
126801
|
||||
124902
|
||||
103083
|
||||
130858
|
||||
54885
|
||||
126837
|
||||
71103
|
||||
143975
|
||||
135207
|
||||
77264
|
||||
149331
|
||||
85252
|
||||
78910
|
||||
84007
|
||||
123953
|
||||
87355
|
||||
113433
|
||||
57750
|
||||
78394
|
||||
106081
|
||||
110942
|
||||
118180
|
||||
71745
|
||||
60080
|
||||
56637
|
||||
105491
|
||||
111329
|
||||
71799
|
||||
59962
|
||||
60597
|
||||
75241
|
||||
102506
|
||||
75341
|
||||
129539
|
||||
71011
|
||||
127185
|
||||
51245
|
||||
144401
|
||||
78592
|
||||
116835
|
||||
52029
|
||||
134905
|
||||
80104
|
||||
146304
|
||||
113780
|
||||
108124
|
||||
131268
|
||||
124765
|
||||
78847
|
||||
76897
|
||||
56445
|
||||
116487
|
||||
62068
|
||||
125176
|
||||
122259
|
||||
134261
|
||||
101127
|
||||
127089
|
||||
55793
|
||||
113113
|
||||
132835
|
||||
118901
|
||||
59574
|
||||
113399
|
||||
73232
|
||||
93720
|
||||
144450
|
||||
129604
|
||||
101741
|
||||
108759
|
||||
55891
|
||||
52939
|
||||
"""
|
||||
|
||||
func fuel(mass: Int) -> Int {
|
||||
let requiredFuel = mass / 3 - 2
|
||||
guard requiredFuel > 0 else {
|
||||
return 0
|
||||
}
|
||||
|
||||
return requiredFuel + fuel(mass: requiredFuel)
|
||||
}
|
||||
|
||||
input.split(separator: "\n")
|
||||
.compactMap { Int($0) }
|
||||
.map { fuel(mass: $0) }
|
||||
.reduce(0, { a, b -> Int in a + b })
|
||||
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
//: [Previous](@previous)
|
||||
|
||||
import Foundation
|
||||
|
||||
var str = "Hello, playground"
|
||||
|
||||
//: [Next](@next)
|
|
@ -0,0 +1,80 @@
|
|||
let program = [3,8,1005,8,339,1106,0,11,0,0,0,104,1,104,0,3,8,1002,8,-1,10,101,1,10,10,4,10,1008,8,0,10,4,10,1002,8,1,29,2,1108,11,10,1,1,20,10,2,107,6,10,3,8,102,-1,8,10,101,1,10,10,4,10,108,0,8,10,4,10,101,0,8,62,1006,0,29,1006,0,12,1,1101,5,10,1,2,20,10,3,8,102,-1,8,10,1001,10,1,10,4,10,1008,8,0,10,4,10,1001,8,0,99,1006,0,30,3,8,1002,8,-1,10,1001,10,1,10,4,10,1008,8,0,10,4,10,1001,8,0,124,1006,0,60,3,8,1002,8,-1,10,1001,10,1,10,4,10,1008,8,1,10,4,10,101,0,8,149,2,1007,2,10,1,1105,10,10,3,8,1002,8,-1,10,101,1,10,10,4,10,108,0,8,10,4,10,101,0,8,178,1,1108,15,10,1,1101,5,10,1,109,8,10,1006,0,20,3,8,102,-1,8,10,1001,10,1,10,4,10,108,1,8,10,4,10,101,0,8,215,1006,0,61,1006,0,16,2,1105,15,10,1006,0,50,3,8,1002,8,-1,10,1001,10,1,10,4,10,108,1,8,10,4,10,101,0,8,250,1,1003,10,10,1,9,19,10,2,1004,6,10,2,1106,2,10,3,8,1002,8,-1,10,1001,10,1,10,4,10,1008,8,1,10,4,10,101,0,8,289,1,1103,13,10,2,105,17,10,3,8,1002,8,-1,10,1001,10,1,10,4,10,108,1,8,10,4,10,1002,8,1,318,101,1,9,9,1007,9,1086,10,1005,10,15,99,109,661,104,0,104,1,21101,0,825599304340,1,21101,356,0,0,1106,0,460,21101,0,937108545948,1,21102,1,367,0,1106,0,460,3,10,104,0,104,1,3,10,104,0,104,0,3,10,104,0,104,1,3,10,104,0,104,1,3,10,104,0,104,0,3,10,104,0,104,1,21102,1,21628980315,1,21101,0,414,0,1105,1,460,21101,0,3316673539,1,21101,425,0,0,1106,0,460,3,10,104,0,104,0,3,10,104,0,104,0,21102,988753428840,1,1,21102,1,448,0,1106,0,460,21102,825544569700,1,1,21102,459,1,0,1106,0,460,99,109,2,21202,-1,1,1,21102,1,40,2,21102,491,1,3,21102,481,1,0,1105,1,524,109,-2,2106,0,0,0,1,0,0,1,109,2,3,10,204,-1,1001,486,487,502,4,0,1001,486,1,486,108,4,486,10,1006,10,518,1101,0,0,486,109,-2,2105,1,0,0,109,4,2102,1,-1,523,1207,-3,0,10,1006,10,541,21102,0,1,-3,21201,-3,0,1,22102,1,-2,2,21102,1,1,3,21102,560,1,0,1106,0,565,109,-4,2105,1,0,109,5,1207,-3,1,10,1006,10,588,2207,-4,-2,10,1006,10,588,22101,0,-4,-4,1105,1,656,21202,-4,1,1,21201,-3,-1,2,21202,-2,2,3,21102,1,607,0,1106,0,565,22102,1,1,-4,21101,0,1,-1,2207,-4,-2,10,1006,10,626,21101,0,0,-1,22202,-2,-1,-2,2107,0,-3,10,1006,10,648,21202,-1,1,1,21101,0,648,0,105,1,523,21202,-2,-1,-2,22201,-4,-2,-4,109,-5,2105,1,0]
|
||||
|
||||
class Robot: IO {
|
||||
static let size = 1000
|
||||
static let colorMask = 1 << 0
|
||||
static let paintedMask = 1 << 1
|
||||
|
||||
var position = (x:Robot.size / 2, y: Robot.size / 2)
|
||||
var direction = 0
|
||||
|
||||
var colors = Array(repeating: 0, count: Robot.size * Robot.size)
|
||||
var paintedCells = 0
|
||||
var nextIsPaint = true
|
||||
|
||||
var minX = Robot.size
|
||||
var maxX = 0
|
||||
var minY = Robot.size
|
||||
var maxY = 0
|
||||
|
||||
func move(turn: Int) {
|
||||
direction = (4 + direction + (turn == 0 ? -1 : 1)) % 4
|
||||
switch direction {
|
||||
case 0: position.y -= 1
|
||||
case 1: position.x += 1
|
||||
case 2: position.y += 1
|
||||
case 3: position.x -= 1
|
||||
default: fatalError()
|
||||
}
|
||||
}
|
||||
|
||||
func input() -> Int {
|
||||
return colors[position] & Robot.colorMask
|
||||
}
|
||||
|
||||
func output(_ value: Int) {
|
||||
precondition(value == 0 || value == 1)
|
||||
if nextIsPaint {
|
||||
if colors[position] & Robot.paintedMask == 0 {
|
||||
paintedCells += 1
|
||||
}
|
||||
colors[position] = value | Robot.paintedMask
|
||||
|
||||
minX = min(position.x, minX)
|
||||
maxX = max(position.x, maxX)
|
||||
minY = min(position.y, minY)
|
||||
maxY = max(position.y, maxY)
|
||||
} else {
|
||||
move(turn: value)
|
||||
}
|
||||
nextIsPaint.toggle()
|
||||
}
|
||||
}
|
||||
|
||||
extension Array {
|
||||
subscript(pos: (Int, Int)) -> Element {
|
||||
get {
|
||||
let (x, y) = pos
|
||||
precondition(0..<Robot.size ~= x)
|
||||
precondition(0..<Robot.size ~= y)
|
||||
return self[x + y * Robot.size]
|
||||
}
|
||||
set(newValue) {
|
||||
let (x, y) = pos
|
||||
precondition(0..<Robot.size ~= x)
|
||||
precondition(0..<Robot.size ~= y)
|
||||
self[x + y * Robot.size] = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let robot = Robot()
|
||||
robot.colors[robot.position] = 1
|
||||
|
||||
IntCode(program: program, io: robot).run()
|
||||
print(robot.paintedCells)
|
||||
|
||||
for y in robot.minY ... robot.maxY {
|
||||
let lineStart = y * Robot.size
|
||||
print(String(robot.colors[lineStart + robot.minX ... lineStart + robot.maxX].map { $0 & Robot.colorMask == 0 ? " " : "*" }))
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
struct Moon: Hashable {
|
||||
var x: Int
|
||||
var y: Int
|
||||
var z: Int
|
||||
|
||||
var vx = 0
|
||||
var vy = 0
|
||||
var vz = 0
|
||||
|
||||
init(x: Int, y: Int, z: Int) {
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.z = z
|
||||
}
|
||||
|
||||
mutating func move() {
|
||||
x += vx
|
||||
y += vy
|
||||
z += vz
|
||||
}
|
||||
|
||||
mutating func applyGravity(from other: Moon) {
|
||||
vx += grav(x, other.x)
|
||||
vy += grav(y, other.y)
|
||||
vz += grav(z, other.z)
|
||||
}
|
||||
|
||||
var energy: Int {
|
||||
let pot = abs(x) + abs(y) + abs(z)
|
||||
let kin = abs(vx) + abs(vy) + abs(vz)
|
||||
return pot * kin
|
||||
}
|
||||
}
|
||||
|
||||
func grav(_ a: Int, _ b: Int) -> Int
|
||||
{
|
||||
if a < b {
|
||||
return 1
|
||||
} else if a == b {
|
||||
return 0
|
||||
} else {
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var moons = [
|
||||
Moon(x: -13, y: 14, z: -7),
|
||||
Moon(x: -18, y: 9, z: 0),
|
||||
Moon(x: 0, y: -3, z: -3),
|
||||
Moon(x: -15, y: 3, z: -13)
|
||||
]
|
||||
|
||||
@discardableResult
|
||||
func step() -> Int {
|
||||
for a in 0..<moons.count {
|
||||
for b in 0..<moons.count where a != b {
|
||||
moons[a].applyGravity(from: moons[b])
|
||||
}
|
||||
}
|
||||
|
||||
var energy = 0
|
||||
for i in 0..<moons.count {
|
||||
moons[i].move()
|
||||
energy += moons[i].energy
|
||||
}
|
||||
return energy
|
||||
}
|
||||
|
||||
var seen: Set<[Moon]> = []
|
||||
|
||||
var steps = 0
|
||||
|
||||
repeat {
|
||||
seen.insert(moons)
|
||||
step()
|
||||
steps += 1
|
||||
} while !seen.contains(moons)
|
||||
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,64 @@
|
|||
import Foundation
|
||||
|
||||
let input = """
|
||||
9 ORE => 2 A
|
||||
8 ORE => 3 B
|
||||
7 ORE => 5 C
|
||||
3 A, 4 B => 1 AB
|
||||
5 B, 7 C => 1 BC
|
||||
4 C, 1 A => 1 CA
|
||||
2 AB, 3 BC, 4 CA => 1 FUEL
|
||||
"""
|
||||
|
||||
|
||||
struct Chemical {
|
||||
let name: String
|
||||
let amount: Int
|
||||
}
|
||||
|
||||
struct Reaction {
|
||||
let product: Chemical
|
||||
let educts: [Chemical]
|
||||
}
|
||||
|
||||
var reactions: [String: Reaction] = [:]
|
||||
|
||||
let scanner = Scanner(string: input)
|
||||
|
||||
func parseChemical() -> Chemical? {
|
||||
guard let amount = scanner.scanInt(),
|
||||
let name = scanner.scanCharacters(from: .letters) else {
|
||||
return nil
|
||||
}
|
||||
return Chemical(name: name, amount: amount)
|
||||
}
|
||||
|
||||
func parseReaction() -> Reaction? {
|
||||
var educts: [Chemical] = []
|
||||
repeat {
|
||||
guard let chemical = parseChemical() else {
|
||||
return nil
|
||||
}
|
||||
educts.append(chemical)
|
||||
} while scanner.scanString(",") != nil
|
||||
guard scanner.scanString("=>") != nil else {
|
||||
return nil
|
||||
}
|
||||
guard let product = parseChemical() else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return Reaction(product: product, educts: educts)
|
||||
}
|
||||
|
||||
while !scanner.isAtEnd {
|
||||
guard let reaction = parseReaction() else {
|
||||
fatalError()
|
||||
}
|
||||
|
||||
reactions[reaction.product.name] = reaction
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
|
||||
func pattern(position: Int) -> DropFirstSequence<AnySequence<Int>>
|
||||
{
|
||||
precondition(position >= 0)
|
||||
let repeats = position + 1
|
||||
|
||||
let base = [0, 1, 0, -1]
|
||||
return repeating(base.flatMap { Array(repeating: $0, count: repeats) }).dropFirst()
|
||||
}
|
||||
|
||||
func repeating<T: Sequence>(_ sequence: T) -> AnySequence<T.Element>
|
||||
{
|
||||
return AnySequence { () -> AnyIterator<T.Element> in
|
||||
var it = sequence.makeIterator()
|
||||
return AnyIterator { () -> T.Element? in
|
||||
if let value = it.next() {
|
||||
return value
|
||||
}
|
||||
|
||||
it = sequence.makeIterator()
|
||||
return it.next()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func phase(_ input: [Int]) -> [Int] {
|
||||
var result: [Int] = []
|
||||
return input.indices.map { i in
|
||||
abs(zip(input, pattern(position: i)).reduce(0) { (accum: Int, value: (Int, Int)) -> Int in accum + value.0 * value.1 }) % 10
|
||||
}
|
||||
}
|
||||
|
||||
let input = "59773419794631560412886746550049210714854107066028081032096591759575145680294995770741204955183395640103527371801225795364363411455113236683168088750631442993123053909358252440339859092431844641600092736006758954422097244486920945182483159023820538645717611051770509314159895220529097322723261391627686997403783043710213655074108451646685558064317469095295303320622883691266307865809481566214524686422834824930414730886697237161697731339757655485312568793531202988525963494119232351266908405705634244498096660057021101738706453735025060225814133166491989584616948876879383198021336484629381888934600383957019607807995278899293254143523702000576897358"
|
||||
|
||||
var data: [Int] = input.map { $0.wholeNumberValue! }
|
||||
|
||||
func readAt(_ index: Int) -> Int {
|
||||
data[index ..< index + 8].reduce(0) { 10 * $0 + $1 }
|
||||
}
|
||||
|
||||
readAt(readAt(0))
|
||||
|
||||
|
||||
//for i in 0..<100 {
|
||||
// data = phase(data)
|
||||
//}
|
||||
//
|
||||
//print(data[0..<8])
|
||||
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
let program = [1,0,0,3,1,1,2,3,1,3,4,3,1,5,0,3,2,10,1,19,1,5,19,23,1,23,5,27,1,27,13,31,1,31,5,35,1,9,35,39,2,13,39,43,1,43,10,47,1,47,13,51,2,10,51,55,1,55,5,59,1,59,5,63,1,63,13,67,1,13,67,71,1,71,10,75,1,6,75,79,1,6,79,83,2,10,83,87,1,87,5,91,1,5,91,95,2,95,10,99,1,9,99,103,1,103,13,107,2,10,107,111,2,13,111,115,1,6,115,119,1,119,10,123,2,9,123,127,2,127,9,131,1,131,10,135,1,135,2,139,1,10,139,0,99,2,0,14,0]
|
||||
|
||||
|
||||
|
||||
func run(a: Int, b: Int) -> Int {
|
||||
var memory = program
|
||||
|
||||
memory[1] = a
|
||||
memory[2] = b
|
||||
|
||||
var pc = 0
|
||||
|
||||
loop: while(true) {
|
||||
switch memory[pc] {
|
||||
case 1:
|
||||
memory[memory[pc + 3]] = memory[memory[pc + 1]] + memory[memory[pc + 2]]
|
||||
|
||||
case 2:
|
||||
memory[memory[pc + 3]] = memory[memory[pc + 1]] * memory[memory[pc + 2]]
|
||||
|
||||
case 99:
|
||||
break loop
|
||||
|
||||
default:
|
||||
fatalError()
|
||||
|
||||
}
|
||||
pc += 4
|
||||
}
|
||||
|
||||
return memory[0]
|
||||
}
|
||||
|
||||
for a in 0...99 {
|
||||
for b in 0...99 {
|
||||
if run(a: a, b: b) == 19690720 {
|
||||
print (100 * a + b)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
143
2019/AoC.playground/Pages/Day 3.xcplaygroundpage/Contents.swift
Normal file
143
2019/AoC.playground/Pages/Day 3.xcplaygroundpage/Contents.swift
Normal file
|
@ -0,0 +1,143 @@
|
|||
import Foundation
|
||||
|
||||
//let in1 = "R1002,D715,R356,D749,L255,U433,L558,D840,R933,U14,L285,U220,L88,D477,R36,U798,R373,U378,R305,D341,R959,D604,R717,D911,L224,D32,R481,D508,L203,U445,L856,U44,L518,U909,R580,U565,R484,D170,R356,U614,R278,U120,R540,D330,R124,D555,R890,U445,L876,D948,R956,D503,R391,U564,R624,D642,L821,U924,L921,U869,R104,U376,L693,U812,R758,U200,L515,U435,R505,U22,R707,U926,R261,D332,R535,D704,L561,U476,R225,U168,L784,D794,R311,D426,R813,U584,L831,D258,R241,D665,R550,D709,R261,U557,L670,D823,L297,U951,R634,D647,R699,U907,L219,U481,L583,D854,L898,U535,R648,U307,L870,D748,R768,D502,L15,U684,R476,D591,L531,D881,L466,U135,R445,U813,R950,D303,L590,U938,R630,D233,R567,U739,L446,U689,R585,D892,R741,U849,R629,D972,L625,D524,L715,D936,L328,U102,R864,U859,L827,U162,L886,D785,R359,D38,R51,U999,R560,U415,L840,U736,R552,D277,R722,D444,R164,U335,L129,D873,L499,U847,R84,U780,R104,U879,R938,D468,L575,D668,L143,U917,R86,D562,R595,U924,R807,U76,L44,D685,R936,U876,R570,U782,L139,D815,R89,D976,R84,U446,R238,U853,L603,U869,R312,U970,R387,U131,L647,D383,R161,D818,L765,U291,L423,D753,R277,U840,R23,U265,R298,U665,R522,D955,R26,D320,R347,U952,R743,U782,L780,D20,L393,U855,L279,D969,L923,D902,L818,U855,L927,D342,R769,U517,L485,U176,R14,U683,L632,U198,R656,U444,R41,D911,R99,U880,L363,D15,L894,D782,R612,D677,R469,D166,R61,U284,R474,U222,L687,D502,R690,U619,R536,D663,L54,D660,L804,D697,R67,U116,R842,D785,R277,U978,L920,D926,R681,D957,L582,U441,L593,U686,R829,U937,L924,U965,R727,D964,R468,U240,R934,D266,R416"
|
||||
//let in2 = "L998,U258,R975,U197,R680,D56,R898,D710,R475,U909,L201,D579,L21,U743,R832,D448,R216,D136,R83,U413,R167,U138,R102,U122,L290,D49,L93,D941,L625,U709,R129,D340,L322,D27,R440,U692,R368,D687,L246,D425,R823,U287,L436,U999,R90,U663,R470,U177,R956,D981,L767,D780,R610,D644,R238,D416,R402,D327,L680,D367,L94,D776,L331,D745,R846,D559,R113,U158,R125,D627,L898,D212,L80,D184,L386,U943,R122,D614,L868,D600,R912,U501,R25,D887,R310,U872,L157,U865,L382,U959,R712,D248,L343,U819,L763,U886,R582,D631,L835,U443,L917,D934,L333,U470,R778,U142,R384,U589,R306,U933,L206,D199,L497,D406,L212,U439,L15,U985,R505,D502,R934,D966,R429,U810,R588,U367,L424,U804,R767,U703,R885,U568,R748,U209,L319,U305,L941,D184,R398,U681,L411,U414,L90,U711,L575,D368,L986,U29,R982,U361,L501,D970,R558,D887,L241,U506,R578,D932,R911,U621,L153,U200,L873,U711,L843,U549,R72,U377,R915,D79,L378,U66,L989,D589,L341,D350,L200,D78,R944,U876,L794,U643,R871,D909,L353,D54,R651,U338,R857,D938,R636,D301,R728,U318,R530,D589,L682,U784,L428,D879,L207,D247,L53,U312,L488,D534,L998,U512,L628,D957,L994,D747,L804,U399,L801,D500,R791,D980,R839,U564,L81,U461,R615,U863,R308,D564,R843,U579,R792,D472,R229,D153,L21,D647,R425,D54,L470,U330,R285,D81,L221,U168,R970,D624,R815,U189,L812,U195,L654,U108,R820,U786,L932,U657,L605,D164,L788,D393,L717,D49,R615,D81,L91,U322,L150,D368,R434,D861,L859,D911,R161,U576,L671,U992,L745,U585,R440,D731,R740,U584,L867,D906,R176,U72,L323,U329,L445,D667,R626,D111,L895,D170,R957,D488,R214,D354,L215,U486,L665,D266,L987"
|
||||
|
||||
let in1 = "R8,U5,L5,D3"
|
||||
let in2 = "U7,R6,D4,L4"
|
||||
struct LineSegment: Equatable {
|
||||
let first: Bool
|
||||
let startLength: Int
|
||||
let x0: Int
|
||||
let y0: Int
|
||||
let symbol: String
|
||||
}
|
||||
|
||||
enum Entry: Equatable {
|
||||
case start(x: Int, y: Int, LineSegment)
|
||||
case end(x: Int, y: Int, LineSegment)
|
||||
case vertical(x: Int, y0: Int, y1: Int, LineSegment)
|
||||
|
||||
var x: Int {
|
||||
switch self {
|
||||
case .start(let x, _, _): return x
|
||||
case .end(let x, _, _): return x
|
||||
case .vertical(let x, _, _, _): return x
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Entry: Comparable {
|
||||
static func < (lhs: Entry, rhs: Entry) -> Bool {
|
||||
return lhs.x < rhs.x
|
||||
}
|
||||
}
|
||||
|
||||
var segments = Heap<Entry>()
|
||||
|
||||
|
||||
|
||||
func parse(_ s: String, first: Bool) {
|
||||
var x = 0
|
||||
var y = 0
|
||||
let s = Scanner(string: s)
|
||||
var len = 0
|
||||
|
||||
loop: repeat {
|
||||
guard let dir = s.scanCharacter(),
|
||||
let amount = s.scanInt() else {
|
||||
break
|
||||
}
|
||||
|
||||
let symbol = "\(dir)\(amount)"
|
||||
|
||||
switch dir {
|
||||
case "R":
|
||||
let seg = LineSegment(first: first, startLength: len, x0: x, y0: y, symbol: symbol)
|
||||
segments.insert(item: .start(x: x, y: y, seg))
|
||||
x += amount
|
||||
segments.insert(item: .end(x: x, y: y, seg))
|
||||
|
||||
case "L":
|
||||
let seg = LineSegment(first: first, startLength: len, x0: x - amount, y0: y, symbol: symbol)
|
||||
segments.insert(item: .end(x: x, y: y, seg))
|
||||
x -= amount
|
||||
segments.insert(item: .start(x: x, y: y, seg))
|
||||
|
||||
case "U":
|
||||
let seg = LineSegment(first: first, startLength: len, x0: x, y0: y - amount,symbol: symbol)
|
||||
segments.insert(item: .vertical(x: x, y0: y - amount, y1: y, seg))
|
||||
y -= amount
|
||||
|
||||
case "D":
|
||||
let seg = LineSegment(first: first, startLength: len, x0: x, y0: y, symbol: symbol)
|
||||
segments.insert(item: .vertical(x: x, y0: y, y1: y + amount, seg))
|
||||
y += amount
|
||||
|
||||
default:
|
||||
break loop
|
||||
}
|
||||
|
||||
len += amount
|
||||
} while s.scanString(",") != nil
|
||||
}
|
||||
|
||||
parse(in1, first: true)
|
||||
parse(in2, first: false)
|
||||
|
||||
var intersections: [(Int, Int, Int)] = []
|
||||
|
||||
struct Line: Equatable {
|
||||
var y: Int
|
||||
let segment: LineSegment
|
||||
}
|
||||
|
||||
struct Tree {
|
||||
var items: [Line] = []
|
||||
|
||||
mutating func add(_ value: Line) {
|
||||
items.append(value)
|
||||
}
|
||||
|
||||
mutating func remove(_ value: Line) {
|
||||
items.removeAll(where: { $0 == value })
|
||||
}
|
||||
|
||||
func range(from: Int, to: Int) -> [Line] {
|
||||
return items.filter({ from <= $0.y && $0.y <= to })
|
||||
}
|
||||
}
|
||||
|
||||
var openLines = Tree()
|
||||
|
||||
var segs = segments
|
||||
while let s = segs.extractMin() {
|
||||
print(s)
|
||||
}
|
||||
|
||||
while let min = segments.extractMin() {
|
||||
switch min {
|
||||
case .start(_, let y, let s):
|
||||
openLines.add(Line(y: y, segment: s))
|
||||
|
||||
case .end(_, let y, let s):
|
||||
openLines.remove(Line(y: y, segment: s))
|
||||
|
||||
case .vertical(let x, let y0, let y1, let f):
|
||||
print("vertical \(x),\(y0) - \(x),\(y1):")
|
||||
for l in openLines.range(from: y0, to: y1) where l.segment.first != f.first {
|
||||
let horizontalDistance = l.segment.startLength + x - l.segment.x0
|
||||
let verticalDistance = f.startLength + l.y - f.y0
|
||||
print(f, " - ", l.segment, ":", x, l.y, "-", horizontalDistance, verticalDistance, horizontalDistance + verticalDistance)
|
||||
intersections.append((x, l.y, horizontalDistance + verticalDistance))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
intersections
|
||||
.map { $0.2 }
|
||||
.min()
|
||||
|
||||
intersections
|
||||
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
//
|
||||
// Heap.swift
|
||||
// SwiftHeap
|
||||
//
|
||||
// Created by Sven Weidauer on 30.12.14.
|
||||
// Copyright (c) 2014 Sven Weidauer. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// A heap
|
||||
public struct Heap<T : Comparable> : ExpressibleByArrayLiteral, Equatable {
|
||||
public typealias ArrayLiteralElement = T
|
||||
typealias Element = T
|
||||
|
||||
/// Initializes the heap with multiple items
|
||||
public init(arrayLiteral items : T... ) {
|
||||
self.init( items )
|
||||
}
|
||||
|
||||
public init(_ items: T...) {
|
||||
self.init(items)
|
||||
}
|
||||
|
||||
/// Initializes the heap from an array of items
|
||||
public init( _ items : [T] ) {
|
||||
self.items = items
|
||||
for index in (0 ..< size/2).reversed() {
|
||||
heapify( index )
|
||||
}
|
||||
}
|
||||
|
||||
/// The minimum item on this heap or nil if the heap is empty
|
||||
public var min : T? {
|
||||
return items.first
|
||||
}
|
||||
|
||||
/// The number of items on this heap
|
||||
public var size : Int {
|
||||
return items.count
|
||||
}
|
||||
|
||||
/// true if this heap is empty
|
||||
public var empty : Bool {
|
||||
return size > 0
|
||||
}
|
||||
|
||||
/**
|
||||
Removes and returns the minimum item from the heap.
|
||||
|
||||
:returns: The minimum item from the heap or nil if the heap is empty.
|
||||
*/
|
||||
public mutating func extractMin() -> T? {
|
||||
|
||||
|
||||
if let result = items.first {
|
||||
items[0] = items[items.count - 1]
|
||||
items.removeLast()
|
||||
heapify(0)
|
||||
return result
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
/// Inserts a new item into this heap
|
||||
///
|
||||
/// :param: item The new item to insert
|
||||
public mutating func insert( item : T ) {
|
||||
items.append( item )
|
||||
var i = items.count - 1
|
||||
while i > 0 && items[i] < items[parent( i )] {
|
||||
items.swapAt(i, parent(i))
|
||||
i = parent( i )
|
||||
}
|
||||
}
|
||||
|
||||
/// Restores the heap property starting at a given index
|
||||
///
|
||||
/// :param: index The index to start at
|
||||
private mutating func heapify(_ index : Int ) {
|
||||
var minimumIndex = index
|
||||
if left( index ) < size && items[left( index )] < items[minimumIndex] {
|
||||
minimumIndex = left( index )
|
||||
}
|
||||
|
||||
if right( index ) < size && items[right( index )] < items[minimumIndex] {
|
||||
minimumIndex = right( index )
|
||||
}
|
||||
|
||||
if minimumIndex != index {
|
||||
items.swapAt(minimumIndex, index)
|
||||
heapify( minimumIndex )
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the index of the left child of an item
|
||||
private func left(_ index : Int ) -> Int {
|
||||
return 2 * index + 1
|
||||
}
|
||||
|
||||
/// Returns the index of the right child of an item
|
||||
private func right(_ index: Int ) -> Int {
|
||||
return 2 * index + 2
|
||||
}
|
||||
|
||||
/// Returns the index of the parent of an item
|
||||
private func parent(_ index: Int ) -> Int {
|
||||
return (index - 1) / 2
|
||||
}
|
||||
|
||||
/// Storage for the items in thie heap
|
||||
private var items : [T]
|
||||
|
||||
/// Compares two heaps for equality
|
||||
public static func ==( lhs: Heap, rhs: Heap ) -> Bool {
|
||||
return lhs.items == rhs.items
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Timeline
|
||||
version = "3.0">
|
||||
<TimelineItems>
|
||||
<LoggerValueHistoryTimelineItem
|
||||
documentLocation = "file:///Volumes/Daten/Projekte/AoC.playground/Pages/Untitled%20Page%203.xcplaygroundpage#CharacterRangeLen=13&CharacterRangeLoc=6510&EndingColumnNumber=0&EndingLineNumber=141&StartingColumnNumber=1&StartingLineNumber=140&Timestamp=597611208.2789299"
|
||||
selectedRepresentationIndex = "0"
|
||||
shouldTrackSuperviewWidth = "NO">
|
||||
</LoggerValueHistoryTimelineItem>
|
||||
</TimelineItems>
|
||||
</Timeline>
|
|
@ -0,0 +1,23 @@
|
|||
let min = 172930
|
||||
let max = 683082
|
||||
|
||||
var count = 0
|
||||
outer: for i in min...max {
|
||||
let s = String(i).compactMap { $0.wholeNumberValue }
|
||||
|
||||
var hasDouble = false
|
||||
|
||||
for (first, second) in zip(s, s.dropFirst()) {
|
||||
if second < first {
|
||||
continue outer
|
||||
}
|
||||
|
||||
if first == second {
|
||||
hasDouble = true
|
||||
}
|
||||
}
|
||||
|
||||
guard hasDouble else { continue }
|
||||
|
||||
count += 1
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
let program = [3,225,1,225,6,6,1100,1,238,225,104,0,1002,36,25,224,1001,224,-2100,224,4,224,1002,223,8,223,101,1,224,224,1,223,224,223,1102,31,84,225,1102,29,77,225,1,176,188,224,101,-42,224,224,4,224,102,8,223,223,101,3,224,224,1,223,224,223,2,196,183,224,1001,224,-990,224,4,224,1002,223,8,223,101,7,224,224,1,224,223,223,102,14,40,224,101,-1078,224,224,4,224,1002,223,8,223,1001,224,2,224,1,224,223,223,1001,180,64,224,101,-128,224,224,4,224,102,8,223,223,101,3,224,224,1,223,224,223,1102,24,17,224,1001,224,-408,224,4,224,1002,223,8,223,101,2,224,224,1,223,224,223,1101,9,66,224,1001,224,-75,224,4,224,1002,223,8,223,1001,224,6,224,1,223,224,223,1102,18,33,225,1101,57,64,225,1102,45,11,225,1101,45,9,225,1101,11,34,225,1102,59,22,225,101,89,191,224,1001,224,-100,224,4,224,1002,223,8,223,1001,224,1,224,1,223,224,223,4,223,99,0,0,0,677,0,0,0,0,0,0,0,0,0,0,0,1105,0,99999,1105,227,247,1105,1,99999,1005,227,99999,1005,0,256,1105,1,99999,1106,227,99999,1106,0,265,1105,1,99999,1006,0,99999,1006,227,274,1105,1,99999,1105,1,280,1105,1,99999,1,225,225,225,1101,294,0,0,105,1,0,1105,1,99999,1106,0,300,1105,1,99999,1,225,225,225,1101,314,0,0,106,0,0,1105,1,99999,8,226,677,224,1002,223,2,223,1006,224,329,1001,223,1,223,108,226,226,224,1002,223,2,223,1006,224,344,1001,223,1,223,7,677,226,224,102,2,223,223,1005,224,359,101,1,223,223,7,226,677,224,102,2,223,223,1006,224,374,101,1,223,223,1008,677,226,224,1002,223,2,223,1006,224,389,101,1,223,223,8,677,677,224,1002,223,2,223,1005,224,404,101,1,223,223,8,677,226,224,102,2,223,223,1005,224,419,1001,223,1,223,1107,677,226,224,102,2,223,223,1005,224,434,1001,223,1,223,1107,226,677,224,1002,223,2,223,1006,224,449,1001,223,1,223,107,677,226,224,1002,223,2,223,1005,224,464,1001,223,1,223,1008,677,677,224,1002,223,2,223,1006,224,479,1001,223,1,223,1108,677,226,224,1002,223,2,223,1006,224,494,1001,223,1,223,1108,677,677,224,1002,223,2,223,1006,224,509,1001,223,1,223,107,677,677,224,1002,223,2,223,1005,224,524,101,1,223,223,1007,677,226,224,102,2,223,223,1005,224,539,1001,223,1,223,1107,226,226,224,1002,223,2,223,1006,224,554,1001,223,1,223,1008,226,226,224,1002,223,2,223,1006,224,569,101,1,223,223,1108,226,677,224,1002,223,2,223,1006,224,584,101,1,223,223,108,677,677,224,1002,223,2,223,1006,224,599,1001,223,1,223,1007,677,677,224,102,2,223,223,1006,224,614,101,1,223,223,107,226,226,224,102,2,223,223,1006,224,629,101,1,223,223,1007,226,226,224,102,2,223,223,1005,224,644,1001,223,1,223,108,226,677,224,102,2,223,223,1005,224,659,1001,223,1,223,7,677,677,224,102,2,223,223,1006,224,674,1001,223,1,223,4,223,99,226]
|
||||
|
||||
|
||||
func input() -> Int {
|
||||
return 5
|
||||
}
|
||||
|
||||
func output(_ value: Int) {
|
||||
print("output>",value)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
func run() {
|
||||
var memory = program
|
||||
|
||||
var pc = 0
|
||||
|
||||
func get(_ index: Int) -> Int {
|
||||
let mode = (memory[pc] / pow(2 + index - 1)) % 10
|
||||
|
||||
switch mode {
|
||||
case 0: return memory[memory[pc + index]]
|
||||
case 1: return memory[pc + index]
|
||||
default: preconditionFailure("Unknown mode \(mode)")
|
||||
}
|
||||
}
|
||||
|
||||
func put(_ index: Int, value: Int) {
|
||||
memory[memory[pc + index]] = value
|
||||
}
|
||||
|
||||
loop: while(true) {
|
||||
let opcode = memory[pc] % 100
|
||||
|
||||
print("pc", pc, "op", opcode)
|
||||
|
||||
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: input())
|
||||
pc += 2
|
||||
|
||||
case 4:
|
||||
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 99:
|
||||
break loop
|
||||
|
||||
default:
|
||||
preconditionFailure("Unknown opcode \(opcode)")
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
run()
|
||||
|
1974
2019/AoC.playground/Pages/Day 6.xcplaygroundpage/Contents.swift
Normal file
1974
2019/AoC.playground/Pages/Day 6.xcplaygroundpage/Contents.swift
Normal file
File diff suppressed because it is too large
Load diff
115
2019/AoC.playground/Pages/Day 7.xcplaygroundpage/Contents.swift
Normal file
115
2019/AoC.playground/Pages/Day 7.xcplaygroundpage/Contents.swift
Normal file
|
@ -0,0 +1,115 @@
|
|||
import Foundation
|
||||
|
||||
let program = [3,8,1001,8,10,8,105,1,0,0,21,38,59,84,93,110,191,272,353,434,99999,3,9,101,5,9,9,1002,9,5,9,101,5,9,9,4,9,99,3,9,1001,9,3,9,1002,9,2,9,101,4,9,9,1002,9,4,9,4,9,99,3,9,102,5,9,9,1001,9,4,9,1002,9,2,9,1001,9,5,9,102,4,9,9,4,9,99,3,9,1002,9,2,9,4,9,99,3,9,1002,9,5,9,101,4,9,9,102,2,9,9,4,9,99,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,102,2,9,9,4,9,99,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,99,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,1,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,99,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,99,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,1,9,9,4,9,3,9,1001,9,1,9,4,9,99]
|
||||
|
||||
|
||||
class Io: IO {
|
||||
var inputs = [4, 0, 3, 2, 1, 0]
|
||||
|
||||
func input() -> Int {
|
||||
let input = inputs.remove(at: 0)
|
||||
return input
|
||||
}
|
||||
|
||||
var lastOutput = 0
|
||||
func output(_ value: Int) {
|
||||
lastOutput = value
|
||||
if !inputs.isEmpty {
|
||||
inputs.insert(value, at: 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Buffered: IO {
|
||||
var inputs: [Int] = []
|
||||
let condition = NSCondition()
|
||||
var outputHandler: (Int) -> Void = { _ in }
|
||||
|
||||
|
||||
|
||||
func input() -> Int {
|
||||
condition.lock()
|
||||
defer { condition.unlock() }
|
||||
|
||||
while inputs.isEmpty {
|
||||
condition.wait()
|
||||
}
|
||||
|
||||
return inputs.removeFirst()
|
||||
}
|
||||
|
||||
func add(input: Int) {
|
||||
condition.lock()
|
||||
defer { condition.unlock() }
|
||||
|
||||
inputs.append(input)
|
||||
condition.signal()
|
||||
}
|
||||
|
||||
func output(_ value: Int) {
|
||||
outputHandler(value)
|
||||
}
|
||||
}
|
||||
|
||||
func test(phases: [Int]) -> Int {
|
||||
|
||||
let ios = phases.map { phase -> Buffered in
|
||||
let b = Buffered()
|
||||
b.add(input: phase)
|
||||
return b
|
||||
}
|
||||
|
||||
ios[0].add(input: 0)
|
||||
|
||||
for i in 0 ..< ios.count - 1 {
|
||||
ios[i].outputHandler = { [unowned next = ios[i + 1]] val in
|
||||
next.add(input: val)
|
||||
}
|
||||
}
|
||||
|
||||
var lastOutput = -1
|
||||
|
||||
ios[ios.count - 1].outputHandler = { [unowned first = ios[0]] val in
|
||||
first.add(input: val)
|
||||
lastOutput = val
|
||||
print("out>", val)
|
||||
}
|
||||
|
||||
let group = DispatchGroup()
|
||||
|
||||
for io in ios {
|
||||
DispatchQueue.global().async(group: group) {
|
||||
IntCode(program: program, io: io).run()
|
||||
}
|
||||
}
|
||||
|
||||
group.wait()
|
||||
|
||||
print("done>", lastOutput)
|
||||
print("\n\n")
|
||||
|
||||
return lastOutput
|
||||
}
|
||||
|
||||
var maxOutput = Int.min
|
||||
var maxPhases: [Int] = []
|
||||
|
||||
for a in 0...4 {
|
||||
for b in 0...4 where b != a {
|
||||
for c in 0...4 where c != b && c != a {
|
||||
for d in 0...4 where d != c && d != b && d != a {
|
||||
for e in 0...4 where e != d && e != c && e != c && e != b && e != a {
|
||||
let phases = [5 + a, 5 + b, 5 + c, 5 + d, 5 + e]
|
||||
let output = test(phases: phases)
|
||||
if maxOutput < output {
|
||||
maxOutput = output
|
||||
maxPhases = phases
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
maxOutput
|
||||
maxPhases
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,16 @@
|
|||
let program = [1102,34463338,34463338,63,1007,63,34463338,63,1005,63,53,1102,3,1,1000,109,988,209,12,9,1000,209,6,209,3,203,0,1008,1000,1,63,1005,63,65,1008,1000,2,63,1005,63,904,1008,1000,0,63,1005,63,58,4,25,104,0,99,4,0,104,0,99,4,17,104,0,99,0,0,1101,0,33,1017,1101,24,0,1014,1101,519,0,1028,1102,34,1,1004,1101,0,31,1007,1101,0,844,1025,1102,0,1,1020,1102,38,1,1003,1102,39,1,1008,1102,849,1,1024,1101,0,22,1001,1102,25,1,1009,1101,1,0,1021,1101,0,407,1022,1101,404,0,1023,1101,0,35,1013,1101,27,0,1011,1101,0,37,1016,1102,1,26,1019,1102,28,1,1015,1101,0,30,1000,1102,1,36,1005,1101,0,29,1002,1101,23,0,1012,1102,1,32,1010,1102,21,1,1006,1101,808,0,1027,1102,20,1,1018,1101,0,514,1029,1102,1,815,1026,109,14,2107,24,-5,63,1005,63,199,4,187,1105,1,203,1001,64,1,64,1002,64,2,64,109,-1,2108,21,-7,63,1005,63,225,4,209,1001,64,1,64,1106,0,225,1002,64,2,64,109,-16,1201,6,0,63,1008,63,35,63,1005,63,249,1001,64,1,64,1106,0,251,4,231,1002,64,2,64,109,9,2102,1,2,63,1008,63,37,63,1005,63,271,1105,1,277,4,257,1001,64,1,64,1002,64,2,64,109,11,1208,-8,23,63,1005,63,293,1105,1,299,4,283,1001,64,1,64,1002,64,2,64,109,8,21107,40,39,-8,1005,1017,319,1001,64,1,64,1106,0,321,4,305,1002,64,2,64,109,-28,2101,0,6,63,1008,63,39,63,1005,63,341,1106,0,347,4,327,1001,64,1,64,1002,64,2,64,109,19,2107,26,-7,63,1005,63,363,1106,0,369,4,353,1001,64,1,64,1002,64,2,64,109,1,1202,-9,1,63,1008,63,39,63,1005,63,395,4,375,1001,64,1,64,1105,1,395,1002,64,2,64,109,9,2105,1,-3,1106,0,413,4,401,1001,64,1,64,1002,64,2,64,109,-13,1207,-4,26,63,1005,63,435,4,419,1001,64,1,64,1105,1,435,1002,64,2,64,109,-1,21101,41,0,7,1008,1019,41,63,1005,63,461,4,441,1001,64,1,64,1105,1,461,1002,64,2,64,109,7,21107,42,43,-2,1005,1017,479,4,467,1105,1,483,1001,64,1,64,1002,64,2,64,109,-6,21108,43,46,0,1005,1013,499,1106,0,505,4,489,1001,64,1,64,1002,64,2,64,109,17,2106,0,-2,4,511,1105,1,523,1001,64,1,64,1002,64,2,64,109,-27,1202,-1,1,63,1008,63,28,63,1005,63,547,1001,64,1,64,1106,0,549,4,529,1002,64,2,64,109,18,1206,-1,567,4,555,1001,64,1,64,1106,0,567,1002,64,2,64,109,-16,21102,44,1,6,1008,1011,43,63,1005,63,587,1106,0,593,4,573,1001,64,1,64,1002,64,2,64,109,8,21102,45,1,-1,1008,1012,45,63,1005,63,619,4,599,1001,64,1,64,1105,1,619,1002,64,2,64,109,7,1205,1,633,4,625,1106,0,637,1001,64,1,64,1002,64,2,64,109,-8,2102,1,-3,63,1008,63,25,63,1005,63,659,4,643,1105,1,663,1001,64,1,64,1002,64,2,64,109,14,1206,-5,679,1001,64,1,64,1105,1,681,4,669,1002,64,2,64,109,-28,2101,0,2,63,1008,63,30,63,1005,63,707,4,687,1001,64,1,64,1106,0,707,1002,64,2,64,109,21,21101,46,0,0,1008,1019,48,63,1005,63,727,1106,0,733,4,713,1001,64,1,64,1002,64,2,64,109,-3,21108,47,47,1,1005,1017,751,4,739,1106,0,755,1001,64,1,64,1002,64,2,64,109,-13,1207,0,37,63,1005,63,771,1105,1,777,4,761,1001,64,1,64,1002,64,2,64,109,7,2108,21,-9,63,1005,63,797,1001,64,1,64,1105,1,799,4,783,1002,64,2,64,109,22,2106,0,-5,1001,64,1,64,1106,0,817,4,805,1002,64,2,64,109,-4,1205,-8,829,1106,0,835,4,823,1001,64,1,64,1002,64,2,64,109,-4,2105,1,0,4,841,1105,1,853,1001,64,1,64,1002,64,2,64,109,-30,1208,6,30,63,1005,63,871,4,859,1105,1,875,1001,64,1,64,1002,64,2,64,109,-2,1201,9,0,63,1008,63,22,63,1005,63,897,4,881,1106,0,901,1001,64,1,64,4,64,99,21101,27,0,1,21102,1,915,0,1106,0,922,21201,1,66266,1,204,1,99,109,3,1207,-2,3,63,1005,63,964,21201,-2,-1,1,21102,942,1,0,1105,1,922,22101,0,1,-1,21201,-2,-3,1,21101,0,957,0,1106,0,922,22201,1,-1,-2,1105,1,968,21202,-2,1,-2,109,-3,2106,0,0]
|
||||
|
||||
|
||||
class io: IO {
|
||||
func input() -> Int {
|
||||
return 2
|
||||
}
|
||||
|
||||
func output(_ value: Int) {
|
||||
print("output>", value)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
IntCode(program: program, io: io()).run()
|
||||
|
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
|
||||
}
|
||||
}
|
||||
}
|
BIN
2019/AoC.playground/Tools.o
Normal file
BIN
2019/AoC.playground/Tools.o
Normal file
Binary file not shown.
2
2019/AoC.playground/Tools.remap
Normal file
2
2019/AoC.playground/Tools.remap
Normal file
|
@ -0,0 +1,2 @@
|
|||
[
|
||||
]
|
20
2019/AoC.playground/contents.xcplayground
Normal file
20
2019/AoC.playground/contents.xcplayground
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<playground version='6.0' target-platform='macos'>
|
||||
<pages>
|
||||
<page name='Day 1'/>
|
||||
<page name='Day 2'/>
|
||||
<page name='Day 3'/>
|
||||
<page name='Day 4'/>
|
||||
<page name='Day 5'/>
|
||||
<page name='Day 6'/>
|
||||
<page name='Day 7'/>
|
||||
<page name='Day 8'/>
|
||||
<page name='Day 9'/>
|
||||
<page name='Day 10'/>
|
||||
<page name='Day 11'/>
|
||||
<page name='Day 12'/>
|
||||
<page name='Day 13'/>
|
||||
<page name='Day 14'/>
|
||||
<page name='Day 16'/>
|
||||
</pages>
|
||||
</playground>
|
7
2019/AoC.playground/playground.xcworkspace/contents.xcworkspacedata
generated
Normal file
7
2019/AoC.playground/playground.xcworkspace/contents.xcworkspacedata
generated
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
Loading…
Add table
Reference in a new issue