summaryrefslogtreecommitdiffstats
path: root/day6
diff options
context:
space:
mode:
Diffstat (limited to 'day6')
-rw-r--r--day6/.vscode/launch.json43
-rw-r--r--day6/Cargo.lock14
-rw-r--r--day6/Cargo.toml7
-rw-r--r--day6/src/main.rs183
4 files changed, 247 insertions, 0 deletions
diff --git a/day6/.vscode/launch.json b/day6/.vscode/launch.json
new file mode 100644
index 0000000..7013d5e
--- /dev/null
+++ b/day6/.vscode/launch.json
@@ -0,0 +1,43 @@
+{
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "type": "lldb",
+ "request": "launch",
+ "name": "Debug executable 'day6'",
+ "cargo": {
+ "args": [
+ "build",
+ "--bin=day6",
+ "--package=day6"
+ ],
+ "filter": {
+ "kind": "bin"
+ }
+ },
+ "args": ["input.txt"],
+ "cwd": "${workspaceFolder}"
+ },
+ {
+ "type": "lldb",
+ "request": "launch",
+ "name": "Debug unit tests in executable 'day6'",
+ "cargo": {
+ "args": [
+ "test",
+ "--no-run",
+ "--bin=day6",
+ "--package=day6"
+ ],
+ "filter": {
+ "kind": "bin"
+ }
+ },
+ "args": [],
+ "cwd": "${workspaceFolder}"
+ }
+ ]
+} \ No newline at end of file
diff --git a/day6/Cargo.lock b/day6/Cargo.lock
new file mode 100644
index 0000000..7b1ff1d
--- /dev/null
+++ b/day6/Cargo.lock
@@ -0,0 +1,14 @@
+[[package]]
+name = "day6"
+version = "0.1.0"
+dependencies = [
+ "text_io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "text_io"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[metadata]
+"checksum text_io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9658b61ebd1d2a40c276ba2335890b9eb6550b67458a6fbce2022e58c3350a50"
diff --git a/day6/Cargo.toml b/day6/Cargo.toml
new file mode 100644
index 0000000..0b3b5e0
--- /dev/null
+++ b/day6/Cargo.toml
@@ -0,0 +1,7 @@
+[package]
+name = "day6"
+version = "0.1.0"
+authors = ["Jan Tuomi <jan.tuomi@eficode.com>"]
+
+[dependencies]
+text_io = "0.1.7"
diff --git a/day6/src/main.rs b/day6/src/main.rs
new file mode 100644
index 0000000..de2a2b5
--- /dev/null
+++ b/day6/src/main.rs
@@ -0,0 +1,183 @@
+use std::env;
+use std::io::BufReader;
+use std::io::BufRead;
+use std::fs::File;
+use std::process;
+
+#[macro_use] extern crate text_io;
+
+struct BoundingBox {
+ left: u32,
+ top: u32,
+ right: u32,
+ bottom: u32
+}
+
+struct Coordinate {
+ x: u32,
+ y: u32
+}
+
+struct Point {
+ coordinate: Coordinate,
+ id: u32
+}
+
+fn distance(a: &Coordinate, b: &Coordinate) -> u32 {
+ let dx = (a.x as i32 - b.x as i32).abs();
+ let dy = (a.y as i32 - b.y as i32).abs();
+ (dx + dy) as u32
+}
+
+fn find_closest(c: &Coordinate, points: &Vec<Point>) -> Option<(u32, u32)> {
+ let mut shortest = std::u32::MAX;
+ let mut point_id: Option<u32> = None;
+ for point in points {
+ let dist = distance(&point.coordinate, c);
+ if dist < shortest {
+ shortest = dist;
+ point_id = Some(point.id);
+ } else if dist == shortest {
+ point_id = None;
+ }
+ }
+
+ match point_id {
+ Some(id) => Some((id, shortest)),
+ None => None
+ }
+}
+
+fn find_total_distance_to_points(c: &Coordinate, points: &Vec<Point>) -> u32 {
+ let mut total: u32 = 0;
+ for point in points {
+ let dist = distance(c, &point.coordinate);
+ total += dist;
+ }
+ total
+}
+
+fn draw_grid(grid: &Vec<Vec<Option<u32>>>, bb: &BoundingBox) {
+ let w = (bb.right - bb.left + 1) as usize;
+ let h = (bb.bottom - bb.top + 1) as usize;
+ for j in 0..h {
+ for i in 0..w {
+ let x = (i as u32 + bb.left) as u32;
+ let y = (j as u32 + bb.top) as u32;
+ let id_opt = grid[j][i];
+ match id_opt {
+ Some(id) => { print!("{}", id); }
+ None => { print!("."); }
+ }
+ }
+ print!("\n");
+ }
+}
+
+fn find_largest_area(grid: &Vec<Vec<Option<u32>>>, points: &Vec<Point>, bb: &BoundingBox) -> u32 {
+ let w = (bb.right - bb.left + 1) as usize;
+ let h = (bb.bottom - bb.top + 1) as usize;
+ let mut largest_area = 0;
+ for point in points {
+ let mut area = 0;
+ for j in 0..h {
+ for i in 0..w {
+ let id_opt = grid[j][i];
+ match id_opt {
+ Some(id) => {
+ if id == point.id {
+ area += 1;
+ }
+ }
+ None => {}
+ }
+ }
+ }
+
+ if area > largest_area {
+ largest_area = area;
+ }
+ }
+
+ largest_area
+}
+
+fn main() {
+ let args: Vec<String> = env::args().collect();
+ if args.len() != 2 {
+ println!("Wrong number of arguments. Provide just a file name.");
+ 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 points: Vec<Point> = Vec::new();
+ let mut bb: BoundingBox = BoundingBox {
+ left: std::u32::MAX,
+ top: std::u32::MAX,
+ right: std::u32::MIN,
+ bottom: std::u32::MIN
+ };
+
+ for (i, line) in (&lines).iter().enumerate() {
+ let (x, y): (u32, u32);
+ scan!(line.bytes() => "{}, {}", x, y);
+ if x < bb.left { bb.left = x; }
+ if x > bb.right { bb.right = x; }
+ if y < bb.top { bb.top = y; }
+ if y > bb.bottom { bb.bottom = y; }
+
+ let coordinate = Coordinate { x, y };
+ points.push(Point { coordinate, id: i as u32 });
+ println!("Add point {}, {}", &x, &y);
+ }
+
+ println!("BB: l: {}, r: {}, top: {}, bot: {}", bb.left, bb.right, bb.top, bb.bottom);
+
+ let w = (bb.right - bb.left + 1) as usize;
+ let h = (bb.bottom - bb.top + 1) as usize;
+ let mut grid: Vec<Vec<Option<u32>>> = vec![vec![None; w]; h];
+ for j in 0..h {
+ for i in 0..w {
+ let x = (i as u32 + bb.left) as u32;
+ let y = (j as u32 + bb.top) as u32;
+ let coord = Coordinate { x, y };
+ let opt: Option<(u32, u32)> = find_closest(&coord, &points);
+ match opt {
+ Some((id, shortest)) => { grid[j][i] = Some(id); }
+ None => { grid[j][i] = None }
+ }
+ }
+ }
+
+ //draw_grid(&grid, &bb);
+ let largest_area_1 = find_largest_area(&grid, &points, &bb);
+ println!("1. Largest area: {}", largest_area_1);
+
+ let threshold = 10000;
+ let mut largest_area_2 = 0;
+ for j in 0..h {
+ for i in 0..w {
+ let x = (i as u32 + bb.left) as u32;
+ let y = (j as u32 + bb.top) as u32;
+ let coord = Coordinate { x, y };
+ let total_dist = find_total_distance_to_points(&coord, &points);
+ if total_dist < threshold {
+ largest_area_2 += 1;
+ }
+ }
+ }
+
+ println!("2. Largest area: {}", largest_area_2);
+} \ No newline at end of file