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