Mercurial > lbo > hg > aoc22
view 2022/17/17.jl @ 54:a8d3b517a0fe
Add 3rd test input for Day 08
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Thu, 14 Dec 2023 14:28:01 +0100 |
parents | 05ddc45b4210 |
children |
line wrap: on
line source
using StaticArrays; const test_input = "test_input.txt"; const rocks = Vector{Matrix{Int}}([[1 1 1 1], [0 1 0; 1 1 1; 0 1 0], [0 0 1; 0 0 1; 1 1 1], [1;1;1;1][:,:], [1 1; 1 1]]); const ChamberWidth = 7; const InitialVOff = 3; const Line = MVector{ChamberWidth, Bool}; const Chamber = Vector{Line}; function show_chamber(c::Chamber) for l in reverse(c) println(String(map(x -> x ? '@' : '.', l))); end end @enum Direction begin L R end function parsechar(c::Char)::Direction if c == '<' L elseif c == '>' R end end function parse_input(f::String)::Vector{Direction} open(f; read=true) do fh l = readline(fh); map(parsechar, collect(l)) end end function would_overlap(r::Matrix{Int}, left::Int, up::Int, c::Chamber)::Bool if left+size(r, 2)-1 > ChamberWidth || left < 1 println("lateral stop"); return true; end if up > length(c) return false; end lines_overlap = length(c) - up + 1; zs = zeros(Bool, ChamberWidth); for l = 1:lines_overlap cl = c[end-l+1]; rl = r[end-l+1,:]; rlc = Line(zs); rlc[left:left+size(r, 2)-1] .= rl; if any((>)(1), Int.(cl) .+ Int.(rlc)) @show (cl, rlc) return true; end end false end function move_rock(r::Matrix{Int}, d::Direction, left::Int, up::Int, c::Chamber)::Tuple{Int,Int,Bool} newl, newu = left, up; println("Jet pushes $d"); if would_overlap(r, left + (d == L ? -1 : +1), newu, c) # Lateral move didn't work, just ignore # else println(" ok"); newl = left + (d == L ? -1 : 1); end if would_overlap(r, newl, up-1, c) return (newl, up, true); else println("Rock falls 1"); newu = up-1; end (newl, newu, false) end function merge_rock(c::Chamber, r::Matrix{Int}, left::Int, up::Int) z = zeros(Bool, ChamberWidth); for i = 1:(up-length(c)+size(r, 1)-1) push!(c, Line(z)); end for i = 0:size(r, 1)-1 cl = c[up+i]; rl = r[end-i, :]; rlc = Line(z); rlc[left:left+size(r, 2)-1] .= rl; cl .|= rlc; end end function handle_fall(jets::Vector{Direction}; maxi=2022)::Int c = Chamber(); rs = Iterators.cycle(rocks); jets = Iterators.cycle(jets); jetst = 0; i = 0; for rock = rs i += 1; @show i show_chamber(c); # Coordinates relative to floor. # Left is position of left-most edge, up position of bottom part. left, up = 3, length(c)+4+(i == 1 ? 1 : 0); settled = false; for j = 1:3 jet, jetst = iterate(jets, jetst); left, up, settled = move_rock(rock, jet, left, up, c); @assert !settled; end while !settled && up > 1 jet, jetst = iterate(jets, jetst); left, up, settled = move_rock(rock, jet, left, up, c); end # Update chamber image merge_rock(c, rock, left, up); show_chamber(c); if i == maxi break end end println("---"); show_chamber(c); length(c) end handle_fall(parse_input("17/test_input.txt"); maxi=10);