aoc24/9.jl
2024-12-11 02:37:15 +00:00

61 lines
1.4 KiB
Julia

const ID = Union{Int,Nothing}
function getDisk()
local blocks::Vector{Int8} = [ x - Int('0') for x in collect(read("input/9")) ][1:end-1]
local disk::Vector{ID} = Vector()
for b in 1:length(blocks)
local id = (b - 1) ÷ 2
local size = blocks[b]
local isFile = b & 1 == 1
for i in 1:size
push!(disk, isFile ? id : nothing)
end
end
return disk
end
const disk = getDisk()
function compress!(arr::AbstractVector, selectRange = (arr, i) -> i:i)
for i in reverse(1:length(arr))
if !isnothing(arr[i])
local fillerRange = selectRange(arr, i)
local head = 1
while head < i
if isnothing(arr[head])
local emptyRange = selectRange(arr, head)
local l = length(fillerRange)
if length(emptyRange) >= l
local s = emptyRange[1]
arr[s:s+l-1] = arr[fillerRange]
arr[fillerRange] .= nothing
break
else
head += l
continue
end
else
head += 1
end
end
end
end
return arr
end
function selectRangeChunk(arr, i)
local c, lower, upper = arr[i], i, i
while lower > 1 && arr[lower-1] == c
lower -= 1
end
while upper < length(arr) && arr[upper+1] == c
upper += 1
end
return lower:upper
end
checksum(arr) = mapreduce(x -> isnothing(x[2]) ? 0 : (x[1]-1) * x[2], +, enumerate(arr))
println("Part one ", checksum(compress!(copy(disk))))
println("Part two ", checksum(compress!(copy(disk), selectRangeChunk)))