mirror of
https://github.com/danbulant/adventOfCode
synced 2026-06-20 06:41:06 +00:00
perf experiments
This commit is contained in:
parent
38a7be8e0c
commit
ff63902fb2
1 changed files with 120 additions and 21 deletions
|
|
@ -1,7 +1,8 @@
|
||||||
use std::{fs::File, io::{BufReader, BufRead, Write}, ops::Add, fmt::Debug};
|
use std::{fs::File, io::{BufReader, BufRead, Write}, ops::Add, fmt::Debug, collections::HashSet, hash::{Hasher, BuildHasherDefault}};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
part1();
|
part1();
|
||||||
|
part2();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
|
@ -46,6 +47,42 @@ struct Beam {
|
||||||
vector: Vector
|
vector: Vector
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Beam {
|
||||||
|
fn to_u64(&self) -> u64 {
|
||||||
|
(self.point.x * 100 + self.point.y) * (1 + self.vector.x + 2 * (self.vector.y + 1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
struct BeamHasher {
|
||||||
|
nums: u64
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Hasher for BeamHasher {
|
||||||
|
fn write(&mut self, bytes: &[u8]) {
|
||||||
|
// assign bytes directly to nums - this hasher will always get 4 u8s, just once
|
||||||
|
// self.nums = 0;
|
||||||
|
for i in 0..4 {
|
||||||
|
self.nums ^= (bytes[i] as u64) << (i * 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn finish(&self) -> u64 {
|
||||||
|
self.nums
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::hash::Hash for Beam {
|
||||||
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
|
state.write(&[
|
||||||
|
self.point.x as u8,
|
||||||
|
self.point.y as u8,
|
||||||
|
self.vector.x as u8,
|
||||||
|
self.vector.y as u8
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Vector {
|
impl Vector {
|
||||||
fn map_by_mirror(&self, mirror: Type) -> Vector {
|
fn map_by_mirror(&self, mirror: Type) -> Vector {
|
||||||
match mirror {
|
match mirror {
|
||||||
|
|
@ -127,11 +164,11 @@ fn print_energized(energized: &Vec<Vec<bool>>) -> Result<(), std::io::Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn append_if_not_in<T: PartialEq + Debug>(vec: &mut Vec<T>, item: T) {
|
// fn append_if_not_in<T: PartialEq + Debug>(vec: &mut Vec<T>, item: T) {
|
||||||
if !vec.contains(&item) {
|
// if !vec.contains(&item) {
|
||||||
vec.push(item);
|
// vec.push(item);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
fn set_range<T: Copy>(vec: &mut Vec<T>, range: std::ops::Range<usize>, item: T) {
|
fn set_range<T: Copy>(vec: &mut Vec<T>, range: std::ops::Range<usize>, item: T) {
|
||||||
for i in range {
|
for i in range {
|
||||||
vec[i] = item;
|
vec[i] = item;
|
||||||
|
|
@ -159,14 +196,14 @@ fn mark(vec: Vector, point: Point, otherpos: usize, energized: &mut Vec<Vec<bool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part1() {
|
fn get_map() -> Vec<Vec<char>> {
|
||||||
let file = File::open("input2").expect("File not found");
|
let file = File::open("input2").expect("File not found");
|
||||||
let reader = BufReader::new(file);
|
let reader = BufReader::new(file);
|
||||||
let map : Vec<Vec<char>> = reader.lines().map(|l| l.unwrap().chars().collect()).collect();
|
let map : Vec<Vec<char>> = reader.lines().map(|l| l.unwrap().chars().collect()).collect();
|
||||||
let mut energized : Vec<Vec<bool>> = map.iter().map(|l| l.iter().map(|_| false).collect()).collect();
|
map
|
||||||
|
}
|
||||||
let max_point = Point { x: map[0].len(), y: map.len() };
|
|
||||||
|
|
||||||
|
fn get_rows_and_cols(map: Vec<Vec<char>>) -> (Vec<Vec<MapPoint>>, Vec<Vec<MapPoint>>) {
|
||||||
let rows: Vec<Vec<MapPoint>> = map.iter().enumerate().map(|(y, row)| {
|
let rows: Vec<Vec<MapPoint>> = map.iter().enumerate().map(|(y, row)| {
|
||||||
row
|
row
|
||||||
.iter()
|
.iter()
|
||||||
|
|
@ -202,10 +239,23 @@ fn part1() {
|
||||||
}).collect()
|
}).collect()
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
let mut beams : Vec<Beam> = vec![Beam {
|
(rows, columns)
|
||||||
point: Point { x: 0, y: 0 },
|
}
|
||||||
vector: VEC_RIGHT
|
|
||||||
}];
|
fn setup() -> (Point, Vec<Vec<MapPoint>>, Vec<Vec<MapPoint>>) {
|
||||||
|
let map = get_map();
|
||||||
|
// let energized : Vec<Vec<bool>> = map.iter().map(|l| l.iter().map(|_| false).collect()).collect();
|
||||||
|
let max_point = Point { x: map[0].len(), y: map.len() };
|
||||||
|
let (rows, columns) = get_rows_and_cols(map);
|
||||||
|
|
||||||
|
(max_point, rows, columns)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_count(max_point: Point, rows: Vec<Vec<MapPoint>>, columns: Vec<Vec<MapPoint>>, beam: Beam) -> usize {
|
||||||
|
let mut energized : Vec<Vec<bool>> = vec![vec![false; max_point.x]; max_point.y];
|
||||||
|
let mut beams_set = HashSet::<Beam, BuildHasherDefault<BeamHasher>>::default();
|
||||||
|
let mut beams : Vec<Beam> = vec![beam];
|
||||||
|
beams_set.insert(beams[0]);
|
||||||
|
|
||||||
let mut offset = 0;
|
let mut offset = 0;
|
||||||
|
|
||||||
|
|
@ -214,15 +264,16 @@ fn part1() {
|
||||||
offset += 1;
|
offset += 1;
|
||||||
|
|
||||||
let vec = beam.vector;
|
let vec = beam.vector;
|
||||||
|
let vec_is_vertical = vec.is_vertical();
|
||||||
let mut relevant = {
|
let mut relevant = {
|
||||||
(if vec.is_vertical() {
|
(if vec_is_vertical {
|
||||||
columns[beam.point.x].iter()
|
columns[beam.point.x].iter()
|
||||||
} else {
|
} else {
|
||||||
rows[beam.point.y].iter()
|
rows[beam.point.y].iter()
|
||||||
})
|
})
|
||||||
.filter(|mp| {
|
.filter(|mp| {
|
||||||
let mpp = if vec.is_vertical() { mp.point.y } else { mp.point.x };
|
let mpp = if vec_is_vertical { mp.point.y } else { mp.point.x };
|
||||||
let beamp = if vec.is_vertical() { beam.point.y } else { beam.point.x };
|
let beamp = if vec_is_vertical { beam.point.y } else { beam.point.x };
|
||||||
// ignore splits that are the same direction as the beam
|
// ignore splits that are the same direction as the beam
|
||||||
mp.mirror != vec.map_to_split() &&
|
mp.mirror != vec.map_to_split() &&
|
||||||
(mpp >= beamp && vec.is_positive() || mpp <= beamp && vec.is_negative())
|
(mpp >= beamp && vec.is_positive() || mpp <= beamp && vec.is_negative())
|
||||||
|
|
@ -238,7 +289,7 @@ fn part1() {
|
||||||
mark(vec, beam.point, if vec.is_positive() { max_point.x } else { 0 }, &mut energized);
|
mark(vec, beam.point, if vec.is_positive() { max_point.x } else { 0 }, &mut energized);
|
||||||
},
|
},
|
||||||
Some(mappoint) => {
|
Some(mappoint) => {
|
||||||
mark(vec, beam.point, (if vec.is_vertical() { mappoint.point.y } else { mappoint.point.x } ) + (if vec.is_positive() { 1 } else { 0 }), &mut energized);
|
mark(vec, beam.point, (if vec_is_vertical { mappoint.point.y } else { mappoint.point.x } ) + (if vec.is_positive() { 1 } else { 0 }), &mut energized);
|
||||||
let mut vecs = vec![];
|
let mut vecs = vec![];
|
||||||
if mappoint.mirror == Type::SplitHorizontal || mappoint.mirror == Type::SplitVertical {
|
if mappoint.mirror == Type::SplitHorizontal || mappoint.mirror == Type::SplitVertical {
|
||||||
let (v1, v2) = vectors_from_split(mappoint.mirror);
|
let (v1, v2) = vectors_from_split(mappoint.mirror);
|
||||||
|
|
@ -255,14 +306,62 @@ fn part1() {
|
||||||
point: new_point,
|
point: new_point,
|
||||||
vector: v
|
vector: v
|
||||||
};
|
};
|
||||||
append_if_not_in(&mut beams, beam);
|
// append_if_not_in(&mut beams, beam);
|
||||||
|
if beams_set.insert(beam) {
|
||||||
|
beams.push(beam);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
print_energized(&energized).unwrap();
|
// print_energized(&energized).unwrap();
|
||||||
|
|
||||||
let count = energized.iter().map(|row| row.iter().filter(|&&b| b).count()).sum::<usize>();
|
let count = energized.iter().map(|row| row.iter().filter(|&&b| b).count()).sum::<usize>();
|
||||||
println!("Count: {}", count);
|
count
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part1() {
|
||||||
|
let (max_point, rows, columns) = setup();
|
||||||
|
let count = get_count(max_point, rows, columns, Beam {
|
||||||
|
point: Point { x: 0, y: 0 },
|
||||||
|
vector: VEC_RIGHT
|
||||||
|
});
|
||||||
|
println!("Part 1 count: {}", count);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2() {
|
||||||
|
let (max_point, rows, columns) = setup();
|
||||||
|
let mut count = 0;
|
||||||
|
for x in 0..max_point.x {
|
||||||
|
for y in 0..max_point.y {
|
||||||
|
if x != 0 && y != 0 && x != max_point.x - 1 && y != max_point.y - 1 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let mut vecs = vec![];
|
||||||
|
if x > 0 {
|
||||||
|
vecs.push(VEC_LEFT);
|
||||||
|
}
|
||||||
|
if x == 0 {
|
||||||
|
vecs.push(VEC_RIGHT);
|
||||||
|
}
|
||||||
|
if y > 0 {
|
||||||
|
vecs.push(VEC_UP);
|
||||||
|
}
|
||||||
|
if y == 0 {
|
||||||
|
vecs.push(VEC_DOWN);
|
||||||
|
}
|
||||||
|
for vector in vecs {
|
||||||
|
let count_here = get_count(max_point, rows.clone(), columns.clone(), Beam {
|
||||||
|
point: Point { x, y },
|
||||||
|
vector
|
||||||
|
});
|
||||||
|
if count_here > count {
|
||||||
|
count = count_here;
|
||||||
|
println!("New max: {} at {},{}", count, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println!("Max count: {}", count);
|
||||||
}
|
}
|
||||||
Loading…
Reference in a new issue