This commit is contained in:
2024-12-14 00:23:28 -08:00
parent b023d0ea19
commit 18533b6ab4
5 changed files with 126 additions and 0 deletions

67
day09/d09p1.swift Normal file
View 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
View 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

File diff suppressed because one or more lines are too long

1
day09/test.txt Normal file
View File

@@ -0,0 +1 @@
2333133121414131402

1
day09/test2.txt Normal file
View File

@@ -0,0 +1 @@
2333133020404131402