2019-12-11 19:28:40 +01:00
use intcode ::* ;
2019-12-13 13:40:32 +01:00
use grid ::* ;
2019-12-11 19:28:40 +01:00
use std ::collections ::HashMap ;
enum Direction {
Up ,
Down ,
Left ,
Right ,
}
2019-12-11 20:09:22 +01:00
struct Robot {
direction : Direction ,
2019-12-13 13:40:32 +01:00
position : Position2D ,
visited : HashMap < Position2D , i64 > ,
2019-12-11 19:28:40 +01:00
}
2019-12-11 20:09:22 +01:00
impl Robot {
fn turn ( & mut self , turn_value : i64 ) {
self . direction = match turn_value {
0 = > match self . direction {
Direction ::Up = > Direction ::Left ,
Direction ::Right = > Direction ::Up ,
Direction ::Down = > Direction ::Right ,
Direction ::Left = > Direction ::Down ,
} ,
1 = > match self . direction {
Direction ::Up = > Direction ::Right ,
Direction ::Right = > Direction ::Down ,
Direction ::Down = > Direction ::Left ,
Direction ::Left = > Direction ::Up ,
} ,
_ = > unreachable! ( " Illegal turn value " ) ,
}
}
fn mv ( & mut self ) {
let pos = self . position ;
self . position = match self . direction {
2019-12-13 13:40:32 +01:00
Direction ::Up = > pos + ( 0 , 1 ) . into ( ) ,
Direction ::Right = > pos + ( 1 , 0 ) . into ( ) ,
Direction ::Left = > pos + ( - 1 , 0 ) . into ( ) ,
Direction ::Down = > pos + ( 0 , - 1 ) . into ( ) ,
2019-12-11 20:09:22 +01:00
}
}
fn paint ( & mut self , color : i64 ) {
self . visited . insert ( self . position , color ) ;
}
fn current_color ( & self ) -> i64 {
* self . visited . get ( & self . position ) . unwrap_or ( & 0 )
2019-12-11 19:28:40 +01:00
}
}
2019-12-11 20:09:22 +01:00
fn start_with_input ( input : Vec < i64 > , color : i64 ) -> Robot {
let mut robot = Robot {
2019-12-13 13:40:32 +01:00
position : ( 0 , 0 ) . into ( ) ,
2019-12-11 20:09:22 +01:00
visited : HashMap ::new ( ) ,
direction : Direction ::Up ,
} ;
let mut pc = IntComputer ::new ( input , 0 , vec! [ color ] ) ;
2019-12-11 19:28:40 +01:00
while let IntComputerResult ::Output ( o ) = pc . run ( ) {
2019-12-11 20:09:22 +01:00
robot . paint ( o ) ;
2019-12-11 19:28:40 +01:00
let turn_int = pc . run ( ) . unwrap ( ) ;
2019-12-11 20:09:22 +01:00
robot . turn ( turn_int ) ;
robot . mv ( ) ;
pc . params . push ( robot . current_color ( ) ) ;
2019-12-11 19:28:40 +01:00
}
2019-12-11 20:09:22 +01:00
robot
}
fn main ( ) {
let input = read_input ( ) ;
let part1_robot = start_with_input ( input . clone ( ) , 0 ) ;
println! ( " Part 1: {} " , part1_robot . visited . len ( ) ) ;
2019-12-13 15:08:52 +01:00
let part2_robot = start_with_input ( input , 1 ) ;
2019-12-13 13:40:32 +01:00
println! ( " Part 2: \n {} " , draw_ascii ( & part2_robot . visited , 0 ) . replace ( '0' , " " ) . replace ( '1' , " • " ) ) ;
2019-12-11 19:28:40 +01:00
}