Add 2019 solutions

This commit is contained in:
Sven Weidauer 2022-11-23 16:46:51 +01:00
parent 43a2ee8414
commit 4d5c8ee8ce
27 changed files with 3198 additions and 0 deletions

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,2 @@
[
]

View 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 })

View file

@ -0,0 +1,7 @@
//: [Previous](@previous)
import Foundation
var str = "Hello, playground"
//: [Next](@next)

View file

@ -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 ? " " : "*" }))
}

View file

@ -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

View file

@ -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
}

View file

@ -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])

View file

@ -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)
}
}
}

View 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

View file

@ -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
}
}

View file

@ -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&amp;CharacterRangeLoc=6510&amp;EndingColumnNumber=0&amp;EndingLineNumber=141&amp;StartingColumnNumber=1&amp;StartingLineNumber=140&amp;Timestamp=597611208.2789299"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
</TimelineItems>
</Timeline>

View file

@ -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
}

View file

@ -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()

File diff suppressed because it is too large Load diff

View 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

View file

@ -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()

View 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)")
}
}
}
}

View 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

Binary file not shown.

View file

@ -0,0 +1,2 @@
[
]

View 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>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View file

@ -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>