diff options
Diffstat (limited to 'day10/src/main.rs')
| -rw-r--r-- | day10/src/main.rs | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/day10/src/main.rs b/day10/src/main.rs new file mode 100644 index 0000000..8674c8f --- /dev/null +++ b/day10/src/main.rs @@ -0,0 +1,121 @@ +use std::env; +use std::io::BufReader; +use std::io::BufRead; +use std::fs::File; +use std::process; +use std::io::{stdin,stdout,Write}; + +#[macro_use] extern crate text_io; + +struct Point { + x: i64, + y: i64, + vx: i64, + vy: i64 +} + +struct BoundingBox { + x: i64, + y: i64, + w: i64, + h: i64 +} + +static WIDTH: i64 = 200; +static HEIGHT: i64 = 20; + +fn visualize(points: &Vec<Point>, bb: &BoundingBox) { + let mut grid: Vec<Vec<char>> = vec![vec!['.'; bb.w as usize]; bb.h as usize]; + for point in points { + let (xi, yi) = transform(point, bb); + grid[yi][xi] = '#'; + } + + for row in &grid { + for elem in row { + print!("{}", elem); + } + print!("\n"); + } +} + +fn state(points: &Vec<Point>, time: i64) -> Vec<Point> { + points.iter().map(|p| Point { + x: p.x + time * p.vx, + y: p.y + time * p.vy, + vx: p.vx, + vy: p.vy + }).collect() +} + +fn transform(point: &Point, bb: &BoundingBox) -> (usize, usize) { + let x = point.x - bb.x; + let y = point.y - bb.y; + + (x as usize, y as usize) +} + +fn calc_bounding_box(points: &Vec<Point>) -> BoundingBox { + let px_min = points.iter().min_by(|&a, &b| a.x.cmp(&b.x)).unwrap().x; + let px_max = points.iter().max_by(|&a, &b| a.x.cmp(&b.x)).unwrap().x; + let py_min = points.iter().min_by(|&a, &b| a.y.cmp(&b.y)).unwrap().y; + let py_max = points.iter().max_by(|&a, &b| a.y.cmp(&b.y)).unwrap().y; + + let pw = px_max - px_min + 1; + let ph = py_max - py_min + 1; + + let bb = BoundingBox { + x: px_min, + y: py_min, + w: pw, + h: ph + }; + + bb +} + +fn main() { + let args: Vec<String> = env::args().collect(); + if args.len() != 2 { + println!("Wrong number of arguments. Provide a file name and worker count."); + process::exit(1); + } + let filename = &args[1]; + + println!("Using file {} as input.", filename); + let f = match File::open(filename) { + Ok(file) => file, + Err(e) => { + println!("Failed to open file {}. {:?}", filename, e); + process::exit(1); + } + }; + let file = BufReader::new(&f); + let lines: Vec<String> = file.lines() + .map(|line| line.expect("Could not parse line.")) + .collect(); + + let mut init_points: Vec<Point> = Vec::new(); + for line in &lines { + let ln = line + .replace("< ", "<") + .replace(" ", " "); + let (x, y): (i64, i64); + let (vx, vy): (i64, i64); + scan!(ln.bytes() => "position=<{}, {}> velocity=<{}, {}>", x, y, vx, vy); + init_points.push(Point { x, y, vx, vy }); + } + + let mut time = 0; + let step = 1; + // println!("Time: {} s, step: {} s", time, step); + while time < 20000 { + let points = state(&init_points, time); + let bb = calc_bounding_box(&points); + if bb.w <= WIDTH && bb.h <= HEIGHT { + println!("Time: {} s", time); + visualize(&points, &bb); + } + time += step; + } +}
\ No newline at end of file |
