use std::fs::File; use std::io::{self, BufRead}; use std::path::Path; use std::collections::HashMap; use std::ops::Add; use std::ops::Sub; #[derive(Eq, Hash, PartialEq, Debug, Clone, Copy)] struct Point(i32, i32); impl Add for Point { type Output = Point; #[inline(always)] fn add(self, other: Point) -> Point { // Probably it will be optimized to not actually copy self and rhs for each call ! Point(self.0 + other.0, self.1 + other.1) } } impl Sub for Point { type Output = Point; #[inline(always)] fn sub(self, other: Point) -> Point { // Probably it will be optimized to not actually copy self and rhs for each call ! Point(self.0 - other.0, self.1 - other.1) } } fn check_diff(tail: Point, head: Point) -> Point { let diff = tail - head; match diff { Point(-2, -2) => tail + Point(1, 1), Point(-2, -1) => tail + Point(1, 1), Point(-2, 0) => tail + Point(1, 0), Point(-2, 1) => tail + Point(1, -1), Point(-2, 2) => tail + Point(1, -1), Point(-1, -2) => tail + Point(1, 1), Point(-1, 2) => tail + Point(1, -1), Point(0, -2) => tail + Point(0, 1), Point(0, 2) => tail + Point(0, -1), Point(1, -2) => tail + Point(-1, 1), Point(1, 2) => tail + Point(-1, -1), Point(2, -2) => tail + Point(-1, 1), Point(2, -1) => tail + Point(-1, 1), Point(2, 0) => tail + Point(-1, 0), Point(2, 1) => tail + Point(-1, -1), Point(2, 2) => tail + Point(-1, -1), _ => tail, } } fn print_map(hist_x: Vec, hist_y: Vec) { let width= hist_x.iter().max().unwrap() + 1; let height= hist_y.iter().max().unwrap() + 1; println!("width {}, height {}", width, height); let mut map: Vec> = Vec::new(); for _ in 0..height { map.push(Vec::new()); for _ in 0..width { let len = map.len() - 1; map[len].push(0); } } for i in 0..hist_x.len() { map[height - 1 - hist_y[i]][hist_x[i]] += 1; } let mut count = 0; for y in 0..map.len() { //if x % 2 == 0 { let mut s = String::from(""); for x in 0..map[0].len() { // if y % 2 == 0 { //s.push((map[y][x] as u8 + ' ' as u8) as char); if map[y][x] > 0 { s.push(('#' as u8 + map[y][x] as u8) as char); } else { s.push(' '); } count += 1; // } } println!("{}", s); // } } println!("count {}", count / map.len()); } fn main() { let file_path = String::from("../aoc_09a/input4"); let mut positions = HashMap::::new(); let mut rope: Vec = Vec::new(); let mut hist_x: Vec = Vec::new(); let mut hist_y: Vec = Vec::new(); for _ in 0..10 { rope.push(Point(0, 0)); } *positions.entry(rope[9]).or_insert(0) += 1; hist_x.push(rope[9].0); hist_y.push(rope[9].1); println!("In file {}", file_path); if let Ok(lines) = read_lines(file_path) { // Consumes the iterator, returns an (Optional) String for line in lines { if let Ok(ip) = line { let split: Vec<&str> = ip.split(" ").collect(); let dir = split[0]; let steps: usize = split[1].parse().unwrap(); let mut diff = Point(0, 0); match dir { "U" => diff = Point(0, 1), "D" => diff = Point(0, -1), "R" => diff = Point(1, 0), "L" => diff = Point(-1, 0), _ => (), } for k in 0..steps { rope[0] = rope[0] + diff; for i in 0..rope.len() - 1 { rope[i + 1] = check_diff(rope[i + 1], rope[i]) } *positions.entry(*rope.last().unwrap()).or_insert(0) += 1; hist_x.push(rope[9].0); hist_y.push(rope[9].1); } } } } let minx = *hist_x.iter().min().unwrap(); let miny = *hist_y.iter().min().unwrap(); for i in 0..hist_x.len() { hist_x[i] -= minx; hist_y[i] -= miny; } let hist_x: Vec = hist_x.into_iter().map(|x| x as usize).collect(); let hist_y: Vec = hist_y.into_iter().map(|x| x as usize).collect(); print_map(hist_x, hist_y); println!("rope {:?}", rope); //println!("positions {:?}", positions); println!("positions {}", positions.len()); } fn read_lines

(filename: P) -> io::Result>> where P: AsRef, { let file = File::open(filename)?; Ok(io::BufReader::new(file).lines()) }