advent_of_code_2022

My (attempted) solutions to the 2022 Advent of Code
git clone https://git.eamoncaddigan.net/advent_of_code_2022.git
Log | Files | Refs | README

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)