diff --git a/day9/day9.jl b/day9/day9.jl index 449d995..e39ce5c 100644 --- a/day9/day9.jl +++ b/day9/day9.jl @@ -7,7 +7,7 @@ struct Move count :: Int end -mutable struct State +mutable struct KnotPair head_x :: Int head_y :: Int tail_x :: Int @@ -19,6 +19,14 @@ function parse_move(line) return Move(parts[1][1], parse(Int, parts[2])) end + +function state_changed(old_state, new_state) + return (new_state.head_x != old_state.head_x + || new_state.head_y != old_state.head_y + || new_state.tail_x != old_state.tail_x + || new_state.tail_y != old_state.tail_y) +end + function read_moves(io) return [parse_move(line) for line in readlines(io)] end @@ -32,6 +40,8 @@ function apply_move(state, direction) state.head_x -= 1 elseif direction == 'R' state.head_x += 1 + elseif direction != 'O' + throw(DomainError("Unknown direction")) end x_diff = state.head_x - state.tail_x y_diff = state.head_y - state.tail_y @@ -44,20 +54,36 @@ function apply_move(state, direction) elseif abs(y_diff) <= 1 state.tail_y += y_diff state.tail_x += sign(x_diff) * (abs(x_diff) - 1) + elseif abs(x_diff) == 2 && abs(y_diff) == 2 + # possible with more than 2 knots + state.tail_x += sign(x_diff) * (abs(x_diff) - 1) + state.tail_y += sign(y_diff) * (abs(y_diff) - 1) else - throw(DomainError("invalid state")) + throw(DomainError("invalid state " * string(state))) end return state end -function get_visited(moves) +function get_visited(moves; npairs::Int=1) visited = Set{NTuple{2, Int}}() - state = State(0, 0, 0, 0) - push!(visited, (state.tail_x, state.tail_y)) + states = [KnotPair(0, 0, 0, 0) for _ in 1:npairs] + push!(visited, (states[npairs].tail_x, states[npairs].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)) + for m in 1:move.count + # println(move, " ", m) + # print(" 1 ", states[1], " -> ") + states[1] = apply_move(states[1], move.direction) + # println(states[1]) + for i in 2:npairs + states[i].head_x = states[i-1].tail_x + states[i].head_y = states[i-1].tail_y + # old_state = deepcopy(states[i]) + states[i] = apply_move(states[i], 'O') + # if state_changed(states[i], old_state) + # println(" ", i, " ", old_state, " -> ", states[i]) + # end + end + push!(visited, (states[npairs].tail_x, states[npairs].tail_y)) end end return visited @@ -76,10 +102,14 @@ function visited_map(visited) end function test() - @testset "visited count" verbose=true begin + @testset "visited count 2 knot" verbose=true begin @test length(get_visited(read_moves("example.txt"))) == 13 @test length(get_visited(read_moves("input.txt"))) == 6037 end + @testset "visited count 10 knot" verbose=true begin + @test length(get_visited(read_moves("example.txt"), npairs=9)) == 1 + @test length(get_visited(read_moves("input.txt"), npairs=9)) == 2485 + end end function main() @@ -95,6 +125,13 @@ function main() println("count : ", length(visited)) display(visited_map(visited)) println() + + visited10 = get_visited(moves, npairs=9) + println("visited10: ", visited10) + println("count10 : ", length(visited10)) + display(visited_map(visited10)) + println() + end end diff --git a/day9/example2.txt b/day9/example2.txt new file mode 100644 index 0000000..60bd43b --- /dev/null +++ b/day9/example2.txt @@ -0,0 +1,8 @@ +R 5 +U 8 +L 8 +D 3 +R 17 +D 10 +L 25 +U 20