1
0
Fork 0

day 22 part 1 solution

main
Andrew Coleman 2024-02-21 13:00:36 -05:00
parent 5723296657
commit f571a43259
1 changed files with 168 additions and 4 deletions

View File

@ -1,10 +1,116 @@
advent_of_code::solution!(22); advent_of_code::solution!(22);
pub fn part_one(input: &str) -> Option<u32> { use aoc_parse::{parser, prelude::*};
None use std::collections::{HashMap, HashSet};
#[derive(Clone, Copy, Debug, PartialOrd, Ord, Eq, PartialEq)]
struct Coord {
z: usize,
x: usize,
y: usize,
} }
pub fn part_two(input: &str) -> Option<u32> { #[derive(Debug, Clone, PartialOrd, Ord, Eq, PartialEq)]
struct Block {
id: usize,
one: Coord,
two: Coord,
}
impl Block {
fn intersect_xy(&self, other: &Self) -> bool {
self.one.x <= other.two.x
&& other.one.x <= self.two.x
&& self.one.y <= other.two.y
&& other.one.y <= self.two.y
}
fn below(&self, other: &Self) -> bool {
// self.id != other.id && self.intersect_xy(other) && self.two.z == other.one.z - 1
self.intersect_xy(other) && self.two.z == other.one.z - 1
}
fn above(&self, other: &Self) -> bool {
// self.id != other.id && self.intersect_xy(other) && self.one.z == other.two.z + 1
self.intersect_xy(other) && self.one.z == other.two.z + 1
}
}
fn parse(input: &str) -> Vec<Block> {
let p = parser!(lines(usize "," usize "," usize "~" usize "," usize "," usize));
let mut blocks = p
.parse(input)
.unwrap()
.iter()
.enumerate()
.map(|(index, r)| Block {
id: index + 1,
one: Coord {
z: r.2,
x: r.0,
y: r.1,
},
two: Coord {
z: r.5,
x: r.3,
y: r.4,
},
})
.collect::<Vec<_>>();
blocks.sort_by_key(|b| b.one);
blocks
}
fn drop_blocks(blocks: &[Block]) -> Vec<Block> {
let mut btm: Vec<Block> = Vec::with_capacity(blocks.len());
for b in blocks.iter() {
let mut block = b.clone();
for _i in 1..b.one.z {
if let Some(_below) = btm.iter().find(|d| d.below(&block)) {
break;
}
block.one.z -= 1;
block.two.z -= 1;
}
btm.push(block);
}
btm
}
fn pyprint(b: &Block) {
println!(
"(({}, {}, {}), ({}, {}, {}))",
b.one.x, b.one.y, b.one.z, b.two.x, b.two.y, b.two.z
);
}
pub fn part_one(input_str: &str) -> Option<usize> {
let input = parse(input_str);
let btm = drop_blocks(&input);
let mut b: HashMap<usize, Vec<usize>> = HashMap::new();
for outside in btm.iter() {
let mut below: Vec<usize> = vec![];
for inside in btm.iter() {
if inside.below(&outside) {
below.push(inside.id);
}
}
b.insert(outside.id, below);
}
let mut s: HashSet<usize> = HashSet::new();
for id in 1..=btm.len() {
if let Some(below) = b.get(&id) {
if below.len() == 1 {
for &x in below {
s.insert(x);
}
}
}
}
Some(btm.len() - s.len())
}
pub fn part_two(input_str: &str) -> Option<usize> {
None None
} }
@ -15,7 +121,7 @@ mod tests {
#[test] #[test]
fn test_part_one() { fn test_part_one() {
let result = part_one(&advent_of_code::template::read_file("examples", DAY)); let result = part_one(&advent_of_code::template::read_file("examples", DAY));
assert_eq!(result, None); assert_eq!(result, Some(5));
} }
#[test] #[test]
@ -23,4 +129,62 @@ mod tests {
let result = part_two(&advent_of_code::template::read_file("examples", DAY)); let result = part_two(&advent_of_code::template::read_file("examples", DAY));
assert_eq!(result, None); assert_eq!(result, None);
} }
fn perform_test_intersect(
one: &(usize, usize, usize, usize, usize, usize),
two: &(usize, usize, usize, usize, usize, usize),
res: bool,
) {
let b1 = Block {
id: 1,
one: Coord {
x: one.0,
y: one.1,
z: one.2,
},
two: Coord {
x: one.3,
y: one.4,
z: one.5,
},
};
let b2 = Block {
id: 2,
one: Coord {
x: two.0,
y: two.1,
z: two.2,
},
two: Coord {
x: two.3,
y: two.4,
z: two.5,
},
};
assert_eq!(b1.intersect_xy(&b2), res);
}
#[test]
fn test_intersect_xy() {
let false_coords = [
[(0, 0, 1, 0, 0, 1), (1, 0, 1, 4, 0, 1)],
[(0, 0, 1, 0, 0, 1), (0, 1, 1, 0, 4, 1)],
[(0, 0, 1, 10, 0, 1), (1, 1, 1, 1, 1, 1)],
[(0, 0, 1, 10, 0, 1), (1, 1, 1, 1, 10, 1)],
];
for row in false_coords.iter() {
let one = row[0];
let two = row[1];
perform_test_intersect(&one, &two, false);
}
let true_coords = [
[(0, 0, 1, 0, 0, 1), (0, 0, 1, 4, 0, 1)],
[(0, 0, 1, 10, 0, 1), (5, 0, 1, 5, 5, 1)],
];
for row in true_coords.iter() {
let one = row[0];
let two = row[1];
perform_test_intersect(&one, &two, true);
}
}
} }