d05
This commit is contained in:
		
							
								
								
									
										40
									
								
								day05/d05p1.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								day05/d05p1.swift
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | |||||||
|  | import Foundation | ||||||
|  |  | ||||||
|  | func readInput(_ filePath: String) throws -> ([Int: Set<Int>], [[Int]]) { | ||||||
|  |     let content = try String(contentsOfFile: filePath, encoding: .ascii) | ||||||
|  |     var rules: [Int: Set<Int>] = [:] | ||||||
|  |     var pages: [[Int]] = [] | ||||||
|  |     var readingRules = true | ||||||
|  |     for l in content.split(separator: "\n", omittingEmptySubsequences: false) { | ||||||
|  |         if l == "" { | ||||||
|  |             readingRules = false | ||||||
|  |             continue | ||||||
|  |         } | ||||||
|  |         if readingRules { | ||||||
|  |             let rule = l.split(separator: "|").map { Int($0)! } | ||||||
|  |             let (before, after) = (rule[0], rule[1]) | ||||||
|  |             let current = rules[before, default: []] | ||||||
|  |             rules[before] = current.union([after]) | ||||||
|  |         } else { | ||||||
|  |             pages.append(l.split(separator: ",").map { Int($0)! }) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return (rules, pages) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func goodPages(_ pages: [Int], against rules: [Int: Set<Int>]) -> Bool { | ||||||
|  |     var seen: Set<Int> = [] | ||||||
|  |     for page in pages { | ||||||
|  |         if !rules[page, default: []].isDisjoint(with: seen) { | ||||||
|  |             return false | ||||||
|  |         } | ||||||
|  |         seen.insert(page) | ||||||
|  |     } | ||||||
|  |     return true | ||||||
|  | } | ||||||
|  |  | ||||||
|  | let (rules, manuals) = try readInput(CommandLine.arguments[1]) | ||||||
|  | let answer = manuals | ||||||
|  |     .filter { goodPages($0, against: rules) } | ||||||
|  |     .map { $0[$0.count/2] }.reduce(0, +) | ||||||
|  | print(answer) | ||||||
							
								
								
									
										66
									
								
								day05/d05p2.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								day05/d05p2.swift
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | |||||||
|  | import Foundation | ||||||
|  |  | ||||||
|  | func readInput(_ filePath: String) throws -> ([(Int, Int)], [[Int]]) { | ||||||
|  |     let content = try String(contentsOfFile: filePath, encoding: .ascii) | ||||||
|  |     var rules: [(Int, Int)] = [] | ||||||
|  |     var pages: [[Int]] = [] | ||||||
|  |     var readingRules = true | ||||||
|  |     for l in content.split(separator: "\n", omittingEmptySubsequences: false) { | ||||||
|  |         if l == "" { | ||||||
|  |             readingRules = false | ||||||
|  |             continue | ||||||
|  |         } | ||||||
|  |         if readingRules { | ||||||
|  |             let rule = l.split(separator: "|").map { Int($0)! } | ||||||
|  |             rules.append((rule[0], rule[1])) | ||||||
|  |         } else { | ||||||
|  |             pages.append(l.split(separator: ",").map { Int($0)! }) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return (rules, pages) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func rulesMap(_ rulePairs: [(Int, Int)]) -> [Int: Set<Int>] { | ||||||
|  |     var rules: [Int: Set<Int>] = [:] | ||||||
|  |     for (from, to) in rulePairs { | ||||||
|  |         let current = rules[from, default: []] | ||||||
|  |         rules[from] = current.union([to]) | ||||||
|  |     } | ||||||
|  |     return rules | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func goodPages(_ pages: [Int], against rules: [Int: Set<Int>]) -> Bool { | ||||||
|  |     var seen: Set<Int> = [] | ||||||
|  |     for page in pages { | ||||||
|  |         if !rules[page, default: []].isDisjoint(with: seen) { | ||||||
|  |             return false | ||||||
|  |         } | ||||||
|  |         seen.insert(page) | ||||||
|  |     } | ||||||
|  |     return true | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func reorder(_ originalPages: [Int], conformTo rules: [(Int, Int)]) -> [Int] { | ||||||
|  |     let pages = Set(originalPages) | ||||||
|  |     var graph = rulesMap( | ||||||
|  |         rules.filter { from, to in pages.contains(from) && pages.contains(to) } | ||||||
|  |     ) | ||||||
|  |  | ||||||
|  |     // Topological sort | ||||||
|  |     var sorted: [Int] = [] | ||||||
|  |     while graph.count > 0 { | ||||||
|  |         let outNodes: Set<Int> = graph.reduce([], { s, i in s.union(i.value) }) | ||||||
|  |         let inNodes = Set(graph.compactMap { !outNodes.contains($0.key) ? $0.key : nil }) | ||||||
|  |         graph = graph.filter { !inNodes.contains($0.key) } | ||||||
|  |         sorted += inNodes | ||||||
|  |     } | ||||||
|  |     return sorted | ||||||
|  | } | ||||||
|  |  | ||||||
|  | let (rules, manuals) = try readInput(CommandLine.arguments[1]) | ||||||
|  | let answer = manuals | ||||||
|  |     .filter { !goodPages($0, against: rulesMap(rules)) } | ||||||
|  |     .map { reorder($0, conformTo: rules) } | ||||||
|  |     .map { $0[$0.count/2] } | ||||||
|  |     .reduce(0, +) | ||||||
|  | print(answer) | ||||||
							
								
								
									
										1377
									
								
								day05/input.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1377
									
								
								day05/input.txt
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										28
									
								
								day05/test.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								day05/test.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | |||||||
|  | 47|53 | ||||||
|  | 97|13 | ||||||
|  | 97|61 | ||||||
|  | 97|47 | ||||||
|  | 75|29 | ||||||
|  | 61|13 | ||||||
|  | 75|53 | ||||||
|  | 29|13 | ||||||
|  | 97|29 | ||||||
|  | 53|29 | ||||||
|  | 61|53 | ||||||
|  | 97|53 | ||||||
|  | 61|29 | ||||||
|  | 47|13 | ||||||
|  | 75|47 | ||||||
|  | 97|75 | ||||||
|  | 47|61 | ||||||
|  | 75|61 | ||||||
|  | 47|29 | ||||||
|  | 75|13 | ||||||
|  | 53|13 | ||||||
|  |  | ||||||
|  | 75,47,61,53,29 | ||||||
|  | 97,61,53,29,13 | ||||||
|  | 75,29,13 | ||||||
|  | 75,97,47,61,53 | ||||||
|  | 61,13,29 | ||||||
|  | 97,13,75,29,47 | ||||||
		Reference in New Issue
	
	Block a user