commit 05075a757a7f27700d84013b99dc169e60ee5ae9
parent f8360d8b6dc3d70a9cad23d1f07d665b320c0f4d
Author: Shimmy Xu <shimmy.xu@shimmy1996.com>
Date: Wed, 11 Dec 2019 09:56:20 -0500
Add Julia solution for day 11
Diffstat:
A | day-11/day-11.jl | | | 213 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 213 insertions(+), 0 deletions(-)
diff --git a/day-11/day-11.jl b/day-11/day-11.jl
@@ -0,0 +1,213 @@
+function turn_left(dir)
+ if dir == (0, 1)
+ (-1, 0)
+ elseif dir == (1, 0)
+ (0, 1)
+ elseif dir == (0, -1)
+ (1, 0)
+ elseif dir == (-1, 0)
+ (0, -1)
+ else
+ print("Invalid direction.")
+ end
+end
+
+function turn_right(dir)
+ if dir == (0, 1)
+ (1, 0)
+ elseif dir == (1, 0)
+ (0, -1)
+ elseif dir == (0, -1)
+ (-1, 0)
+ elseif dir == (-1, 0)
+ (0, 1)
+ else
+ print("Invalid direction.")
+ end
+end
+
+function robot!(program, panels)
+ program = Dict(enumerate(copy(program)))
+ pc = 1
+ relative_base = 0
+ coord = (0, 0)
+ # Initially facing north.
+ dir = (0, 1)
+ while true
+ # Get color for current panel. Panels start black (0).
+ # This records only panels the robot has stepped on.
+ color = get!(panels, coord, 0)
+ pc, relative_base, finished, step_output = computer_step!(
+ program, pc, relative_base,
+ color
+ )
+ # First instruction is color to paint the panel to.
+ panels[coord] = step_output[1]
+ # Second instruction is direction to turn the robot.
+ if step_output[2] == 0
+ dir = turn_left(dir)
+ else
+ dir = turn_right(dir)
+ end
+ # Move robot forward by one panel.
+ coord = (coord[1] + dir[1], coord[2] + dir[2])
+ if finished
+ break
+ end
+ end
+end
+
+
+function computer(program, input)
+ program = Dict(enumerate(copy(program)))
+ input = copy(input)
+ output = []
+ pc = 1
+ relative_base = 0
+ while true
+ pc, relative_base, finished, step_output = computer_step!(
+ program, pc, relative_base,
+ isempty(input) ? nothing : popfirst!(input)
+ )
+ append!(output, step_output)
+ if finished
+ break
+ end
+ end
+ output
+end
+
+function computer_step!(program, pc, relative_base, input)
+ # Runs from given pc until completion or next request for input.
+ # Modifies program and pc.
+ # Returns if the program has terminated and the output.
+ output = []
+ function get_param(loc, mode)
+ # Loc is gauranteed to exist.
+ if mode == 0
+ # Position mode.
+ get(program, program[loc] + 1, 0)
+ elseif mode == 1
+ # Immediate mode.
+ program[loc]
+ else
+ # Relative mode.
+ get(program, relative_base + program[loc] + 1, 0)
+ end
+ end
+ function get_res_loc(loc, mode)
+ # Loc is gauranteed to exist.
+ if mode == 0
+ # Position mode.
+ program[loc] + 1
+ else
+ # Relative mode.
+ relative_base + program[loc] + 1
+ end
+ end
+ while true
+ op_code = program[pc] % 100
+ mode_1 = (program[pc] % 1000) ÷ 100
+ mode_2 = (program[pc] % 10000) ÷ 1000
+ mode_3 = (program[pc] % 100000) ÷ 10000
+ if op_code == 1
+ program[get_res_loc(pc + 3, mode_3)] = (
+ get_param(pc + 1, mode_1)
+ + get_param(pc + 2, mode_2)
+ )
+ pc += 4
+ elseif op_code == 2
+ program[get_res_loc(pc + 3, mode_3)] = (
+ get_param(pc + 1, mode_1)
+ * get_param(pc + 2, mode_2)
+ )
+ pc += 4
+ elseif op_code == 3
+ if !isnothing(input)
+ program[get_res_loc(pc + 1, mode_1)] = input
+ input = nothing
+ else
+ return (pc, relative_base, false, output)
+ end
+ pc += 2
+ elseif op_code == 4
+ push!(output, get_param(pc + 1, mode_1))
+ pc += 2
+ elseif op_code == 5
+ if get_param(pc + 1, mode_1) != 0
+ pc = get_param(pc + 2, mode_2) + 1
+ else
+ pc += 3
+ end
+ elseif op_code == 6
+ if get_param(pc + 1, mode_1) == 0
+ pc = get_param(pc + 2, mode_2) + 1
+ else
+ pc += 3
+ end
+ elseif op_code == 7
+ program[get_res_loc(pc + 3, mode_3)] = (
+ get_param(pc + 1, mode_1)
+ < get_param(pc + 2, mode_2)
+ ) ? 1 : 0
+ pc += 4
+ elseif op_code == 8
+ program[get_res_loc(pc + 3, mode_3)] = (
+ get_param(pc + 1, mode_1)
+ == get_param(pc + 2, mode_2)
+ ) ? 1 : 0
+ pc += 4
+ elseif op_code == 9
+ relative_base += get_param(pc + 1, mode_1)
+ pc += 2
+ elseif op_code == 99
+ break
+ else
+ println("Unknown op code: ", op_code)
+ break
+ end
+ end
+ (pc, relative_base, true, output)
+end
+
+function part_1(input)
+ panels = Dict()
+ robot!(input, panels)
+ length(panels)
+end
+
+function part_2(input)
+ # Set initial panel white.
+ panels = Dict([(0, 0) => 1])
+ robot!(input, panels)
+ # Display the panel results.
+ # Check max/min coordinates.
+ min_x = Inf
+ max_x = -Inf
+ min_y = Inf
+ max_y = -Inf
+ for panel in keys(panels)
+ min_x = min(min_x, panel[1])
+ max_x = max(max_x, panel[1])
+ min_y = min(min_y, panel[2])
+ max_y = max(max_y, panel[2])
+ end
+ # Print the panels.
+ for y in reverse(min_y:max_y)
+ for x in min_x:max_x
+ if get(panels, (x, y), 0) == 1
+ print("██")
+ else
+ print(" ")
+ end
+ end
+ println()
+ end
+end
+
+input = map(x -> parse(Int128, x), split(readlines(open("input.txt"))[1], ','))
+
+println("Julia:")
+println("Part 1: ", part_1(input))
+println("Part 2: ")
+part_2(input)