day22: added

This commit is contained in:
Ishan Jain 2023-12-23 06:18:08 +05:30
parent 5dd5dc53d5
commit 2b4ffe5fbe
Signed by: ishan
GPG Key ID: 0506DB2A1CC75C27
4 changed files with 1712 additions and 2 deletions

View File

@ -1 +1,136 @@
const INPUTS: [&'static str; 2] = [include_str!("./sample.txt"), include_str!("./input.txt")];
#![feature(test)]
extern crate test;
const INPUTS: [&str; 2] = [include_str!("./sample.txt"), include_str!("./input.txt")];
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)]
struct Cuboid {
start: (i32, i32, i32),
end: (i32, i32, i32),
}
impl Cuboid {
fn intersect(&self, other: Self) -> bool {
let cs = self.start;
let ce = self.end;
let es = other.start;
let ee = other.end;
let min_x1 = cs.0.min(ce.0);
let min_y1 = cs.1.min(ce.1);
let min_z1 = cs.2.min(ce.2);
let max_x1 = cs.0.max(ce.0);
let max_y1 = cs.1.max(ce.1);
let max_z1 = cs.2.max(ce.2);
let min_x2 = es.0.min(ee.0);
let min_y2 = es.1.min(ee.1);
let min_z2 = es.2.min(ee.2);
let max_x2 = es.0.max(ee.0);
let max_y2 = es.1.max(ee.1);
let max_z2 = es.2.max(ee.2);
!((min_x1 > max_x2)
|| (max_x1 < min_x2)
|| (min_y1 > max_y2)
|| (max_y1 < min_y2)
|| (min_z1 > max_z2)
|| (max_z1 < min_z2))
}
}
fn process(data: &str) -> i64 {
let mut blocks = Vec::new();
for line in data.lines() {
let (start, end) = line.split_once('~').unwrap();
let mut start = start.split(',');
let sx = start.next().unwrap().parse::<i32>().unwrap();
let sy = start.next().unwrap().parse::<i32>().unwrap();
let sz = start.next().unwrap().parse::<i32>().unwrap();
let mut end = end.split(',');
let ex = end.next().unwrap().parse::<i32>().unwrap();
let ey = end.next().unwrap().parse::<i32>().unwrap();
let ez = end.next().unwrap().parse::<i32>().unwrap();
blocks.push(Cuboid {
start: (sx, sy, sz),
end: (ex, ey, ez),
});
}
blocks.sort_unstable_by(|a, b| a.start.2.cmp(&b.start.2));
let blocks = drop(&blocks);
count_safe_groups(&blocks)
}
fn drop(blocks: &[Cuboid]) -> Vec<Cuboid> {
let mut current = blocks.to_vec();
loop {
let mut changed = false;
let mut next: Vec<Cuboid> = vec![];
for i in 0..current.len() {
let block = &current[i];
let mut new_block = *block;
new_block.start.2 -= 1;
new_block.end.2 -= 1;
if new_block.start.2 < 1 {
next.push(*block);
continue;
}
let mut intersected = false;
for other_block in current.iter().take(i) {
if new_block.intersect(*other_block) {
intersected = true;
break;
}
}
if intersected {
next.push(*block);
} else {
next.push(new_block);
changed = true
}
}
current = next;
if !changed {
break;
}
}
current
}
fn count_safe_groups(v: &Vec<Cuboid>) -> i64 {
let mut out: i64 = 0;
for i in 0..v.len() {
let mut a = v.clone();
a.remove(i);
let dropped = drop(&a);
if dropped == a {
out += 1;
}
}
out
}
fn main() {
for input in INPUTS.iter().skip(1) {
println!("answer = {}", process(input));
}
}
#[bench]
fn part1(b: &mut test::Bencher) {
b.iter(|| {
let v = process(INPUTS[INPUTS.len() - 1]);
test::black_box(v);
});
}

View File

@ -1 +1,140 @@
const INPUTS: [&'static str; 2] = [include_str!("./sample.txt"), include_str!("./input.txt")];
#![feature(test)]
extern crate test;
const INPUTS: [&str; 2] = [include_str!("./sample.txt"), include_str!("./input.txt")];
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)]
struct Cuboid {
start: (i32, i32, i32),
end: (i32, i32, i32),
}
impl Cuboid {
fn intersect(&self, other: Self) -> bool {
let cs = self.start;
let ce = self.end;
let es = other.start;
let ee = other.end;
let min_x1 = cs.0.min(ce.0);
let min_y1 = cs.1.min(ce.1);
let min_z1 = cs.2.min(ce.2);
let max_x1 = cs.0.max(ce.0);
let max_y1 = cs.1.max(ce.1);
let max_z1 = cs.2.max(ce.2);
let min_x2 = es.0.min(ee.0);
let min_y2 = es.1.min(ee.1);
let min_z2 = es.2.min(ee.2);
let max_x2 = es.0.max(ee.0);
let max_y2 = es.1.max(ee.1);
let max_z2 = es.2.max(ee.2);
!((min_x1 > max_x2)
|| (max_x1 < min_x2)
|| (min_y1 > max_y2)
|| (max_y1 < min_y2)
|| (min_z1 > max_z2)
|| (max_z1 < min_z2))
}
}
fn process(data: &str) -> i64 {
let mut blocks = Vec::new();
for line in data.lines() {
let (start, end) = line.split_once('~').unwrap();
let mut start = start.split(',');
let sx = start.next().unwrap().parse::<i32>().unwrap();
let sy = start.next().unwrap().parse::<i32>().unwrap();
let sz = start.next().unwrap().parse::<i32>().unwrap();
let mut end = end.split(',');
let ex = end.next().unwrap().parse::<i32>().unwrap();
let ey = end.next().unwrap().parse::<i32>().unwrap();
let ez = end.next().unwrap().parse::<i32>().unwrap();
blocks.push(Cuboid {
start: (sx, sy, sz),
end: (ex, ey, ez),
});
}
blocks.sort_unstable_by(|a, b| a.start.2.cmp(&b.start.2));
let blocks = drop(&blocks);
count_collapsible(&blocks)
}
fn drop(blocks: &[Cuboid]) -> Vec<Cuboid> {
let mut current = blocks.to_vec();
loop {
let mut changed = false;
let mut next: Vec<Cuboid> = vec![];
for i in 0..current.len() {
let block = &current[i];
let mut new_block = *block;
new_block.start.2 -= 1;
new_block.end.2 -= 1;
if new_block.start.2 < 1 {
next.push(*block);
continue;
}
let mut intersected = false;
for other_block in current.iter().take(i) {
if new_block.intersect(*other_block) {
intersected = true;
break;
}
}
if intersected {
next.push(*block);
} else {
next.push(new_block);
changed = true
}
}
current = next;
if !changed {
break;
}
}
current
}
fn count_collapsible(v: &Vec<Cuboid>) -> i64 {
let mut out: i64 = 0;
for i in 0..v.len() {
let mut a = v.clone();
a.remove(i);
let dropped = drop(&a);
for (a, b) in a.into_iter().zip(dropped.into_iter()) {
if a != b {
out += 1;
}
}
}
out
}
fn main() {
for input in INPUTS.iter().skip(1) {
println!("answer = {}", process(input));
}
}
#[bench]
fn part1(b: &mut test::Bencher) {
b.iter(|| {
let v = process(INPUTS[INPUTS.len() - 1]);
test::black_box(v);
});
}

1429
src/day22/input.txt Normal file

File diff suppressed because it is too large Load Diff

7
src/day22/sample.txt Normal file
View File

@ -0,0 +1,7 @@
1,0,1~1,2,1
0,0,2~2,0,2
0,2,3~2,2,3
0,0,4~0,2,4
2,0,5~2,2,5
0,1,6~2,1,6
1,1,8~1,1,9