diff options
Diffstat (limited to 'day6/src')
| -rw-r--r-- | day6/src/main.rs | 183 |
1 files changed, 183 insertions, 0 deletions
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 |
