You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

98 lines
2.2 KiB

#!/usr/bin/env julia
using Test
function parse_stacks_line(line)
parts = Iterators.partition(line, 4)
return [s[2] for s in parts]
end
function read_stacks(io)
stacks = Vector{Vector{Char}}()
for line in eachline(io)
if isempty(line)
return stacks
end
if line[1:3] == " 1 "
continue
end
stacks_row = parse_stacks_line(line)
while length(stacks_row) > length(stacks)
push!(stacks, [])
end
for (i, c) in Iterators.enumerate(stacks_row)
if c == ' '
continue
end
pushfirst!(stacks[i], c)
end
end
return stacks
end
struct Move
count :: Int
from :: Int
to :: Int
end
function parse_move_line(line)
# move 1 from 2 to 1
parts = split(line)
return Move(parse(Int, parts[2]), parse(Int, parts[4]), parse(Int, parts[6]))
end
function read_apply_moves(stacks, io; rev::Bool = true)
for line in eachline(io)
move = parse_move_line(line)
if rev
for i in 1:move.count
push!(stacks[move.to], pop!(stacks[move.from]))
end
else
from_len = length(stacks[move.from])
from_range = UnitRange(from_len - move.count + 1, from_len)
append!(stacks[move.to], splice!(stacks[move.from], from_range))
end
end
return stacks
end
function operate_crane(infile; rev::Bool = true)
open(infile, "r") do io
stacks = read_stacks(io)
stacks2 = read_apply_moves(stacks, io, rev=rev)
return stacks2
end
end
function top_crates(stacks)
return join([last(s) for s in stacks])
end
function test()
@testset "elf crates 2000" verbose=true begin
@test top_crates(operate_crane("example.txt")) == "CMZ"
@test top_crates(operate_crane("input.txt")) == "QNHWJVJZW"
end
@testset "elf crates 2001" verbose=true begin
@test top_crates(operate_crane("example.txt", rev=false)) == "MCD"
@test top_crates(operate_crane("input.txt", rev=false)) == "BPCZJLFJW"
end
end
function main()
if size(ARGS, 1) == 0
test()
else
infile = ARGS[1]
println("infile = ", infile)
println("crates: ", read_stacks(infile))
stacks2 = operate_crane(infile)
println("after : ", stacks2)
println("top : ", top_crates(stacks2))
end
end
main()