Implement AoC 2025 #1

Open
leon wants to merge 22 commits from 2025 into main
Showing only changes of commit c2df9b06ca - Show all commits

View File

@@ -1,8 +1,26 @@
---cargo
[profile.dev]
opt-level = 3
[dependencies]
rayon = "1"
---
use rayon::prelude::*;
static CONTENT: &'static str = include_str!("./inputs/09_1.txt");
const PRINT: bool = false;
#[derive(Debug, PartialEq, Clone, Copy)]
enum Cell {
Empty,
Red,
Green,
}
const _T: () = assert!(1 == core::mem::size_of::<Cell>());
fn main() {
let points: Vec<(usize, usize)> = CONTENT.lines().map(|l| l.trim()).filter(|l| !l.is_empty()).map(|l| {
let (first, second) = l.split_once(',').unwrap();
@@ -12,17 +30,124 @@ fn main() {
(first, second)
}).collect();
println!("Points:\n{:?}", points);
// println!("Points:\n{:?}", points);
let mut rects: Vec<((usize, usize), (usize, usize), usize)> = points.iter()
.flat_map(|p| core::iter::repeat(*p).zip(points.iter().copied()))
let grid_width: usize = points.iter().map(|(x, _)| *x).max().unwrap()+1;
let grid_height: usize = points.iter().map(|(y, _)| *y).max().unwrap()+1;
let mut grid = vec![Cell::Empty;grid_width*grid_height];
for parts in points.windows(2).chain(core::iter::once(&[points.last().copied().unwrap(), points.first().copied().unwrap()] as &[(usize, usize)])) {
let start = parts[0];
let end = parts[1];
let g_points = line_point_iter(start, end);
grid[start.1 *grid_width+ start.0] = Cell::Red;
for (x,y) in g_points {
grid[y*grid_width+x] = Cell::Green;
}
}
print_grid(&grid, grid_width, grid_height);
let inner_point = points.windows(2)
.filter(|p| {
let start = p[0];
let end = p[1];
start.0 == end.0
}).filter_map(|p| {
let start = p[0];
let end = p[1];
line_point_iter(start, end).next()
}).flat_map(|(x, y)| {
[(x-1, y), (x+1, y)]
}).filter(|(x, y)| {
(0..grid_width).contains(x)
}).find(|(x, y)| {
let c = (0..*x).map(|x| grid[y*grid_width + x]).filter(|c| *c == Cell::Green).count();
c == 1
}).unwrap();
println!("After filling");
print_grid(&grid, grid_width, grid_height);
let largest = points.par_iter()
.flat_map_iter(|p| core::iter::repeat(*p).zip(points.iter().copied()))
.filter(|(f, s)| f != s)
.map(|(f, s)| (f, s, (f.0.abs_diff(s.0)+1) * (f.1.abs_diff(s.1)+1)))
.collect();
.filter(|(f, s, _)| {
let x0 = f.0.min(s.0);
let x1 = f.0.max(s.0);
rects.sort_by_key(|(_, _, a)| *a);
let y0 = f.1.min(s.1);
let y1 = f.1.max(s.1);
// println!("Rectangle: {:?}", rects);
println!("Largest: {:?}", rects.last().unwrap());
(x0..=x1).flat_map(|x| {
core::iter::repeat(x).zip(y0..=y1)
}).all(|(x, y)| in_grid(&grid, grid_width, grid_height, (x,y)))
})
.reduce(|| ((0,0), (0,0), 0), |acc, (f, s, a)| {
if a > acc.2 {
return (f, s, a);
}
acc
});
println!("Largest: {:?}", largest);
}
fn print_grid(grid: &[Cell], width: usize, height: usize) {
if !PRINT {
return;
}
for y in 0..height {
for x in 0..width {
match grid[y*width+x] {
Cell::Empty => print!("."),
Cell::Red => print!("#"),
Cell::Green => print!("X"),
};
}
println!();
}
}
fn line_point_iter(start: (usize, usize), end: (usize, usize)) -> Box<dyn Iterator<Item = (usize, usize)>> {
if start.0 == end.0 {
let s = start.1.min(end.1);
let e = start.1.max(end.1);
Box::new(core::iter::repeat(start.0).zip(s..e).skip(1))
} else {
let s = start.0.min(end.0);
let e = start.0.max(end.0);
Box::new((s..e).zip(core::iter::repeat(start.1)).skip(1))
}
}
fn in_grid(grid: &[Cell], width: usize, height: usize, (x, y): (usize, usize)) -> bool {
if grid[y*width+x] != Cell::Empty {
return true;
}
let c = (0..x).map(|x| grid[y*width + x]).filter(|c| *c != Cell::Empty).count();
match c {
0 => false,
1 => true,
2 => false,
_ => {
let c = (0..y).map(|y| grid[y*width + x]).filter(|c| *c != Cell::Empty).count();
match c {
1 => true,
_ => false,
}
}
}
}