Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #[macro_use] extern crate scan_fmt;
- use std::io::BufRead;
- #[derive(Debug)]
- struct Star {
- position: (i64, i64),
- velocity: (i64, i64)
- }
- fn integrate_step(stars: &mut [Star]) {
- for star in stars {
- star.position.0 += star.velocity.0;
- star.position.1 += star.velocity.1;
- }
- }
- fn undo_step(stars: &mut [Star]) {
- for star in stars {
- star.position.0 -= star.velocity.0;
- star.position.1 -= star.velocity.1;
- }
- }
- /// Returns (minx, miny), (maxx, maxy)
- fn bounding_box(stars: &[Star]) -> ((i64, i64), (i64, i64)){
- let minx = stars.iter().map(|s| s.position.0).min().unwrap();
- let miny = stars.iter().map(|s| s.position.1).min().unwrap();
- let maxx = stars.iter().map(|s| s.position.0).max().unwrap();
- let maxy = stars.iter().map(|s| s.position.1).max().unwrap();
- ((minx, miny), (maxx, maxy))
- }
- fn area(bounding_box: ((i64, i64), (i64, i64))) -> i64 {
- (bounding_box.0 .0 - bounding_box.1 .0) * (bounding_box.0 .1 - bounding_box.1 .1)
- }
- fn print_stars(stars: &[Star]) {
- let ((min_x, min_y), (max_x, max_y)) = bounding_box(stars);
- // Fill a buffer with the thing to print
- // buf[y][x] gives whether to print or not at (x, y). True means print.
- let mut buf = vec![vec![false; (max_x - min_x + 1) as usize]; (max_y - min_y + 1) as usize];
- for star in stars {
- buf[(star.position.1 - min_y) as usize][(star.position.0 - min_x) as usize] = true;
- }
- for line in buf {
- for val in line {
- if val {
- print!("#");
- } else {
- print!(" ");
- }
- }
- println!("");
- }
- }
- fn main() {
- let mut stars: Vec<Star> = std::io::stdin()
- .lock()
- .lines()
- .map(|line| {
- let (x, y, vx, vy) = scan_fmt!(
- &line.expect("Couldn't read input"),
- "position=<{}, {}> velocity=<{}, {}>",
- i64, i64, i64, i64);
- Star {
- position: (x.unwrap(), y.unwrap()),
- velocity: (vx.unwrap(), vy.unwrap())
- }
- }).collect();
- // Integrate until we hit minimum bounding box
- let mut previous_area = area(bounding_box(&stars));
- let mut number_seconds = 0;
- while previous_area >= area(bounding_box(&stars)) {
- previous_area = area(bounding_box(&stars));
- integrate_step(&mut stars);
- number_seconds += 1;
- }
- // Undo the last step to get to the minimum bounding box
- undo_step(&mut stars);
- number_seconds -= 1;
- println!("Message in the sky:");
- print_stars(&stars);
- println!("Waited {} seconds", number_seconds);
- }
Add Comment
Please, Sign In to add comment