2019-12-13 13:40:32 +01:00
use grid ::* ;
2019-12-15 11:49:30 +01:00
use intcode ::* ;
2019-12-11 19:28:40 +01:00
use std ::collections ::HashMap ;
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 {
2019-12-15 11:49:30 +01:00
fn mov ( & mut self ) {
2019-12-15 12:36:46 +01:00
self . position + = self . direction ;
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-15 12:00:28 +01:00
robot . direction . turn ( turn_int * 2 - 1 ) ;
2019-12-15 11:49:30 +01:00
robot . mov ( ) ;
2019-12-11 20:09:22 +01:00
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-15 11:49:30 +01:00
println! (
" Part 2: \n {} " ,
draw_ascii ( & part2_robot . visited , 0 )
. replace ( '0' , " " )
. replace ( '1' , " • " )
) ;
2019-12-11 19:28:40 +01:00
}