commitd8e9c1709f622035b21e8f41edbd088487bb904dparent6d129d2f5129e367ec3fa6c38be9435284a8b46aAuthor:Eamon Caddigan <eamon.caddigan@gmail.com>Date:Sat, 10 Dec 2022 19:06:53 -0800 Solution to day 10, part 2. Rewrote part of my part 1 logic again so that I could reuse it for part 2 (specifically: I went out of my way to avoid having to interpolate X for cycles that I didn't [need to] observe directly, but part 2 worked so much better if you just interpolate X). DataFrames interface is making more sense as I learn the language a bit more.Diffstat:

M | src/day_10.jl | | | 61 | ++++++++++++++++++++++++++++++++++++++++++++----------------- |

1 file changed, 44 insertions(+), 17 deletions(-)diff --git a/src/day_10.jl b/src/day_10.jl@@ -162,14 +162,35 @@ input = readlines("data/day_10.txt") Calculate cumulative sum, skipping `nothing` values """ function cumsomething(x) + # Life would have been easier if I had used `missing` instead of `nothing`, + # but to my mind, "missing" is more specific than "not available". I + # probably just need to get over this. cumsum([isnothing(v) ? 0 : v for v in x]) end """ -Calculate signal strength +Find the X value during every cycle. + +Given a vector of observed cycles and the X values _after_ that cycle, return a +vector containing the X value _during_ every cycle. """ -function signal_strength(X, total_cycles) - cat(1, X[1:end-1], dims = 1) .* total_cycles +function interp_x(cycles::Vector{Int}, X_after::Vector{Int}) + X_during = Array{Int}(undef, (last(cycles)+1,)) + X_during[1] = 1 + obs_cycle_idx = 1 + for cycle = 2:lastindex(X_during) + if cycles[obs_cycle_idx] + 1 == cycle + X_during[cycle] = X_after[obs_cycle_idx] + obs_cycle_idx += 1 + else + X_during[cycle] = X_during[cycle-1] + end + end + X_during +end + +function interp_x(cpu::DataFrame) + interp_x(cpu[!, :total_cycles], cpu[!, :X]) end """ @@ -208,25 +229,31 @@ function run_instructions(input) cpu end -""" -Find the signal strength during a cycle. - -To find the signal strength DURING cycle n, we need the X value AFTER cycle -n-1. -""" -function strength_during(cpu, cycle_number) - X = cpu.X[findlast(cpu.total_cycles .< cycle_number)] - X * cycle_number -end - function part_1(input) cpu = run_instructions(input) - sum(map(Base.Fix1(strength_during, cpu), 20:40:maximum(cpu.total_cycles))) + sum((20:40:last(cpu[!, :total_cycles])) .* interp_x(cpu)[20:40:end]) end @assert part_1(example) == 13140 @info part_1(input) +function draw_crt(X::Vector{Int}) + @assert length(X) == 6 * 40 + crt = [["." for __ in 1:40] for _ in 1:6] + + cycle = 1 + for row = 1:6, col = 1:40 + (abs(X[cycle]+1 - col) <= 1) && (crt[row][col] = "#") + cycle += 1 + end + + println(join([join(x, "") for x in crt], "\n")) +end + function part_2(input) - nothing + cpu = run_instructions(input) + draw_crt(interp_x(cpu)[1:240]) end -@info part_2(input) +println("Example:") +part_2(example) +println("Puzzle:") +part_2(input)