advent-of-code

Perserverance, or the lack thereof

git clone git://git.shimmy1996.com/advent-of-code.git

day-17.jl (5656B)

    1 function computer_step!(program, pc, relative_base, input)
    2     # Runs from given pc until completion or next request for input.
    3     # Modifies program and pc.
    4     # Returns if the program has terminated and the output.
    5     output = []
    6     function get_param(loc, mode)
    7         # Loc is gauranteed to exist.
    8         if mode == 0
    9             # Position mode.
   10             get(program, program[loc] + 1, 0)
   11         elseif mode == 1
   12             # Immediate mode.
   13             program[loc]
   14         else
   15             # Relative mode.
   16             get(program, relative_base + program[loc] + 1, 0)
   17         end
   18     end
   19     function get_res_loc(loc, mode)
   20         # Loc is gauranteed to exist.
   21         if mode == 0
   22             # Position mode.
   23             program[loc] + 1
   24         else
   25             # Relative mode.
   26             relative_base + program[loc] + 1
   27         end
   28     end
   29     while true
   30         op_code = program[pc] % 100
   31         mode_1 = (program[pc] % 1000) ÷ 100
   32         mode_2 = (program[pc] % 10000) ÷ 1000
   33         mode_3 = (program[pc] % 100000) ÷ 10000
   34         if op_code == 1
   35             program[get_res_loc(pc + 3, mode_3)] = (
   36                 get_param(pc + 1, mode_1)
   37                 + get_param(pc + 2, mode_2)
   38             )
   39             pc += 4
   40         elseif op_code == 2
   41             program[get_res_loc(pc + 3, mode_3)] = (
   42                 get_param(pc + 1, mode_1)
   43                 * get_param(pc + 2, mode_2)
   44             )
   45             pc += 4
   46         elseif op_code == 3
   47             if !isnothing(input)
   48                 program[get_res_loc(pc + 1, mode_1)] = input
   49                 input = nothing
   50             else
   51                 return (pc, relative_base, false, output)
   52             end
   53             pc += 2
   54         elseif op_code == 4
   55             push!(output, get_param(pc + 1, mode_1))
   56             pc += 2
   57         elseif op_code == 5
   58             if get_param(pc + 1, mode_1) != 0
   59                 pc = get_param(pc + 2, mode_2) + 1
   60             else
   61                 pc += 3
   62             end
   63         elseif op_code == 6
   64             if get_param(pc + 1, mode_1) == 0
   65                 pc = get_param(pc + 2, mode_2) + 1
   66             else
   67                 pc += 3
   68             end
   69         elseif op_code == 7
   70             program[get_res_loc(pc + 3, mode_3)] = (
   71                 get_param(pc + 1, mode_1)
   72                 < get_param(pc + 2, mode_2)
   73             ) ? 1 : 0
   74             pc += 4
   75         elseif op_code == 8
   76             program[get_res_loc(pc + 3, mode_3)] = (
   77                 get_param(pc + 1, mode_1)
   78                 == get_param(pc + 2, mode_2)
   79             ) ? 1 : 0
   80             pc += 4
   81         elseif op_code == 9
   82             relative_base += get_param(pc + 1, mode_1)
   83             pc += 2
   84         elseif op_code == 99
   85             break
   86         else
   87             println("Unknown op code: ", op_code)
   88             break
   89         end
   90     end
   91     (pc, relative_base, true, output)
   92 end
   93 
   94 function get_view(input)
   95     # Get view of the scaffoldings.
   96     program = Dict(enumerate(copy(input)))
   97     # Set program state.
   98     pc = 1
   99     relative_base = 0
  100     _, _, _, output = computer_step!(
  101         program, pc, relative_base, nothing
  102     )
  103     # Split output into vector of vector.
  104     width = findfirst(output .== 10)
  105     chart = []
  106     for i in 1:size(output, 1)
  107         # No need to include the new lines at the end.
  108         if output[i] != 10
  109             row = i ÷ width + 1
  110             if size(chart, 1) < row
  111                 push!(chart, [])
  112             end
  113             push!(chart[row], Char(output[i]))
  114         end
  115     end
  116     chart
  117 end
  118 
  119 function print_view(view)
  120     for row in view
  121         for px in row
  122             print(px)
  123         end
  124         println()
  125     end
  126 end
  127 
  128 function calc_alignment_parameter(view)
  129     width = size(view[1], 1)
  130     height = size(view, 1)
  131     alignment_param = 0
  132     # Current coordinate.
  133     # No intersection can occur on the borders.
  134     for x in 2:(width - 1)
  135         for y in 2:(height - 1)
  136             # Check for intersection.
  137             # All 5 squares should be scaffolding.
  138             if (view[y][x] != '.'
  139                 && view[y][x + 1] != '.'
  140                 && view[y][x - 1] != '.'
  141                 && view[y + 1][x] != '.'
  142                 && view[y - 1][x] != '.')
  143                 alignment_param += (x - 1) * (y - 1)
  144             end
  145         end
  146     end
  147     alignment_param
  148 end
  149 
  150 function collect_dust(input, main_routine, func_a, func_b, func_c)
  151      # Get view of the scaffoldings.
  152     program = Dict(enumerate(copy(input)))
  153     # Enable movements.
  154     program[1] = 2
  155     # Set program state.
  156     pc = 1
  157     relative_base = 0
  158     # Assemble commands.
  159     commands = map(
  160         ch -> Int(ch),
  161         collect(
  162             main_routine
  163             * func_a
  164             * func_b
  165             * func_c
  166             * "n\n" # No video feeds.
  167         )
  168     )
  169     # Collect output.
  170     output = []
  171     # Run program.
  172     while true
  173         pc, relative_base, finished, step_output = computer_step!(
  174             program, pc, relative_base, popfirst!(commands)
  175         )
  176         append!(output, step_output)
  177         if finished
  178             break
  179         end
  180     end
  181     output[end]
  182 end
  183 
  184 function part_1(input)
  185     view = get_view(input)
  186     print_view(view)
  187     calc_alignment_parameter(view)
  188 end
  189 
  190 function part_2(input)
  191     main_routine = "A,B,A,B,C,A,B,C,A,C\n"
  192     func_a = "R,6,L,6,L,10\n"
  193     func_b = "L,8,L,6,L,10,L,6\n"
  194     func_c = "R,6,L,8,L,10,R,6\n"
  195     collect_dust(input, main_routine, func_a, func_b, func_c)
  196 end
  197 
  198 input = map(x -> parse(Int128, x), split(readlines(open("input.txt"))[1], ','))
  199 
  200 println("Julia:")
  201 println("Part 1: ", part_1(input))
  202 println("Part 2: ", part_2(input))