commit d8e9c1709f622035b21e8f41edbd088487bb904d
parent 6d129d2f5129e367ec3fa6c38be9435284a8b46a
Author: 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)