day22: added
This commit is contained in:
parent
5dd5dc53d5
commit
2b4ffe5fbe
137
src/day22/1.rs
137
src/day22/1.rs
|
@ -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 = ¤t[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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
141
src/day22/2.rs
141
src/day22/2.rs
|
@ -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 = ¤t[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
1429
src/day22/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
7
src/day22/sample.txt
Normal file
7
src/day22/sample.txt
Normal 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
|
Loading…
Reference in New Issue
Block a user