day_9.jl (3180B)
1 #!/usr/bin/env julia 2 # https://adventofcode.com/2022/day/9 3 using AdventOfCode 4 5 example = readlines(IOBuffer(""" 6 R 4 7 U 4 8 L 3 9 D 1 10 R 4 11 D 1 12 L 5 13 R 2""")) 14 input = readlines("data/day_9.txt") 15 16 """ 17 Shift the head one left, right, up, or down as directed. 18 """ 19 function shift_head(head_position::Tuple{Int,Int}, 20 direction::Char) 21 offset = Dict( 22 'L' => (-1, 0), 23 'R' => (1, 0), 24 'U' => (0, 1), 25 'D' => (0, -1) 26 ) 27 head_position .+ offset[direction] 28 end 29 30 """ 31 Return true if the knots are touching, and the difference vector (as a tuple) 32 """ 33 function touching(head_position, tail_position) 34 diff_vec = head_position .- tail_position 35 (maximum(abs.(diff_vec)) <= 1, diff_vec) 36 end 37 38 """ 39 Shift the tail one step based on the difference vector 40 41 The tail can move up/down, left/right, or diagonally. It moves at most one step 42 (in either or both cardinal directions). 43 """ 44 function shift_tail(diff_vec, tail_position) 45 tail_position .+ sign.(diff_vec) 46 end 47 48 function move_knots(instructions, num_knots=2) 49 knot_positions = [(0, 0) for _ in 1:num_knots] 50 tail_visits = Set{Tuple{Int,Int}}([knot_positions[end]]) 51 52 for instruction = instructions 53 for _ in 1:parse(Int, instruction[3:end]) # Number of steps 54 knot_positions[1] = shift_head( 55 knot_positions[1], 56 instruction[1] 57 ) 58 59 for i = 2:lastindex(knot_positions) 60 aretouching, diff_vec = touching(knot_positions[i-1], 61 knot_positions[i]) 62 while !aretouching 63 knot_positions[i] = shift_tail(diff_vec, 64 knot_positions[i]) 65 66 if i == lastindex(knot_positions) 67 push!(tail_visits, knot_positions[i]) 68 end 69 70 aretouching, diff_vec = touching(knot_positions[i-1], 71 knot_positions[i]) 72 end 73 end 74 end # steps 75 end # instructions 76 77 tail_visits 78 end 79 80 function part_1(input) 81 length(move_knots(input)) 82 end 83 @assert part_1(example) == 13 84 @info part_1(input) 85 86 # Part 2 stuff below 87 88 example2 = readlines(IOBuffer(""" 89 R 5 90 U 8 91 L 8 92 D 3 93 R 17 94 D 10 95 L 25 96 U 20""")) 97 98 # Looks like I need help: my first attempt worked for the example but not the 99 # puzzle input (argh). So here's a helper function to draw the map 100 function draw_map(tail_visits) 101 tail_visits = [tup[k] for tup in tail_visits, k in 1:2] 102 tail_visits[:,1] .-= minimum(tail_visits[:,1]) - 1 103 tail_visits[:,2] .-= minimum(tail_visits[:,2]) - 1 104 105 tailmap = fill('.', 106 maximum(tail_visits[:,2]), 107 maximum(tail_visits[:,1])) 108 for coord = eachrow(tail_visits) 109 tailmap[coord[2], coord[1]] = '#' 110 end 111 112 println(join(reverse([join(x, "") for x in eachrow(tailmap)]), "\n")) 113 end 114 115 function part_2(input) 116 length(move_knots(input, 10)) 117 end 118 @assert part_2(example2) == 36 119 draw_map(move_knots(example2, 10)) 120 @info part_2(input)