d09
This commit is contained in:
67
day09/d09p1.swift
Normal file
67
day09/d09p1.swift
Normal file
@@ -0,0 +1,67 @@
|
||||
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 if x > 0 {
|
||||
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
|
||||
var firstFree: Int = 0 // emulate a Deque, avoid O(n) removal from front
|
||||
var compact = false
|
||||
|
||||
mutating func evolve() {
|
||||
var (iFree, freeBlock) = free[firstFree]
|
||||
var (iData, dataBlock) = data.last!
|
||||
let fileNo = data.count - 1
|
||||
while (dataBlock >= freeBlock) {
|
||||
if iFree > iData {
|
||||
if dataBlock == 0 {
|
||||
data.removeLast()
|
||||
}
|
||||
data.enumerated().forEach { fileNo, d in
|
||||
let (i, len) = d
|
||||
csum += fileNo * sumRange(start: i, len: len)
|
||||
}
|
||||
compact = true
|
||||
return
|
||||
}
|
||||
csum += fileNo * sumRange(start: iFree, len: freeBlock)
|
||||
dataBlock -= freeBlock
|
||||
data[fileNo] = (iData, dataBlock)
|
||||
firstFree += 1
|
||||
(iFree, freeBlock) = free[firstFree]
|
||||
}
|
||||
if dataBlock > 0 { // not needed; only for sanity
|
||||
csum += fileNo * sumRange(start: iFree, len: dataBlock)
|
||||
free[firstFree] = (iFree + dataBlock, freeBlock - dataBlock)
|
||||
}
|
||||
data.removeLast()
|
||||
}
|
||||
}
|
||||
|
||||
var disk = try readInput(CommandLine.arguments[1])
|
||||
while !disk.compact {
|
||||
disk.evolve()
|
||||
//print(disk)
|
||||
}
|
||||
print(disk.csum)
|
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)
|
1
day09/input.txt
Normal file
1
day09/input.txt
Normal file
File diff suppressed because one or more lines are too long
1
day09/test.txt
Normal file
1
day09/test.txt
Normal file
@@ -0,0 +1 @@
|
||||
2333133121414131402
|
1
day09/test2.txt
Normal file
1
day09/test2.txt
Normal file
@@ -0,0 +1 @@
|
||||
2333133020404131402
|
Reference in New Issue
Block a user