summaryrefslogtreecommitdiffstats
path: root/day10/src/main.rs
diff options
context:
space:
mode:
authorJan Tuomi <jan.tuomi@eficode.com>2018-12-10 18:32:09 +0200
committerJan Tuomi <jan.tuomi@eficode.com>2018-12-10 18:32:09 +0200
commit49230f87d81c21f11c6d227109b7b9eaee52608f (patch)
treeb10589341472bcab4d428943878733d70bdebf4e /day10/src/main.rs
parentb8e9c88da10835a32c82891c93023eb6eda952ed (diff)
Solve day10
Diffstat (limited to 'day10/src/main.rs')
-rw-r--r--day10/src/main.rs121
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