From ac786bc052d95beba0c2d83cbd8f052b50ec75f5 Mon Sep 17 00:00:00 2001 From: Filip Zymek Date: Mon, 12 Dec 2022 21:20:08 +0100 Subject: [PATCH] Day 12 --- AdventOfCode2022.xcodeproj/project.pbxproj | 6 + AdventOfCode2022/Input/day_12.txt | 41 +++++ AdventOfCode2022/Solutions/Day12.swift | 185 +++++++++++++++++++++ AdventOfCode2022/main.swift | 6 +- 4 files changed, 237 insertions(+), 1 deletion(-) create mode 100644 AdventOfCode2022/Input/day_12.txt create mode 100644 AdventOfCode2022/Solutions/Day12.swift diff --git a/AdventOfCode2022.xcodeproj/project.pbxproj b/AdventOfCode2022.xcodeproj/project.pbxproj index 396a61e..426201a 100644 --- a/AdventOfCode2022.xcodeproj/project.pbxproj +++ b/AdventOfCode2022.xcodeproj/project.pbxproj @@ -13,6 +13,7 @@ 464561562939F2E900BB9874 /* Day2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 464561552939F2E900BB9874 /* Day2.swift */; }; 4663CA3029424CD30086DF24 /* Day8.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4663CA2F29424CD30086DF24 /* Day8.swift */; }; 46C166D12947245200A88A2B /* Day11.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46C166D02947245200A88A2B /* Day11.swift */; }; + 46C166D72947A34C00A88A2B /* Day12.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46C166D62947A34C00A88A2B /* Day12.swift */; }; 46CFCF1C29407A610017442D /* Day6.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46CFCF1B29407A610017442D /* Day6.swift */; }; 46CFCF1E294080D80017442D /* Day7.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46CFCF1D294080D80017442D /* Day7.swift */; }; 46D5FD8729439AFB009DE94F /* Day9.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46D5FD8629439AFB009DE94F /* Day9.swift */; }; @@ -47,6 +48,8 @@ 4663CA2F29424CD30086DF24 /* Day8.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Day8.swift; sourceTree = ""; }; 46C166CF2947243A00A88A2B /* day_11.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = day_11.txt; sourceTree = ""; }; 46C166D02947245200A88A2B /* Day11.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Day11.swift; sourceTree = ""; }; + 46C166D62947A34C00A88A2B /* Day12.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Day12.swift; sourceTree = ""; }; + 46C166D82947A35B00A88A2B /* day_12.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = day_12.txt; sourceTree = ""; }; 46CFCF1A29407A520017442D /* day_6.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = day_6.txt; sourceTree = ""; }; 46CFCF1B29407A610017442D /* Day6.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Day6.swift; sourceTree = ""; }; 46CFCF1D294080D80017442D /* Day7.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Day7.swift; sourceTree = ""; }; @@ -114,6 +117,7 @@ 46D5FD8829439B0F009DE94F /* day_9.txt */, 46D5FD8B2944AB7F009DE94F /* day_10.txt */, 46C166CF2947243A00A88A2B /* day_11.txt */, + 46C166D82947A35B00A88A2B /* day_12.txt */, ); path = Input; sourceTree = ""; @@ -132,6 +136,7 @@ 46D5FD8629439AFB009DE94F /* Day9.swift */, 46D5FD892944AB6F009DE94F /* Day10.swift */, 46C166D02947245200A88A2B /* Day11.swift */, + 46C166D62947A34C00A88A2B /* Day12.swift */, ); path = Solutions; sourceTree = ""; @@ -208,6 +213,7 @@ 46D5FD8729439AFB009DE94F /* Day9.swift in Sources */, 464561562939F2E900BB9874 /* Day2.swift in Sources */, 464561542939F19A00BB9874 /* InputLoader.swift in Sources */, + 46C166D72947A34C00A88A2B /* Day12.swift in Sources */, 46CFCF1E294080D80017442D /* Day7.swift in Sources */, 463CADAD2938C2330045460C /* main.swift in Sources */, ); diff --git a/AdventOfCode2022/Input/day_12.txt b/AdventOfCode2022/Input/day_12.txt new file mode 100644 index 0000000..0ae755d --- /dev/null +++ b/AdventOfCode2022/Input/day_12.txt @@ -0,0 +1,41 @@ +abccccaaacaccccaaaaacccccccaaccccccccaaaaaaccccccaaaaaccccccccccaaaaaaaaacccccccaaaaaaaaaaaaaaccaaaaaccccccccccccaccacccccccccccccccccccccccccccccccccccccccaaaaaa +abccaacaaaaaccaaaaacccccaaaaaccccccccaaaaaaccccccaaaaaacccccccccaaaaaaaaaaaaacccaaaaaaaaaaaaaaaaaaaaaccccccccccccaaaacccccccccccccccccccccccccccccccccccccccaaaaaa +abccaaaaaaaaccaaaaaacccccaaaaaccccccaaaaaaaacccccaaaaaaccccccccccaaaaaaaaaaaacccaaaaaacaaaaaacaaaaaaaaccccccccccaaaaacccccaccccccccccccccccccaaacccccccccccccaaaaa +abcccaaaaaccccccaaaacccccaaaaacccccaaaaaaaaaaccccaaaaaacccccccccaaaaaaaaaaaaaacaaaaaaaaaaaaaacaaaaaaaaccccccccccaaaaaacccaaacccccccccccccccccaaaccccccccccccccaaaa +abaaacaaaaacccccacccccccaaaaaccccccaaaaaaaaaaccccccaaaccccccccccaaaaaaaaacaaaaaaaaaaaaaaaaaaacccaaacaccaaaccccccaaaaaaaacaaacccccccccccaaccccaaacccccccccccccccaac +abaaacaacaaaaccccccccccccccaaccccccacaaaaacccccaacccccccccccccccaaaacaaaaaaaaaacccaacccaaacaacccaaccccaaaaccccccccaacaaaaaaaaaaccccccccaaaaccaaaccccccccccccccaaac +abaaccaaccaaacacccccccccccccccccccccccaaaacccaaaaaaccaaaccccccccccaacaaaaaaaaaacccaaccccccccccccccccccaaaaccccccccccccaaaaaaaaaccccccciiiiiaaaaacccccccccccccccccc +abaaccccaaaaaaaacccccccccccccccccccccccaaccccaaaaaaccaaaaaccccacccaaccaaacaaaaacccccccccccccccaacccccccaaaccccccccccccccaaaaacccccccciiiiiiiiaaaaaccccccaaaccccccc +abaaacccaaaaaaaacccccccccccccccccccccccccccccaaaaaacaaaaaccccaaaaaaaccaaccaaacccccccaaaaacacccaaccccccccccaacccccccccccaaaaaaccccccciiiiiiiiijjaaaaaccccaaacaccccc +abaaaccccaaaaaaccccccccccccccccccccaaccccccccaaaaaccaaaaacccccaaaaaaaaccccccccccccccaaaaaaaaaaaaccccccccccaaacaaccccccaaaaaaaccccccciiinnnnoijjjjjjjjjjaaaaaaacccc +abccccccccaaaaacccccaacccccccccccaaaacccccccccaaaacccaaaaaccccaaaaaaaaacccccccccccccaaaaaaaaaaaaaaccccccccaaaaaacccaacaaacaaacccccchhinnnnnoojjjjjjjjjkkaaaaaacccc +abcccccccaaaaaacaaacaacccccccccccaaaaaaccccccccccccccaacccccccaaaaaaaaacaaccccccccccaaaaaaaaaaaaaaacccccaaaaaaacccaaaaccccccacaaccchhinnnnnoooojjjjjjkkkkaaaaccccc +abaacccaccaaaccccaaaaaccccccccccccaaaaccccccccccccccccccccccccaaaaaaaacaaaaaaaccccccaaaaaaaaaaaaaaacccccaaaaaaacccaaaaccccaaacaaachhhnnntttuooooooooppkkkaaaaccccc +abaacccaaaaaaaccccaaaaaacccccccccaaaaaccccccccccccccccccccccccaaaaaaacccaaaaacccccccccaaacaaaaaaaaccccccccaaaaacccaaaacccccaaaaacchhhnnnttttuooooooppppkkkaaaccccc +abaacccaaaaaaccccaaaaaaacccccccccaacaaccccccccccccccccccccccaaaccaaaccaaaaaaacccccccccccccaaaaaaaccccccaacaacaaacccccccccccaaaaaahhhhnntttttuuouuuuupppkkkcccccccc +abaaaacaaaaaaaaaaaaaaacccccccccccccccccccccccccccccccccccccaaaacccaaacaaaaaaaaccccccccccccaccaaaccccccaaacaaccccccccccccccaaaaaahhhhnnntttxxxuuuuuuupppkkkcccccccc +abaaaacaaaaaaaaaaacaaacccaaacccccccccccccccccccccacccccccccaaaacccccccaaaaaaaaccccccccccccccccaaacccccaaacaaacccccccccccccaaaaaahhhhmnnttxxxxuuyuuuuuppkkkcccccccc +abaaaccaaaaaaaaccccaaaccccaaaccacccccccccccaaaaaaaaccccccccaaaacccccccccaaacaacccccccccccccccccccccaaaaaaaaaacccccacccccccaacaghhhmmmmtttxxxxxxyyyuupppkkccccccccc +abaaccaaaaaaaccccccccccccaaaaaaaacccccccccccaaaaaaccccccccccccccccccccccaaccccccaacccccccccccccccccaaaaaaaaacccccaaccccccccccagggmmmmttttxxxxxyyyyvvppkkkccccccccc +abaacccaccaaacccccccccccaaaaaaaaccccccccccccaaaaaaccccccccccccccccccccccccccaaacaaaccccccccccccccccccaaaaaccccaaaaacaacccccccgggmmmmttttxxxxxyyyyvvpppiiiccccccccc +SbaaaaaccccaaccccccccccaaaaaaaaacacccccccccaaaaaaaacccccccccccccccaacccccccccaaaaaccccccccccaaaacccccaaaaaacccaaaaaaaaccaaaccgggmmmsssxxxEzzzzyyvvvpppiiiccccccccc +abaaaaaccccccccccccccccaaaaaaaaaaaaaaaaaccaaaaaaaaaacccccccccccaaaaacccccccccaaaaaaaccccccccaaaaaccccaaaaaaaccccaaaaacccaaaaagggmmmsssxxxxxyyyyyyvvqqqiiiccccccccc +abaaaaacccccccccccccccccaaaaaaaacaaaaaacccaaaaaaaaaaccccccccccccaaaaacccccccaaaaaaaacccccccaaaaaaccccaaacaaacccaaaaacccaaaaaagggmmmssswwwwwyyyyyyyvvqqqiiicccccccc +abaaaaccccccccccccccccccccaaaaaaaaaaaaacccacacaaacccccccccccccccaaaaacccccccaaaaaaaacccccccaaaaaaccccacccccccccaacaaaccaaaaaagggmmmsssswwwwyyyyyyyvvvqqiiicccccccc +abaaaaacccccccccccccccccccaacccaaaaaaaaaccccccaaaccccccccccccccaaaaaccccccccaacaaacccccccccaaaaaacccccccccccccccccaaccccaaaaagggmmmmssssswwyywwvvvvvvqqiiicccccccc +abaaaaaccccccccccccccccccaaacccaaaaaaaaaacccccaaaccccccaacccccccccaaccaaccccccaaaacaccccaacccaacccccccccccccccccccccccccaaaaccggglllllssswwwywwwvvvvqqqiiicccccccc +abaccccccccccccccccccccccccccccaaaaaaaaaaccccaaaacccaaaacccccccccccccaaaccccccaaaaaaaaaaaacccccccccccccccccccccccccccccccccccccffffllllsswwwwwwrrqvqqqqiiicccccccc +abccccccccccccccccccccccccccccccccaaacacaccccaaaacccaaaaaacccccccccaaaaaaaaccccaaaaaaaaaaaacccccccccccccccccccccccccccccccccccccfffflllssrwwwwrrrqqqqqqjjicccccccc +abcccccccaaaccccccccaaccccccccccccaaacccccccccaaaccccaaaaacccccccccaaaaaaaaccaaaaaaacaaaaaaacccccccccccccccccccccccccccccccccccccfffflllrrwwwrrrrqqqqjjjjjcccccccc +abaaaccaaaaacccccccaaacaaccccccccccaacccccccccccccccaaaaacccccccccccaaaaaacccaaaaaaaaaaaaaaaccccccccccccccccccccccccccccccccccccccffffllrrrrrrrkjjjjjjjjjcccaccccc +abaaaccaaaaaacccccccaaaaacaacaaccccccccccccccccccccccccaacccccccccccaaaaaacccaaaaaaaaaaaaacccccccccccccccccccccccccccccccccccccccccfffllrrrrrrkkjjjjjjjcccccaccccc +abaaaccaaaaaacccccaaaaaaccaaaaacccccccccccccccccccccccccccccccccccccaaaaaacccccaaacaaaaaaacccccccccccccccccccccccccccccccccccccccccfffllkkrrrkkkjjddcccccccaaacccc +abaaaccaaaaaccccccaaaaaaaacaaaaaccccccccccccccccccccccccccccccccccccaaacaacccccaaaccccccaaaaccccaaaccccccccccccccccaaaccccccccccccccfeekkkkkkkkkdddddccccaaaaacccc +abaaacccaaaaccccccaacaaaaaaaaaaaccccccccccccccccccccccccccccccccccccccaacaacccccccccccccccaaccccaaaacccccccccccccccaaaacccccccccccccceeekkkkkkdddddddcccaaacaccccc +abaccccccccccccccccccaacccaaaaccccccccccccccccccccccccccccaaccaaccaacccaaaaccccccccccccaaaaaaaacaaaacccccccccccccccaaaacccaaaaacccccceeeekkkkdddddaaccccaacccccccc +abccccccccccccccccccaaccccccaaccccccccccccaaacccccccccccccaaaaaaccaaaacaaaaacccccccccccaaaaaaaacaaaccccccccccccccccaaaacccaaaaaccccccceeeeeeedddcacacccccccccccccc +abccccccccccccccccccccccccccccccccccccccccaaaacaacccccccccaaaaacccaaaaaaaaaaccccccccccccaaaaaacccccccccccccccccccccccccccaaaaaacccccccaeeeeeeddcccccccccccccccaaac +abccccccccccccccccccccccccccccccccccccccccaaaaaaacccccccccaaaaaaccaaaaaaaacaccccccaaacaaaaaaaacccccccccccccccccccccccccccaaaaaacccccccccceeeeaaccccccccccccccccaaa +abcccccccccccccccccccccccccccccccccccccccccaaaaaaccccccccaaaaaaaaccaaaaaaaccccccccaaaaaaaaaaaacccccccccccccccccccccccccccaaaaaacccccccccccccaaaccccccccccccccccaaa +abccccccccccccccccccccccccccccccccccccccaaaaaaaaccccaaaccaaaaaaaacaaaaaaaaaacccccccaaaaaaaccaacccccccccccccccccccccccccccccaacccccccccccccccaaaccccccccccccccaaaaa +abccccccccccccccccccccccccccccccccccccccaaaaaaaaacccaaaaccccaaccaaaaaaaaaaaaaccccaaaaaaaaaacccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccaaaaaa diff --git a/AdventOfCode2022/Solutions/Day12.swift b/AdventOfCode2022/Solutions/Day12.swift new file mode 100644 index 0000000..205d3db --- /dev/null +++ b/AdventOfCode2022/Solutions/Day12.swift @@ -0,0 +1,185 @@ +import Foundation + + +struct Day12 { + + func solution1(_ input: String) -> Int { + + let heightMap = parse(input) + let startNode = heightMap.startNode + let endNode = heightMap.endNode + + let distance = heightMap.findShortestPath(from: startNode, to: endNode) + return distance + } + + + func solution2(_ input: String) -> Int { + + let heightMap = parse(input) + let endNode = heightMap.endNode + + var paths: [MapNode: Int] = [:] + + for startNode in heightMap.lowestNodes { + let dist = heightMap.findShortestPath(from: startNode, to: endNode) + paths[startNode] = dist + } + + return paths.values.filter { $0 != -1 }.sorted().first! + + } + + func parse(_ input: String) -> HeightMap { + var mapRows = [[MapNode]]() + + let map = input.split(separator: "\n").map { String($0).split(separator: "").map { String($0) } } + + for (i, row) in map.enumerated() { + var nodeRow = [MapNode]() + for (j, val) in row.enumerated() { + let id = row.count * i + j + nodeRow.append(MapNode(height: val, x: i, y: j, id: id)) + } + mapRows.append(nodeRow) + } + + return HeightMap(nodes: mapRows) + + } + +} + + +struct HeightMap { + let nodes: [[MapNode]] + + var startNode: MapNode { + for nodeRow in nodes { + for node in nodeRow { + if node.isStartNode { + return node + } + } + } + + fatalError("no start node!") + } + + var endNode: MapNode { + for nodeRow in nodes { + for node in nodeRow { + if node.isEndNode { + return node + } + } + } + + fatalError("no end node!") + } + + var lowestNodes: [MapNode] { + var lowNodes = [MapNode]() + for nodeRow in nodes { + for node in nodeRow { + if node.isStartNode || node.height == "a" { + lowNodes.append(node) + } + } + } + return lowNodes + } + + func findShortestPath(from fromNode: MapNode, to toNode: MapNode) -> Int { + + var nodesToVisit: Queue = Queue() + var distances = Array(repeating: -1, count: nodes.count * nodes[0].count) + + nodesToVisit.enqueue(fromNode) + distances[fromNode.id] = 0 + + while !nodesToVisit.isEmpty { + + let node = nodesToVisit.dequeue()! + + for neighbour in getAllowedNodesFor(node) { + if distances[neighbour.id] == -1 { + distances[neighbour.id] = distances[node.id] + 1 + nodesToVisit.enqueue(neighbour) + } + } + + } + + return distances[toNode.id] + } + + + func getAllowedNodesFor(_ node: MapNode) -> [MapNode] { + var neighbours = [MapNode]() + let x = node.x + let y = node.y + + //up + let prevRow = x-1 + + if prevRow >= 0, nodes[prevRow][y].intrinsicHeight - nodes[x][y].intrinsicHeight <= 1 { + neighbours.append(nodes[prevRow][y]) + } + + //down + let nextRow = x+1 + if nextRow < nodes.count, nodes[nextRow][y].intrinsicHeight - nodes[x][y].intrinsicHeight <= 1 { + neighbours.append(nodes[nextRow][y]) + } + + // left + let prevCol = y-1 + if prevCol >= 0, nodes[x][prevCol].intrinsicHeight - nodes[x][y].intrinsicHeight <= 1 { + neighbours.append(nodes[x][prevCol]) + } + + //right + let nextCol = y+1 + if nextCol < nodes[x].count, nodes[x][nextCol].intrinsicHeight - nodes[x][y].intrinsicHeight <= 1 { + neighbours.append(nodes[x][nextCol]) + } + + return neighbours + } +} + + +struct MapNode: Hashable, Identifiable { + let height: String + let x: Int + let y: Int + let id: Int + + var isStartNode: Bool { + height == "S" + } + + var isEndNode: Bool { + height == "E" + } + + var intrinsicHeight: Int { + if height == "S" { + return Int("a"[0].asciiValue!) + } + + if height == "E" { + return Int("z"[0].asciiValue!) + } + + return Int(height[0].asciiValue!) + } +} + + +extension Queue { + var isEmpty: Bool { + count == 0 + } +} diff --git a/AdventOfCode2022/main.swift b/AdventOfCode2022/main.swift index 3d1cabe..340b35a 100644 --- a/AdventOfCode2022/main.swift +++ b/AdventOfCode2022/main.swift @@ -45,6 +45,10 @@ let inputLoader = InputLoader(inputPath: inputsPath) //Day11 //let result = Day11().solution1(inputLoader.loadFileAsString("day_11.txt")) -let result = Day11().solution2(inputLoader.loadFileAsString("day_11.txt")) +//let result = Day11().solution2(inputLoader.loadFileAsString("day_11.txt")) + +//day12 +//let result = Day12().solution1(inputLoader.loadFileAsString("day_12.txt")) +let result = Day12().solution2(inputLoader.loadFileAsString("day_12.txt")) print(result)