Skip to content

Commit 8537924

Browse files
committed
day16 nope
1 parent 9f806c7 commit 8537924

File tree

6 files changed

+396
-1
lines changed

6 files changed

+396
-1
lines changed

Package.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ let dependencies: [Target.Dependency] = [
55
.product(name: "Algorithms", package: "swift-algorithms"),
66
.product(name: "Collections", package: "swift-collections"),
77
.product(name: "ArgumentParser", package: "swift-argument-parser"),
8+
.product(name: "SwiftGraph", package: "SwiftGraph"),
89
]
910

1011
let package = Package(
@@ -14,6 +15,9 @@ let package = Package(
1415
.package(
1516
url: "https://github.com/apple/swift-algorithms.git",
1617
.upToNextMajor(from: "1.2.0")),
18+
.package(
19+
url: "https://github.com/davecom/SwiftGraph.git", branch: "master"
20+
),
1721
.package(
1822
url: "https://github.com/apple/swift-collections.git",
1923
.upToNextMajor(from: "1.0.0")),

Sources/Day15.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ struct Day15: AdventDay {
139139
func part1() -> Int {
140140
var wareHouse = parseMap()
141141
// print(wareHouse.display())
142-
for (idx, instruction) in instructions.enumerated() {
142+
for (_, instruction) in instructions.enumerated() {
143143
// print("step \(idx), \(instruction.rawValue):\n")
144144
wareHouse.execute(instruction: instruction)
145145
// print(wareHouse.display())

Sources/Day16.swift

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import Algorithms
2+
import SwiftGraph
3+
4+
struct Day16: AdventDay {
5+
var maze: Maze
6+
7+
init(data: String) {
8+
maze = Maze(from: data)
9+
}
10+
11+
func part1() -> Int {
12+
let allPaths = maze.findAllPathsToEnd()
13+
return allPaths.min() ?? 0
14+
}
15+
16+
// func part1() -> Int {
17+
// let nodes = maze.getNodes()
18+
// let allEdges = nodes.map { [$0, Edge.inverted(edge: $0)] }.flatMap { $0 }
19+
// let vertices = Array(Set(allEdges.map { [$0.from, $0.to] }.flatMap { $0 }))
20+
// let graph: WeightedGraph<String, Int> = WeightedGraph<String, Int>(vertices: vertices)
21+
// for edge in nodes {
22+
// graph.addEdge(from: edge.from, to: edge.to, weight: edge.weight)
23+
// }
24+
// let (distances, pathDict) = graph.dijkstra(root: "S", startDistance: 0)
25+
// let nameDistance: [String: Int?] = distanceArrayToVertexDict(
26+
// distances: distances, graph: graph)
27+
// // shortest distance from New York to San Francisco
28+
// let temp = nameDistance["E"]
29+
// print(temp)
30+
// return (temp ?? 0) ?? 0
31+
// }
32+
33+
func part2() -> Int {
34+
0
35+
}
36+
}

Sources/Helpers/Maze.swift

Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
struct Edge {
2+
var from: String
3+
var to: String
4+
var weight: Int
5+
}
6+
extension Edge {
7+
init(from: String, to: Int, weight: Int) {
8+
self.from = from
9+
self.to = String(to)
10+
self.weight = weight
11+
}
12+
init(from: Int, to: String, weight: Int) {
13+
self.from = String(from)
14+
self.to = to
15+
self.weight = weight
16+
}
17+
init(from: Int, to: Int, weight: Int) {
18+
self.from = String(from)
19+
self.to = String(to)
20+
self.weight = weight
21+
}
22+
23+
static func inverted(edge: Edge) -> Self {
24+
Edge(from: edge.to, to: edge.from, weight: edge.weight)
25+
}
26+
}
27+
28+
struct Maze {
29+
enum Tile: Character {
30+
case Wall = "#"
31+
case Floor = "."
32+
}
33+
enum Orientation {
34+
case vertical
35+
case horizontal
36+
}
37+
38+
enum TileType {
39+
case DeadEnd // cul de sac
40+
case Pipe(direction: Orientation)
41+
case Corner(quadrant: [Coord])
42+
case TSection
43+
}
44+
45+
// map of the maze allowing access by coordinate
46+
private var positions: [Coord: Tile] = [Coord: Tile]()
47+
private var floor: [Coord: Int] = [Coord: Int]()
48+
private var width: Int
49+
private var height: Int
50+
private var startPosition: Coord = Coord.zero
51+
private var endPosition: Coord = Coord.zero
52+
53+
init(from map: String) {
54+
let lines = map.lines()
55+
height = lines.count
56+
width = lines[0].count
57+
for (y, line) in lines.enumerated() {
58+
for (x, char) in line.enumerated() {
59+
let currentPos = Coord(x: x, y: y)
60+
let id = y * width + x
61+
if char == "S" {
62+
startPosition = currentPos
63+
continue
64+
}
65+
if char == "E" {
66+
endPosition = currentPos
67+
continue
68+
}
69+
let tile = Tile(rawValue: char)
70+
if let tile = tile, tile == .Floor {
71+
// print("floor", id)
72+
floor[currentPos] = id
73+
}
74+
positions[currentPos] = tile
75+
}
76+
}
77+
}
78+
79+
func visitNext(node: String, cost: Int, edges: [Edge]) -> [Int] {
80+
var nCost = cost
81+
82+
for candidate in edges.filter({ $0.from == node }) {
83+
if candidate.to == "E" {
84+
nCost += candidate.weight
85+
86+
}
87+
let costs = visitNext(node: candidate.to, cost: cost, edges: edges)
88+
89+
}
90+
return [Int]()
91+
}
92+
93+
func findAllPathsToEnd() -> [Int] {
94+
var pos = startPosition
95+
var currentNode = "S"
96+
var allPaths = [Coord]()
97+
let edges = self.getNodes()
98+
let allEdges = edges.map { [$0, Edge.inverted(edge: $0)] }.flatMap { $0 }
99+
100+
let costs = visitNext(node: "S", cost: 0, edges: allEdges)
101+
return costs
102+
}
103+
104+
func getNodes() -> [Edge] {
105+
var edges = [Edge]()
106+
var intersects: Set<Int> = Set()
107+
for (coord, tileId) in floor {
108+
// for each tile define if we should add it to our node network
109+
let top = floor[coord + Coord.up]
110+
let left = floor[coord + Coord.left]
111+
let down = floor[coord + Coord.down]
112+
let right = floor[coord + Coord.right]
113+
114+
if let top = top, let left = left, let right = right, let down = down {
115+
// add intersect so we do not create further edges
116+
// print("╬")
117+
intersects.insert(tileId)
118+
edges.append(Edge(from: top, to: right, weight: 1001))
119+
edges.append(Edge(from: top, to: left, weight: 1001))
120+
edges.append(Edge(from: down, to: right, weight: 1001))
121+
edges.append(Edge(from: down, to: left, weight: 1001))
122+
edges.append(Edge(from: right, to: left, weight: 2))
123+
edges.append(Edge(from: top, to: down, weight: 2))
124+
continue
125+
}
126+
if let top = top, let left = left, let down = down {
127+
// print("╣")
128+
intersects.insert(tileId)
129+
edges.append(Edge(from: top, to: left, weight: 1001))
130+
edges.append(Edge(from: down, to: left, weight: 1001))
131+
edges.append(Edge(from: top, to: down, weight: 2))
132+
continue
133+
}
134+
if let top = top, let right = right, let down = down {
135+
// print("╠")
136+
intersects.insert(tileId)
137+
edges.append(Edge(from: top, to: right, weight: 1001))
138+
edges.append(Edge(from: down, to: right, weight: 1001))
139+
edges.append(Edge(from: top, to: down, weight: 2))
140+
continue
141+
}
142+
if let top = top, let left = left, let right = right {
143+
// print("╩")
144+
intersects.insert(tileId)
145+
edges.append(Edge(from: top, to: right, weight: 1001))
146+
edges.append(Edge(from: top, to: left, weight: 1001))
147+
edges.append(Edge(from: left, to: right, weight: 2))
148+
continue
149+
}
150+
if let left = left, let right = right, let down = down {
151+
// print("╦")
152+
intersects.insert(tileId)
153+
edges.append(Edge(from: down, to: right, weight: 1001))
154+
edges.append(Edge(from: down, to: left, weight: 1001))
155+
edges.append(Edge(from: left, to: right, weight: 2))
156+
continue
157+
}
158+
if let top = top, let down = down {
159+
// print("║")
160+
if !intersects.contains(top) {
161+
edges.append(Edge(from: top, to: tileId, weight: 1))
162+
}
163+
if !intersects.contains(down) {
164+
edges.append(Edge(from: down, to: tileId, weight: 1))
165+
}
166+
continue
167+
}
168+
if let left = left, let right = right {
169+
// print("═")
170+
if !intersects.contains(left) {
171+
edges.append(Edge(from: left, to: tileId, weight: 1))
172+
}
173+
if !intersects.contains(right) {
174+
edges.append(Edge(from: right, to: tileId, weight: 1))
175+
}
176+
continue
177+
}
178+
if let top = top, let down = down {
179+
// print("║")
180+
if !intersects.contains(top) {
181+
edges.append(Edge(from: top, to: tileId, weight: 1))
182+
}
183+
if !intersects.contains(down) {
184+
edges.append(Edge(from: down, to: tileId, weight: 1))
185+
}
186+
continue
187+
}
188+
if let top = top, let left = left {
189+
// print("╝")
190+
intersects.insert(tileId)
191+
edges.append(Edge(from: top, to: left, weight: 1001))
192+
continue
193+
}
194+
if let left = left, let down = down {
195+
// print("╗")
196+
intersects.insert(tileId)
197+
edges.append(Edge(from: down, to: left, weight: 1001))
198+
continue
199+
}
200+
if let top = top, let right = right {
201+
// print("╚")
202+
intersects.insert(tileId)
203+
edges.append(Edge(from: top, to: right, weight: 1001))
204+
continue
205+
}
206+
if let right = right, let down = down {
207+
// print("╔")
208+
intersects.insert(tileId)
209+
edges.append(Edge(from: down, to: right, weight: 1001))
210+
continue
211+
}
212+
}
213+
// add Start and end
214+
let top = floor[startPosition + Coord.up]
215+
if let top = top {
216+
edges.append(Edge(from: "S", to: top, weight: 1001))
217+
}
218+
let right = floor[startPosition + Coord.right]
219+
if let right = right {
220+
edges.append(Edge(from: "S", to: right, weight: 1))
221+
}
222+
let down = floor[endPosition + Coord.down]
223+
if let down = down {
224+
edges.append(Edge(from: down, to: "E", weight: 1))
225+
}
226+
let left = floor[endPosition + Coord.left]
227+
if let left = left {
228+
edges.append(Edge(from: left, to: "E", weight: 1))
229+
}
230+
return edges
231+
}
232+
233+
func getTileFor(coord: Coord) -> Character {
234+
let top = positions[coord + Coord.up]
235+
let left = positions[coord + Coord.left]
236+
let down = positions[coord + Coord.down]
237+
let right = positions[coord + Coord.right]
238+
if let current = positions[coord], current == .Floor {
239+
return " "
240+
}
241+
return switch (top, left, right, down) {
242+
case let (top, left, right, down)
243+
where top == .Wall && down == .Wall && left == .Wall && right == .Wall:
244+
""
245+
case let (top, left, _, down) where top == .Wall && down == .Wall && left == .Wall: ""
246+
case let (top, _, right, down) where top == .Wall && down == .Wall && right == .Wall: ""
247+
case let (top, left, right, _) where top == .Wall && left == .Wall && right == .Wall: ""
248+
case let (_, left, right, down) where down == .Wall && left == .Wall && right == .Wall: ""
249+
case let (top, _, _, down) where top == .Wall && down == .Wall: ""
250+
case let (_, left, right, _) where left == .Wall && right == .Wall: ""
251+
case let (top, left, _, _) where left == .Wall && top == .Wall: ""
252+
case let (_, left, _, down) where left == .Wall && down == .Wall: ""
253+
case let (top, _, right, _) where top == .Wall && right == .Wall: ""
254+
case let (_, _, right, down) where down == .Wall && right == .Wall: ""
255+
case let (_, left, right, _) where left == .Wall || right == .Wall: ""
256+
case let (top, _, _, down) where top == .Wall || down == .Wall: ""
257+
default: "o"
258+
}
259+
}
260+
261+
func display() -> String {
262+
var lines = [String]()
263+
for y in 0..<height {
264+
var line = [Character]()
265+
for x in 0..<width {
266+
let currentPos = Coord(x: x, y: y)
267+
if currentPos == startPosition {
268+
line.append("S")
269+
continue
270+
}
271+
if currentPos == endPosition {
272+
line.append("E")
273+
continue
274+
}
275+
let tile = getTileFor(coord: currentPos)
276+
line.append(tile)
277+
}
278+
lines.append(String(line))
279+
}
280+
return lines.joined(separator: "\n")
281+
}
282+
}

0 commit comments

Comments
 (0)