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, bb: &BoundingBox) { let mut grid: Vec> = 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, time: i64) -> Vec { 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) -> 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 = 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 = file.lines() .map(|line| line.expect("Could not parse line.")) .collect(); let mut init_points: Vec = 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; } }