i hate d09p2

This commit is contained in:
2025-12-09 16:22:29 +01:00
parent 49bb9c9452
commit b07fdf283b
4 changed files with 391 additions and 0 deletions

36
2025/09/p1.rs Normal file
View File

@@ -0,0 +1,36 @@
#[unsafe(no_mangle)]
pub extern "Rust" fn challenge_usize(buf: &[u8]) -> usize {
// I do see how to make this in idk if O(n) or O(nlogn), but ima O(n^2) just at first
let coords = buf[..(buf.len() - 1)]
.split(|&b| b == b'\n')
.map(parse_ln)
.collect::<Vec<_>>();
let mut area = 0;
for coor1 in &coords {
for coor2 in &coords {
let dx = coor1.0.abs_diff(coor2.0) + 1;
let dy = coor1.1.abs_diff(coor2.1) + 1;
let this_area = dx * dy;
// println!(
// "{},{} {},{} | {this_area}",
// coor1.0, coor1.1, coor2.0, coor2.1
// );
area = area.max(this_area);
}
}
area
}
fn parse_ln(ln: &[u8]) -> (usize, usize) {
let mut iter = ln.split(|&b| b == b',').map(|slice| {
slice
.iter()
.fold(0, |acc, b| acc * 10 + (b - b'0') as usize)
});
(iter.next().unwrap(), iter.next().unwrap())
}

133
2025/09/p2-hu.rs Normal file
View File

@@ -0,0 +1,133 @@
//! Half of the puzzle seems like a fancy way to say that the puzzle corners have to be within any
//! other rectangle or adyacent (as in same x or y as any other point) to other corners.
//!
//! I think even adyacent is within the "other rectangle thing", because
#[unsafe(no_mangle)]
pub extern "Rust" fn challenge_usize(buf: &[u8]) -> usize {
// I do see how to make this in idk if O(n) or O(nlogn), but ima O(n^2) just at first
let coords = buf[..(buf.len() - 1)]
.split(|&b| b == b'\n')
.map(parse_ln)
.collect::<Vec<_>>();
let mut filtering_tiles = coords.clone();
loop {
let filtered_tiles = filtering_tiles
.iter()
.cloned()
.filter(|coor| {
for corner1 in &filtering_tiles {
for corner2 in &filtering_tiles {
if coor == corner1 || coor == corner2 {
continue;
}
let minx = corner1.0.min(corner2.0);
let maxx = corner1.0.max(corner2.0);
let miny = corner1.1.min(corner2.1);
let maxy = corner1.1.max(corner2.1);
if (minx..=maxx).contains(&coor.0) && (miny..=maxy).contains(&coor.1) {
return true;
}
}
}
false
})
.collect::<Vec<_>>();
let filtered_anything = filtered_tiles.len() != filtering_tiles.len();
filtering_tiles = filtered_tiles;
dbg!(filtered_anything);
if !filtered_anything {
break;
}
}
let mut area = 0;
for coor1 in &coords {
for coor2 in &coords {
let dx = coor1.0.abs_diff(coor2.0) + 1;
let dy = coor1.1.abs_diff(coor2.1) + 1;
let this_area = dx * dy;
let conjugate1 = (coor1.0, coor2.1);
let conjugate2 = (coor2.0, coor1.1);
if !is_really_contained_in_any_rectangle(conjugate1, &coords) { continue; }
if !is_really_contained_in_any_rectangle(conjugate2, &coords) { continue; }
// println!(
// "{},{} {},{} | {this_area}",
// coor1.0, coor1.1, coor2.0, coor2.1
// );
area = area.max(this_area);
}
}
area
}
/// This should count
/// ....O.....O
/// .....X.....
/// ...........
/// ....O.....O
///
/// but not
/// ....O.....O
/// .....X.....
/// ...........
/// ..........O
///
/// I will refer to the second case as being normally included in a rectangle while the first case
/// is contained in both normally and inverse rectangles. Good way to identify is that dx and dy
/// have the same sign or not, if sgn(dx) == sgn(dy) its normal, otherwise antinormal.
fn is_really_contained_in_any_rectangle(coor: (usize, usize), inpoints: &[(usize, usize)]) -> bool {
let mut found_normal = false;
let mut found_inverse = false;
for corner1 in inpoints {
for corner2 in inpoints {
let minx = corner1.0.min(corner2.0);
let maxx = corner1.0.max(corner2.0);
let miny = corner1.1.min(corner2.1);
let maxy = corner1.1.max(corner2.1);
if !((minx..=maxx).contains(&coor.0) && (miny..=maxy).contains(&coor.1)) {
continue;
}
let dx = corner1.0 as isize - corner2.0 as isize;
let dy = corner1.1 as isize - corner2.1 as isize;
if dx == 0 || dy == 0 {
return true;
}
if (dx * dy).is_positive() {
found_normal = true;
}
if (dx * dy).is_negative() {
found_inverse = true;
}
if found_inverse && found_normal {
return true;
}
}
}
false
}
fn parse_ln(ln: &[u8]) -> (usize, usize) {
let mut iter = ln.split(|&b| b == b',').map(|slice| {
slice
.iter()
.fold(0, |acc, b| acc * 10 + (b - b'0') as usize)
});
(iter.next().unwrap(), iter.next().unwrap())
}

133
2025/09/p2-hu2.rs Normal file
View File

@@ -0,0 +1,133 @@
//! Half of the puzzle seems like a fancy way to say that the puzzle corners have to be within any
//! other rectangle or adyacent (as in same x or y as any other point) to other corners.
//!
//! I think even adyacent is within the "other rectangle thing", because
#[unsafe(no_mangle)]
pub extern "Rust" fn challenge_usize(buf: &[u8]) -> usize {
// I do see how to make this in idk if O(n) or O(nlogn), but ima O(n^2) just at first
let coords = buf[..(buf.len() - 1)]
.split(|&b| b == b'\n')
.map(parse_ln)
.collect::<Vec<_>>();
let mut filtering_tiles = coords.clone();
loop {
let filtered_tiles = filtering_tiles
.iter()
.cloned()
.filter(|coor| {
for corner1 in &filtering_tiles {
for corner2 in &filtering_tiles {
if coor == corner1 || coor == corner2 {
continue;
}
let minx = corner1.0.min(corner2.0);
let maxx = corner1.0.max(corner2.0);
let miny = corner1.1.min(corner2.1);
let maxy = corner1.1.max(corner2.1);
if (minx..=maxx).contains(&coor.0) && (miny..=maxy).contains(&coor.1) {
return true;
}
}
}
false
})
.collect::<Vec<_>>();
let filtered_anything = filtered_tiles.len() != filtering_tiles.len();
filtering_tiles = filtered_tiles;
dbg!(filtered_anything);
if !filtered_anything {
break;
}
}
let mut area = 0;
for coor1 in &coords {
for coor2 in &coords {
let dx = coor1.0.abs_diff(coor2.0) + 1;
let dy = coor1.1.abs_diff(coor2.1) + 1;
let this_area = dx * dy;
let conjugate1 = (coor1.0, coor2.1);
let conjugate2 = (coor2.0, coor1.1);
if !is_really_contained_in_any_rectangle(conjugate1, &coords) { continue; }
if !is_really_contained_in_any_rectangle(conjugate2, &coords) { continue; }
// println!(
// "{},{} {},{} | {this_area}",
// coor1.0, coor1.1, coor2.0, coor2.1
// );
area = area.max(this_area);
}
}
area
}
/// This should count
/// ....O.....O
/// .....X.....
/// ...........
/// ....O.....O
///
/// but not
/// ....O.....O
/// .....X.....
/// ...........
/// ..........O
///
/// I will refer to the second case as being normally included in a rectangle while the first case
/// is contained in both normally and inverse rectangles. Good way to identify is that dx and dy
/// have the same sign or not, if sgn(dx) == sgn(dy) its normal, otherwise antinormal.
fn is_really_contained_in_any_rectangle(coor: (usize, usize), inpoints: &[(usize, usize)]) -> bool {
let mut found_normal = false;
let mut found_inverse = false;
for corner1 in inpoints {
for corner2 in inpoints {
let minx = corner1.0.min(corner2.0);
let maxx = corner1.0.max(corner2.0);
let miny = corner1.1.min(corner2.1);
let maxy = corner1.1.max(corner2.1);
if !((minx..=maxx).contains(&coor.0) && (miny..=maxy).contains(&coor.1)) {
continue;
}
let dx = corner1.0 as isize - corner2.0 as isize;
let dy = corner1.1 as isize - corner2.1 as isize;
if dx == 0 || dy == 0 {
return true;
}
if (dx * dy).is_positive() {
found_normal = true;
}
if (dx * dy).is_negative() {
found_inverse = true;
}
if found_inverse && found_normal {
return true;
}
}
}
false
}
fn parse_ln(ln: &[u8]) -> (usize, usize) {
let mut iter = ln.split(|&b| b == b',').map(|slice| {
slice
.iter()
.fold(0, |acc, b| acc * 10 + (b - b'0') as usize)
});
(iter.next().unwrap(), iter.next().unwrap())
}

89
2025/09/p2.rs Normal file
View File

@@ -0,0 +1,89 @@
#![feature(iter_map_windows)]
//! Half of the puzzle seems like a fancy way to say that the puzzle corners have to be within any
//! other rectangle or adyacent (as in same x or y as any other point) to other corners.
//!
//! I think even adyacent is within the "other rectangle thing", because
#[unsafe(no_mangle)]
pub extern "Rust" fn challenge_usize(buf: &[u8]) -> usize {
// I do see how to make this in idk if O(n) or O(nlogn), but ima O(n^2) just at first
let coords = buf[..(buf.len() - 1)]
.split(|&b| b == b'\n')
.map(parse_ln)
.collect::<Vec<_>>();
// assuming each coord is contiguous to the prev one
let edges = coords
.iter()
.cloned()
.chain([coords[0]])
.map_windows(|&[a, b]| (a, b))
.collect::<Vec<_>>();
let mut area = 0;
for coor1 in &coords {
for coor2 in &coords {
let dx = coor1.0.abs_diff(coor2.0) + 1;
let dy = coor1.1.abs_diff(coor2.1) + 1;
let this_area = dx * dy;
// println!("{coor1:?}, {coor2:?}");
if is_really_contained((*coor1, *coor2), &edges) {
area = area.max(this_area);
}
// println!(
// "{},{} {},{} | {this_area}",
// coor1.0, coor1.1, coor2.0, coor2.1
// );
}
}
area
}
/// If any bouding vertex is well within (not sitting on a rectangle's edge), the rectangle is not
/// well contained
fn is_really_contained(
(rect0, rect1): ((usize, usize), (usize, usize)),
edges: &[((usize, usize), (usize, usize))],
) -> bool {
let (rect0, rect1) = (
(rect0.0.min(rect1.0), rect0.1.min(rect1.1)),
(rect0.0.max(rect1.0), rect0.1.max(rect1.1)),
);
let xran = (rect0.0 + 1)..=(rect1.0 - 1);
let yran = (rect0.1 + 1)..=(rect1.1 - 1);
// Optimization, no need to check each range's point
for (edge1, edge2) in edges {
if edge1.0 == edge2.0 && xran.contains(&edge1.0) {
for y in edge1.1.min(edge2.1)..edge1.1.max(edge2.1) {
if yran.contains(&y) {
return false;
}
}
}
if edge1.1 == edge2.1 && yran.contains(&edge1.1) {
for x in edge1.0.min(edge2.0)..edge1.0.max(edge2.0) {
if xran.contains(&x) {
return false;
}
}
}
}
true
}
fn parse_ln(ln: &[u8]) -> (usize, usize) {
let mut iter = ln.split(|&b| b == b',').map(|slice| {
slice
.iter()
.fold(0, |acc, b| acc * 10 + (b - b'0') as usize)
});
(iter.next().unwrap(), iter.next().unwrap())
}