d09
This commit is contained in:
		
							
								
								
									
										56
									
								
								day09/d09p2.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								day09/d09p2.swift
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| import Foundation | ||||
|  | ||||
| func readInput(_ filePath: String) throws -> Disk { | ||||
|     let content = try String(contentsOfFile: filePath, encoding: .ascii) | ||||
|         .trimmingCharacters(in: .whitespacesAndNewlines) | ||||
|         .map { Int(String([$0]))! } | ||||
|     var pos = 0 | ||||
|     var data: [(Int, Int)] = [] | ||||
|     var free: [(Int, Int)] = [] | ||||
|     for (i, x) in content.enumerated() { | ||||
|         if i.isMultiple(of: 2) { | ||||
|             data.append((pos, x)) | ||||
|         } else { | ||||
|             free.append((pos, x)) | ||||
|         } | ||||
|         pos += x | ||||
|     } | ||||
|     return Disk(data: data, free: free) | ||||
| } | ||||
|  | ||||
| func sumRange(start: Int, len: Int) -> Int { | ||||
|     return len * (start + start + len - 1) / 2 | ||||
| } | ||||
|  | ||||
| struct Disk { | ||||
|     var data: [(Int, Int)] | ||||
|     var free: [(Int, Int)] | ||||
|     var csum: Int = 0 | ||||
|  | ||||
|     mutating func compact() { | ||||
|         for fileNo in (0..<data.count).reversed() { | ||||
|             var moved = false | ||||
|             let (iData, dataBlock) = data[fileNo] | ||||
|             for freeNo in 0..<free.count { | ||||
|                 let (iFree, freeBlock) = free[freeNo] | ||||
|                 if iFree > iData { | ||||
|                     break | ||||
|                 } | ||||
|                 if freeBlock >= dataBlock { | ||||
|                     csum += fileNo * sumRange(start: iFree, len: dataBlock) | ||||
|                     free[freeNo] = (iFree + dataBlock, freeBlock - dataBlock) | ||||
|                     data[fileNo] = (iData, 0) | ||||
|                     moved = true | ||||
|                     break | ||||
|                 } | ||||
|             } | ||||
|             if !moved { | ||||
|                 csum += fileNo * sumRange(start: iData, len:dataBlock) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| var disk = try readInput(CommandLine.arguments[1]) | ||||
| disk.compact() | ||||
| print(disk.csum) | ||||
		Reference in New Issue
	
	Block a user