parent
ba9b4b91d1
commit
93411e9cc5
@ -0,0 +1,101 @@
|
||||
#!/usr/bin/env julia
|
||||
|
||||
using Test
|
||||
|
||||
struct Move
|
||||
direction :: Char
|
||||
count :: Int
|
||||
end
|
||||
|
||||
mutable struct State
|
||||
head_x :: Int
|
||||
head_y :: Int
|
||||
tail_x :: Int
|
||||
tail_y :: Int
|
||||
end
|
||||
|
||||
function parse_move(line)
|
||||
parts = split(line, limit=2)
|
||||
return Move(parts[1][1], parse(Int, parts[2]))
|
||||
end
|
||||
|
||||
function read_moves(io)
|
||||
return [parse_move(line) for line in readlines(io)]
|
||||
end
|
||||
|
||||
function apply_move(state, direction)
|
||||
if direction == 'U'
|
||||
state.head_y += 1
|
||||
elseif direction == 'D'
|
||||
state.head_y -= 1
|
||||
elseif direction == 'L'
|
||||
state.head_x -= 1
|
||||
elseif direction == 'R'
|
||||
state.head_x += 1
|
||||
end
|
||||
x_diff = state.head_x - state.tail_x
|
||||
y_diff = state.head_y - state.tail_y
|
||||
if abs(x_diff) <= 1 && abs(y_diff) <= 1
|
||||
return state
|
||||
end
|
||||
if abs(x_diff) <= 1
|
||||
state.tail_x += x_diff
|
||||
state.tail_y += sign(y_diff) * (abs(y_diff) - 1)
|
||||
elseif abs(y_diff) <= 1
|
||||
state.tail_y += y_diff
|
||||
state.tail_x += sign(x_diff) * (abs(x_diff) - 1)
|
||||
else
|
||||
throw(DomainError("invalid state"))
|
||||
end
|
||||
return state
|
||||
end
|
||||
|
||||
function get_visited(moves)
|
||||
visited = Set{NTuple{2, Int}}()
|
||||
state = State(0, 0, 0, 0)
|
||||
push!(visited, (state.tail_x, state.tail_y))
|
||||
for move in moves
|
||||
for _ in 1:move.count
|
||||
state = apply_move(state, move.direction)
|
||||
push!(visited, (state.tail_x, state.tail_y))
|
||||
end
|
||||
end
|
||||
return visited
|
||||
end
|
||||
|
||||
function visited_map(visited)
|
||||
(min_x, max_x) = extrema([t[1] for t in visited])
|
||||
(min_y, max_y) = extrema([t[2] for t in visited])
|
||||
nrows = max_y - min_y + 1
|
||||
ncols = max_x - min_x + 1
|
||||
vmap = zeros(Int, nrows, ncols)
|
||||
for (x, y) in visited
|
||||
vmap[nrows - (y - min_y), (x - min_x + 1)] = 1
|
||||
end
|
||||
return vmap
|
||||
end
|
||||
|
||||
function test()
|
||||
@testset "visited count" verbose=true begin
|
||||
@test length(get_visited(read_moves("example.txt"))) == 13
|
||||
@test length(get_visited(read_moves("input.txt"))) == 6037
|
||||
end
|
||||
end
|
||||
|
||||
function main()
|
||||
if size(ARGS, 1) == 0
|
||||
test()
|
||||
else
|
||||
infile = ARGS[1]
|
||||
println("infile = ", infile)
|
||||
moves = read_moves(infile)
|
||||
println("moves: ", moves)
|
||||
visited = get_visited(moves)
|
||||
println("visited: ", visited)
|
||||
println("count : ", length(visited))
|
||||
display(visited_map(visited))
|
||||
println()
|
||||
end
|
||||
end
|
||||
|
||||
main()
|
||||
@ -0,0 +1,8 @@
|
||||
R 4
|
||||
U 4
|
||||
L 3
|
||||
D 1
|
||||
R 4
|
||||
D 1
|
||||
L 5
|
||||
R 2
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue