advent_of_code_2022/aoc_09b/src/main.rs

153 lines
4.8 KiB
Rust

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<usize>, hist_y: Vec<usize>) {
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<usize>> = 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::<Point, u32>::new();
let mut rope: Vec<Point> = Vec::new();
let mut hist_x: Vec<i32> = Vec::new();
let mut hist_y: Vec<i32> = 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<usize> = hist_x.into_iter().map(|x| x as usize).collect();
let hist_y: Vec<usize> = 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<P>(filename: P) -> io::Result<io::Lines<io::BufReader<File>>>
where P: AsRef<Path>, {
let file = File::open(filename)?;
Ok(io::BufReader::new(file).lines())
}