diff options
| author | Jan Tuomi <jan.tuomi@eficode.com> | 2018-12-06 19:45:06 +0200 |
|---|---|---|
| committer | Jan Tuomi <jan.tuomi@eficode.com> | 2018-12-06 19:45:06 +0200 |
| commit | 2a0f5d3f3d28235abe87898597f8fb89b9668885 (patch) | |
| tree | b1456455037dba5e4bfc0d4ae3de2f6482b9ab76 | |
| parent | d7ed7cb411329c15e2c5457b3b1c48aa9dba22c8 (diff) | |
Solve day6
| -rw-r--r-- | day6/.vscode/launch.json | 43 | ||||
| -rw-r--r-- | day6/Cargo.lock | 14 | ||||
| -rw-r--r-- | day6/Cargo.toml | 7 | ||||
| -rw-r--r-- | day6/src/main.rs | 183 |
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 |
