Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- extern crate chrono;
- extern crate regex;
- use std::collections::HashMap;
- use std::fs;
- use std::ops::Not;
- use regex::Regex;
- use chrono::DateTime;
- use chrono::offset::Utc;
- struct Point {
- position: (i64, i64),
- velocity: (i16, i16),
- }
- impl Point {
- fn apply_velocity(&mut self) {
- let Self { position, velocity } = self;
- position.0 += velocity.0 as i64;
- position.1 += velocity.1 as i64;
- }
- }
- fn fmt_secs(start: DateTime<Utc>) -> String {
- format!("⏱ {}s", (Utc::now() - start).num_milliseconds() as f64 / 1000_f64)
- }
- fn main() {
- const INPUT: &str = include_str!("../../input");
- // const INPUT: &str = "position=< 9, 1> velocity=< 0, 2>
- // position=< 7, 0> velocity=<-1, 0>
- // position=< 3, -2> velocity=<-1, 1>
- // position=< 6, 10> velocity=<-2, -1>
- // position=< 2, -4> velocity=< 2, 2>
- // position=<-6, 10> velocity=< 2, -2>
- // position=< 1, 8> velocity=< 1, -1>
- // position=< 1, 7> velocity=< 1, 0>
- // position=<-3, 11> velocity=< 1, -2>
- // position=< 7, 6> velocity=<-1, -1>
- // position=<-2, 3> velocity=< 1, 0>
- // position=<-4, 3> velocity=< 2, 0>
- // position=<10, -3> velocity=<-1, 1>
- // position=< 5, 11> velocity=< 1, -2>
- // position=< 4, 7> velocity=< 0, -1>
- // position=< 8, -2> velocity=< 0, 1>
- // position=<15, 0> velocity=<-2, 0>
- // position=< 1, 6> velocity=< 1, 0>
- // position=< 8, 9> velocity=< 0, -1>
- // position=< 3, 3> velocity=<-1, 1>
- // position=< 0, 5> velocity=< 0, -1>
- // position=<-2, 2> velocity=< 2, 0>
- // position=< 5, -2> velocity=< 1, 2>
- // position=< 1, 4> velocity=< 2, 1>
- // position=<-2, 7> velocity=< 2, -2>
- // position=< 3, 6> velocity=<-1, -1>
- // position=< 5, 0> velocity=< 1, 0>
- // position=<-6, 0> velocity=< 2, 0>
- // position=< 5, 9> velocity=< 1, -2>
- // position=<14, 7> velocity=<-2, 0>
- // position=<-3, 6> velocity=< 2, -1>";
- let time = Utc::now();
- let re = Regex::new(r"-?\d+").unwrap();
- let points: Vec<Point> = INPUT
- .trim()
- .lines()
- .map(|line| {
- if let &[x, y, dx, dy] = &re
- .find_iter(line)
- .map(|mat| mat.as_str().parse::<i64>().unwrap())
- .collect::<Vec<i64>>()[..] {
- Point {
- position: (x, y),
- velocity: (dx as i16, dy as i16),
- }
- } else { panic!(); }
- })
- .collect();
- println!("Prep: {}", fmt_secs(time));
- let time = Utc::now();
- part1(points);
- println!("Part 1 {}", fmt_secs(time));
- }
- fn part1(mut points: Vec<Point>) {
- let x_values: Vec<i64> = points
- .iter()
- .map(|&Point { position: (x, _), .. }| x)
- .collect();
- let y_values: Vec<i64> = points
- .iter()
- .map(|&Point { position: (_, y), .. }| y)
- .collect();
- let top_left = (
- *x_values.iter().min().unwrap(),
- *y_values.iter().min().unwrap(),
- );
- let bottom_right = (
- *x_values.iter().max().unwrap(),
- *y_values.iter().max().unwrap(),
- );
- for sec in 0.. {
- if is_message(&points) {
- print_grid(sec, &points, top_left, bottom_right);
- break;
- }
- for point in &mut points { point.apply_velocity(); }
- }
- }
- fn is_message(points: &Vec<Point>) -> bool {
- const TOO_MANY_LONELY_POINTS: usize = 1000;
- // Check how many points are not surrounded by points on any side
- points
- .iter()
- .filter(|Point { position: pos, .. }|
- [
- (pos.0, pos.1 - 1),
- (pos.0 - 1, pos.1), (pos.0 + 1, pos.1),
- (pos.0, pos.1 + 1),
- ]
- .into_iter()
- .any(|p| points.iter().any(|Point { position, .. }| position == p))
- .not())
- .count() < TOO_MANY_LONELY_POINTS
- }
- fn print_grid(sec: u32, points: &Vec<Point>, top_left: (i64, i64), bottom_right: (i64, i64)) {
- let grid: HashMap<(i64, i64), char> = points
- .into_iter()
- .map(|&Point { position, .. }| (
- position,
- '#',
- ))
- .collect();
- let dot = &'.';
- let mut out = "".to_string();
- out += &format!("After {} second(s):\n", sec);
- for y in top_left.1 ..= bottom_right.1 {
- for x in top_left.0 ..= bottom_right.0 {
- out += &format!("{}", grid.get(&(x, y)).unwrap_or(dot));
- }
- out += "\n";
- }
- out += "\n";
- fs::write("../out.txt", out).expect("unable to write file");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement