2019-12-10 14:59:21 +01:00
use std ::collections ::HashSet ;
2019-12-10 19:59:52 +01:00
use std ::io ::{ self , BufRead } ;
2019-12-10 14:59:21 +01:00
2019-12-10 19:59:52 +01:00
#[ derive(Clone) ]
struct Asteroid {
x : i64 ,
y : i64 ,
visible_asteroids : HashSet < i64 > ,
2019-12-10 08:05:30 +01:00
}
2019-12-10 11:45:56 +01:00
2019-12-10 19:59:52 +01:00
impl Asteroid {
pub fn new ( x : usize , y : usize ) -> Self {
Self {
x : x as i64 ,
y : y as i64 ,
visible_asteroids : HashSet ::new ( ) ,
}
}
fn compute_visibles ( mut self , all_asteroids : & Vec < Asteroid > ) -> Self {
// Technically incorrect because we add ourself here, but since the asteroid with most
// visibles has some legitimate asteroid at an angle of 0°, this doesn’t actually matter.
for ast in all_asteroids {
self . visible_asteroids
. insert ( calculate_angle ( self . x - ast . x , self . y - ast . y ) ) ;
}
self
}
2019-12-10 11:45:56 +01:00
}
2019-12-10 19:59:52 +01:00
fn main ( ) {
let input : Vec < Asteroid > = io ::stdin ( )
. lock ( )
. lines ( )
. enumerate ( )
. flat_map ( | ( y , l ) | {
l . unwrap ( )
. chars ( )
. enumerate ( )
. filter ( | ( _ , c ) | c = = & '#' )
. map ( move | ( x , _ ) | Asteroid ::new ( x , y ) )
. collect ::< Vec < _ > > ( )
} )
. collect ( ) ;
let part1 = input
. clone ( )
. into_iter ( )
. map ( | ast | ast . compute_visibles ( & input ) )
. max_by_key ( | ast | ast . visible_asteroids . len ( ) )
. unwrap ( ) ;
println! ( " Part 1: {} " , part1 . visible_asteroids . len ( ) ) ;
2019-12-10 14:59:21 +01:00
}
2019-12-10 19:59:52 +01:00
fn calculate_angle ( x_offset : i64 , y_offset : i64 ) -> i64 {
return ( ( y_offset as f64 ) . atan2 ( x_offset as f64 ) . to_degrees ( ) * 1000.0 ) . round ( ) as i64 ;
2019-12-10 14:59:21 +01:00
}
2019-12-10 19:59:52 +01:00
//fn part1(asteroids: &HashSet<(i32, i32)>) -> Asteroid {
//unimplemented!()
//}
2019-12-10 11:45:56 +01:00
#[ cfg(test) ]
mod tests {
use super ::* ;
#[ test ]
fn test_angle_calculation ( ) {
2019-12-10 19:59:52 +01:00
assert_eq! ( calculate_angle ( 1 , 1 ) , 45_000 ) ;
assert_eq! ( calculate_angle ( 1 , 0 ) , 0 ) ;
assert_eq! ( calculate_angle ( 0 , - 1 ) , - 90_000 ) ;
assert_eq! ( calculate_angle ( 2 , 1 ) , 26_565 ) ;
2019-12-10 11:45:56 +01:00
assert_eq! ( calculate_angle ( 1 , 1 ) , calculate_angle ( 3 , 3 ) ) ;
2019-12-10 19:59:52 +01:00
assert_eq! ( calculate_angle ( - 2 , - 2 ) , - 135_000 ) ;
assert_eq! ( calculate_angle ( - 2 , 2 ) , 135_000 ) ;
2019-12-10 11:45:56 +01:00
assert_ne! ( calculate_angle ( 1 , 1 ) , calculate_angle ( 3 , - 3 ) ) ;
}
2019-12-10 14:59:21 +01:00
2019-12-10 19:59:52 +01:00
/*
#[ test ]
fn test_part_1 ( ) {
assert_eq! (
part1 ( & parse_input (
" .#..#
.. .. .
#####
.. .. #
.. . ##"
. lines ( )
) ) . visible_asteroids ,
HashSet ::new ( )
) ;
2019-12-10 14:59:21 +01:00
2019-12-10 19:59:52 +01:00
assert_eq! (
part1 ( & parse_input (
" #.#...#.#.
. ###.. .. #.
. #.. .. #.. .
##. #. #. #. #
.. .. #. #. #.
. ##.. ###. #
.. #.. . ##..
.. ##.. .. ##
.. .. .. #.. .
. ####. ###. "
. lines ( )
) ) ,
( 1 , 2 )
) ;
assert_eq! (
part1 ( & parse_input (
" .#..#..###
####. ###. #
.. .. ###. #.
.. ###. ##. #
##. ##. #. #.
.. .. ###.. #
.. #. #.. #. #
#.. #. #. ###
. ##.. . ##. #
.. .. . #. #.. "
. lines ( )
) ) ,
( 6 , 3 )
) ;
assert_eq! (
part1 ( & parse_input (
" ......#.#.
#.. #. #.. ..
.. #######.
. #. #. ###..
. #.. #.. .. .
.. #.. .. #. #
#.. #.. .. #.
. ##. #.. ###
##.. . #.. #.
. #.. .. ####"
. lines ( )
) ) ,
( 5 , 8 )
) ;
assert_eq! (
part1 ( & parse_input (
" .#..##.###...#######
##. ############.. ##.
. #. ######. ########. #
. ###. #######. ####. #.
#####. ##. #. ##. ###. ##
.. #####.. #. #########
####################
#. ####.. .. ###. #. #. ##
##. #################
#####. ##. ###.. ####..
.. ######.. ##. #######
####. ##. ####.. . ##.. #
. #####.. #. ######. ###
##.. . #. ##########.. .
#. ##########. #######
. ####. #. ###. ###. #. ##
.. .. ##. ##. ###.. #####
. #. #. ###########. ###
#. #. #. #####. ####. ###
###. ##. ####. ##. #.. ##"
. lines ( )
) ) ,
( 11 , 13 )
) ;
}
* /
2019-12-10 11:45:56 +01:00
}