Compare commits
	
		
			2 Commits
		
	
	
		
			5b7bbb9963
			...
			e35da0cd55
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| e35da0cd55 | |||
| 99fdb31d76 | 
							
								
								
									
										69
									
								
								day18/d18p1.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								day18/d18p1.swift
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,69 @@ | |||||||
|  | import Foundation | ||||||
|  |  | ||||||
|  | struct Coord : Hashable, CustomStringConvertible { | ||||||
|  |     let (x, y): (Int, Int) | ||||||
|  |     var description: String { return "(\(x),\(y))" } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func readInput(_ fileName: String) throws -> [Coord] { | ||||||
|  |     let xy = try Regex(#"([0-9]+),([0-9]+)"#) | ||||||
|  |     return try String(contentsOfFile: fileName,  encoding: .ascii) | ||||||
|  |         .split(separator: "\n") | ||||||
|  |         .compactMap { $0.wholeMatch(of: xy) } | ||||||
|  |         .map { Coord( | ||||||
|  |             x: Int($0.output[1].substring!)!, | ||||||
|  |             y: Int($0.output[2].substring!)! | ||||||
|  |         ) } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | struct Map : CustomStringConvertible { | ||||||
|  |     let walls: Set<Coord> | ||||||
|  |     let (w, h): (Int, Int) | ||||||
|  |     var description: String { | ||||||
|  |         let top = "   \u{001B}[4m" + (0..<w).map { " \($0 % 10)" }.joined() + "\u{001B}[0m\n" | ||||||
|  |         let maze = (0..<h).map { i in | ||||||
|  |             String(format: "%2d▕", i) + (0..<w).map { j in | ||||||
|  |                 walls.contains(Coord(x: j, y: i)) ? "🮘🮘" : "  " | ||||||
|  |             }.joined() + "▌" | ||||||
|  |         }.joined(separator: "\n") | ||||||
|  |         let bot = "\n   " + String(repeating: "🬂", count: w*2) + "🬀" | ||||||
|  |         return top + maze + bot | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     func dijkstra(from start: Coord, to end: Coord) -> Int? { | ||||||
|  |         var q = Heap<(Coord, Int)>(comparator: { l, r in l.1 < r.1 }) | ||||||
|  |         var seen: Set<Coord> = [start] | ||||||
|  |         q.insert((start, 0)) | ||||||
|  |         while let (cell, cost) = q.pop() { | ||||||
|  |             if cell == end { | ||||||
|  |                 return cost | ||||||
|  |             } | ||||||
|  |             [(0, -1), (0, 1), (-1, 0), (1, 0)].map { dy, dx in | ||||||
|  |                 Coord(x: cell.x + dx, y: cell.y + dy)} | ||||||
|  |                 .filter { c in c.x >= 0 && c.y >= 0 && c.x < w && c.y < h } | ||||||
|  |                 .filter { !seen.contains($0) } | ||||||
|  |                 .filter { !walls.contains($0) } | ||||||
|  |                 .forEach { neighbor in | ||||||
|  |                     seen.insert(neighbor) | ||||||
|  |                     q.insert((neighbor, cost + 1)) | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  |         return nil | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @main | ||||||
|  | struct AoC { | ||||||
|  |     static func main() throws { | ||||||
|  |         let bytes = try readInput(CommandLine.arguments[1]) | ||||||
|  |         let w = Int(CommandLine.arguments[2]) ?? 71 | ||||||
|  |         let h = Int(CommandLine.arguments[3]) ?? 71 | ||||||
|  |         let limit = Int(CommandLine.arguments[4]) ?? 1024 | ||||||
|  |         let map = Map(walls: Set(bytes.prefix(limit)), w: w, h: h) | ||||||
|  |         print(map) | ||||||
|  |         print(map.dijkstra( | ||||||
|  |             from: Coord(x: 0, y: 0), to: Coord(x: map.w - 1, y: map.h - 1) | ||||||
|  |         ) ?? "no solution") | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										82
									
								
								day18/d18p2.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								day18/d18p2.swift
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | |||||||
|  | import Foundation | ||||||
|  |  | ||||||
|  | struct Coord : Hashable, CustomStringConvertible { | ||||||
|  |     let (x, y): (Int, Int) | ||||||
|  |     var description: String { return "(\(x),\(y))" } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func readInput(_ fileName: String) throws -> [Coord] { | ||||||
|  |     let xy = try Regex(#"([0-9]+),([0-9]+)"#) | ||||||
|  |     return try String(contentsOfFile: fileName,  encoding: .ascii) | ||||||
|  |         .split(separator: "\n") | ||||||
|  |         .compactMap { $0.wholeMatch(of: xy) } | ||||||
|  |         .map { Coord( | ||||||
|  |             x: Int($0.output[1].substring!)!, | ||||||
|  |             y: Int($0.output[2].substring!)! | ||||||
|  |         ) } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | struct Map : CustomStringConvertible { | ||||||
|  |     let walls: Set<Coord> | ||||||
|  |     let (w, h): (Int, Int) | ||||||
|  |     var description: String { | ||||||
|  |         let top = "   \u{001B}[4m" + (0..<w).map { " \($0 % 10)" }.joined() + "\u{001B}[0m\n" | ||||||
|  |         let maze = (0..<h).map { i in | ||||||
|  |             String(format: "%2d▕", i) + (0..<w).map { j in | ||||||
|  |                 walls.contains(Coord(x: j, y: i)) ? "▓▓" : "  " | ||||||
|  |             }.joined() + "▌" | ||||||
|  |         }.joined(separator: "\n") | ||||||
|  |         let bot = "\n   " + String(repeating: "🬂", count: w*2) + "🬀" | ||||||
|  |         return top + maze + bot | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     func heur(_ a: Coord, _ b: Coord) -> Int { | ||||||
|  |         return abs(a.x - b.x) + abs(a.y - b.y) | ||||||
|  |     } | ||||||
|  |     func astar(from start: Coord, to end: Coord) -> Int? { | ||||||
|  |         var q = Heap<(Coord, Int)>(comparator: { l, r in l.1 < r.1 }) | ||||||
|  |         var seen: [Coord: Int] = [start: 0] | ||||||
|  |         q.insert((start, heur(start, end))) | ||||||
|  |         while let (cell, _) = q.pop() { | ||||||
|  |             if cell == end { | ||||||
|  |                 return seen[cell] | ||||||
|  |             } | ||||||
|  |             [(0, -1), (0, 1), (-1, 0), (1, 0)].map { dy, dx in | ||||||
|  |                 Coord(x: cell.x + dx, y: cell.y + dy)} | ||||||
|  |                 .filter { c in c.x >= 0 && c.y >= 0 && c.x < w && c.y < h } | ||||||
|  |                 .filter { !walls.contains($0) } | ||||||
|  |                 .forEach { nb in | ||||||
|  |                     let newCost = seen[cell]! + 1 | ||||||
|  |                     if seen[nb, default: w*h] > newCost { | ||||||
|  |                         seen[nb] = newCost | ||||||
|  |                         q.insert((nb, newCost + heur(nb, end))) | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  |         return nil | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @main | ||||||
|  | struct AoC { | ||||||
|  |     static func main() throws { | ||||||
|  |         let bytes = try readInput(CommandLine.arguments[1]) | ||||||
|  |         let w = Int(CommandLine.arguments[2]) ?? 71 | ||||||
|  |         let h = Int(CommandLine.arguments[3]) ?? 71 | ||||||
|  |         let startLimit = Int(CommandLine.arguments[4]) ?? 1024 | ||||||
|  |         for limit in startLimit..<bytes.count { | ||||||
|  |             let map = Map(walls: Set(bytes.prefix(limit)), w: w, h: h) | ||||||
|  |             if let cost = map.astar( | ||||||
|  |                 from: Coord(x: 0, y: 0), | ||||||
|  |                 to: Coord(x: map.w - 1, y: map.h - 1) | ||||||
|  |             ) { | ||||||
|  |                 print("\(limit): \(cost)") | ||||||
|  |             } else { | ||||||
|  |                 print(map) | ||||||
|  |                 print("found byte \(limit-1): \(bytes[limit-1])") | ||||||
|  |                 return | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										54
									
								
								day18/heap.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								day18/heap.swift
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | |||||||
|  | struct Heap<T> { | ||||||
|  |     var comparator: ((_ l: T,_ r: T) -> Bool) | ||||||
|  |     var heap: [T] = [] | ||||||
|  |     var isEmpty: Bool { return heap.isEmpty } | ||||||
|  |  | ||||||
|  |     private mutating func bubbleUp(idx: Int) { | ||||||
|  |         let parent = (idx - 1) / 2 | ||||||
|  |         if idx <= 0 { | ||||||
|  |             return | ||||||
|  |         } | ||||||
|  |         if comparator(heap[idx], heap[parent]) { | ||||||
|  |             heap.swapAt(parent, idx) | ||||||
|  |             bubbleUp(idx: parent) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private mutating func heapify(_ idx: Int) { | ||||||
|  |         let left = idx * 2 + 1 | ||||||
|  |         let right = idx * 2 + 2 | ||||||
|  |         var comp = idx | ||||||
|  |  | ||||||
|  |         if heap.count > left && comparator(heap[left], heap[comp]) { | ||||||
|  |             comp = left | ||||||
|  |         } | ||||||
|  |         if heap.count > right && comparator(heap[right], heap[comp]) { | ||||||
|  |             comp = right | ||||||
|  |         } | ||||||
|  |         if comp != idx { | ||||||
|  |             heap.swapAt(comp, idx) | ||||||
|  |             heapify(comp) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     mutating func insert(_ item: T) { | ||||||
|  |         heap.append(item) | ||||||
|  |         bubbleUp(idx: heap.count-1) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     mutating func pop() -> T? { | ||||||
|  |         let item: T? = heap.first | ||||||
|  |         if heap.count == 0 { | ||||||
|  |             return nil | ||||||
|  |         } | ||||||
|  |         if heap.count > 1 { | ||||||
|  |             heap[0] = heap[heap.count-1] | ||||||
|  |             heap.removeLast() | ||||||
|  |             heapify(0) | ||||||
|  |         } else if heap.count == 1{ | ||||||
|  |             heap.removeLast() | ||||||
|  |         } | ||||||
|  |         return item | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										3450
									
								
								day18/input.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3450
									
								
								day18/input.txt
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										25
									
								
								day18/test.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								day18/test.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | |||||||
|  | 5,4 | ||||||
|  | 4,2 | ||||||
|  | 4,5 | ||||||
|  | 3,0 | ||||||
|  | 2,1 | ||||||
|  | 6,3 | ||||||
|  | 2,4 | ||||||
|  | 1,5 | ||||||
|  | 0,6 | ||||||
|  | 3,3 | ||||||
|  | 2,6 | ||||||
|  | 5,1 | ||||||
|  | 1,2 | ||||||
|  | 5,5 | ||||||
|  | 2,5 | ||||||
|  | 6,5 | ||||||
|  | 1,4 | ||||||
|  | 0,4 | ||||||
|  | 6,4 | ||||||
|  | 1,1 | ||||||
|  | 6,1 | ||||||
|  | 1,0 | ||||||
|  | 0,5 | ||||||
|  | 1,6 | ||||||
|  | 2,0 | ||||||
		Reference in New Issue
	
	Block a user