i got this to work. i do not know how.
This commit is contained in:
parent
08cffbf2d2
commit
9a217a0202
@ -1,9 +1,8 @@
|
||||
use std::{env, fs};
|
||||
use std::cmp::{max, min, Ordering};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
|
||||
struct Brick {
|
||||
start: (i32, i32, i32),
|
||||
end: (i32, i32, i32),
|
||||
@ -31,24 +30,8 @@ impl Brick {
|
||||
.collect();
|
||||
if xes.len() != 1 { return xes; }
|
||||
if yes.len() != 1 { return yes; }
|
||||
if zes.len() != 1 { return zes; }
|
||||
return Vec::new();
|
||||
return zes;
|
||||
}
|
||||
fn shadow(&self) -> Vec<(i32, i32)> {
|
||||
let mut squares = self.squares();
|
||||
squares.dedup_by(|a, b| a.2 == b.2);
|
||||
return squares.iter().map(|(x,y,_z)| (*x,*y)).collect();
|
||||
}
|
||||
fn top (&self) -> i32 {
|
||||
return max(self.start.2, self.end.2);
|
||||
}
|
||||
fn bottom (&self) -> i32 {
|
||||
return min(self.start.2, self.end.2);
|
||||
}
|
||||
}
|
||||
|
||||
fn compare_z(a: &Brick, b: &Brick) -> Ordering {
|
||||
return a.start.2.cmp(&b.start.2);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
@ -63,138 +46,121 @@ fn main() {
|
||||
let file_path = &args[1];
|
||||
let contents = fs::read_to_string(file_path).expect("Should have been able to read the file");
|
||||
|
||||
println!("soorting the bricks by z for some reason");
|
||||
let mut bricks: Vec<Brick> = contents.lines().map(|x| x.parse().unwrap()).collect();
|
||||
let mut bbs = bricks_by_shadow(&bricks);
|
||||
bricks.sort_unstable_by(compare_z);
|
||||
println!("{:?}", bricks);
|
||||
|
||||
println!("dropping bricks now");
|
||||
let mut made_changes = true;
|
||||
while made_changes {
|
||||
let mut new_bricks: Vec<Brick> = Vec::new();
|
||||
made_changes = false;
|
||||
let mut grid: HashMap<(i32, i32, i32), Brick> = HashMap::new();
|
||||
for brick in &bricks {
|
||||
if made_changes {
|
||||
new_bricks.push(brick.clone());
|
||||
} else {
|
||||
let tops = under(&brick, &bbs);
|
||||
if let Some(highest) = tops.iter().max_by_key(|a| a.top()) {
|
||||
let new_brick = lower(brick,highest);
|
||||
if new_brick != brick.clone() {
|
||||
new_bricks.push(new_brick);
|
||||
made_changes = true;
|
||||
} else {
|
||||
new_bricks.push(brick.clone());
|
||||
for coordinate in brick.squares() {
|
||||
grid.insert(coordinate, brick.clone());
|
||||
}
|
||||
} else {
|
||||
new_bricks.push(brick.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
bricks = new_bricks;
|
||||
bbs = bricks_by_shadow(&new_bricks);
|
||||
}
|
||||
|
||||
println!("bricks have been dropped: {bricks:?}");
|
||||
//println!("Bricks: {bricks:?}");
|
||||
|
||||
println!("calculating brick shadows");
|
||||
let brick_shadows = bricks_by_shadow(&bricks);
|
||||
println!("there are {} brick shadows", brick_shadows.len());
|
||||
let mut changed_things = true;
|
||||
while changed_things {
|
||||
changed_things = false;
|
||||
for brick in &mut bricks {
|
||||
let mut able_to_drop_1 = true;
|
||||
for (x, y, z) in brick.squares() {
|
||||
if z <= 0 { able_to_drop_1 = false; }
|
||||
let runs_into_something =
|
||||
grid.contains_key(&(x,y,z-1)) && !brick.squares().contains(&(x,y,z-1));
|
||||
able_to_drop_1 = able_to_drop_1 && !runs_into_something;
|
||||
}
|
||||
|
||||
if able_to_drop_1 {
|
||||
for (x, y, z) in brick.squares() {
|
||||
grid.remove(&(x,y,z));
|
||||
}
|
||||
brick.start.2 -= 1;
|
||||
brick.end.2 -= 1;
|
||||
|
||||
for (x, y, z) in brick.squares() {
|
||||
grid.insert((x, y, z), brick.clone());
|
||||
}
|
||||
//println!("dropping brick {brick:?}");
|
||||
changed_things = true;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println!("bricks have been dropped:");// {bricks:?}");
|
||||
|
||||
let mut grid: HashMap<(i32, i32, i32), Brick> = HashMap::new();
|
||||
for brick in &bricks {
|
||||
for coordinate in brick.squares() {
|
||||
grid.insert(coordinate, brick.clone());
|
||||
}
|
||||
}
|
||||
println!("looking for disintegratbale bricks");
|
||||
|
||||
let mut disintegratable_bricks: HashSet<Brick> = HashSet::new();
|
||||
for brick in &bricks {
|
||||
let mut removable = true;
|
||||
for other_brick in supported_by(brick, &brick_shadows) {
|
||||
if supporting(other_brick, &brick_shadows).len() == 1 {
|
||||
removable = false;
|
||||
}
|
||||
}
|
||||
if removable {
|
||||
if dependent_bricks(&HashSet::from([*brick]), &grid).len() == 0 {
|
||||
disintegratable_bricks.insert(brick.clone());
|
||||
}
|
||||
}
|
||||
println!("The total number of disintegratable bricks is {}", disintegratable_bricks.len());
|
||||
|
||||
println!("now we're looking for chain reactions.");
|
||||
let mut sum = 0;
|
||||
for brick in &bricks {
|
||||
let mut start = HashSet::from([*brick]);
|
||||
let mut keep_going = true;
|
||||
while keep_going {
|
||||
keep_going = false;
|
||||
let chain = dependent_bricks(&start, &grid);
|
||||
if chain.len() != 0 { keep_going = true;}
|
||||
start.extend(chain.iter());
|
||||
}
|
||||
start.remove(&brick);
|
||||
//println!("found a brick we could remove to immediately chain {} bricks", start.len());
|
||||
sum += start.len();
|
||||
}
|
||||
println!("sum is {sum}");
|
||||
}
|
||||
|
||||
fn bricks_by_shadow(bricks: &Vec<Brick>) -> HashMap<(i32, i32), Vec<&Brick>> {
|
||||
let mut bricks_by_shadow: HashMap<(i32, i32), Vec<&Brick>> = HashMap::new();
|
||||
for brick in bricks {
|
||||
for coordinate in brick.shadow() {
|
||||
if let Some(vector) = bricks_by_shadow.get_mut(&coordinate) {
|
||||
vector.push(&brick)
|
||||
} else {
|
||||
bricks_by_shadow.insert(coordinate, Vec::new());
|
||||
bricks_by_shadow.get_mut(&coordinate).unwrap().push(brick);
|
||||
}
|
||||
}
|
||||
}
|
||||
return bricks_by_shadow;
|
||||
}
|
||||
|
||||
// returns a set of bricks under the specified brick
|
||||
fn under<'a>(brick: &Brick,
|
||||
shadow_bricks: &'a HashMap<(i32, i32), Vec<&Brick>>) -> HashSet<&'a Brick>
|
||||
{
|
||||
let mut unders: HashSet<&Brick> = HashSet::new();
|
||||
for c in brick.shadow() {
|
||||
let mut top_brick: Option<&Brick> = None;
|
||||
for other_brick in shadow_bricks.get(&c).unwrap() {
|
||||
if other_brick.top() < brick.bottom() {
|
||||
if top_brick.is_none() {
|
||||
top_brick = Some(other_brick);
|
||||
} else if other_brick.top() > top_brick.unwrap().top() {
|
||||
top_brick = Some(other_brick);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if top_brick.is_some() {
|
||||
unders.insert(top_brick.unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
return unders;
|
||||
}
|
||||
|
||||
fn supporting<'a>(brick: &Brick, shadow_bricks: &'a HashMap<(i32, i32), Vec<&Brick>>) -> HashSet<&'a Brick> {
|
||||
let mut candidates: Vec<&Brick> = Vec::new();
|
||||
for coordinate in brick.shadow() {
|
||||
candidates.extend(shadow_bricks.get(&coordinate).unwrap());
|
||||
}
|
||||
|
||||
fn bricks_relying_on(brick: &Brick, grid: &HashMap<(i32, i32, i32), Brick>) -> HashSet<Brick> {
|
||||
let mut output = HashSet::new();
|
||||
for other_brick in candidates {
|
||||
if other_brick.top() == brick.bottom() - 1 {
|
||||
|
||||
for (x, y, z) in brick.squares() {
|
||||
if let Some(other_brick) = grid.get(&(x,y,z+1)) {
|
||||
if other_brick != brick {
|
||||
output.insert(other_brick.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
fn bricks_relied_on_by(brick: &Brick, grid: &HashMap<(i32, i32, i32), Brick>) -> HashSet<Brick> {
|
||||
let mut output: HashSet<Brick> = HashSet::new();
|
||||
|
||||
for (x, y, z) in brick.squares() {
|
||||
if let Some(other_brick) = grid.get(&(x,y,z-1)) {
|
||||
if other_brick != brick {
|
||||
output.insert(other_brick.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
fn dependent_bricks(missing_bricks: &HashSet<Brick>, grid: &HashMap<(i32, i32, i32), Brick>) -> HashSet<Brick> {
|
||||
let mut output = HashSet::new();
|
||||
|
||||
for brick in missing_bricks {
|
||||
let above = bricks_relying_on(brick, grid);
|
||||
for other_brick in above {
|
||||
let below = bricks_relied_on_by(&other_brick, grid);
|
||||
if below.is_subset(missing_bricks) && !missing_bricks.contains(&other_brick) {
|
||||
output.insert(other_brick);
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
fn supported_by<'a>(brick: &Brick, shadow_bricks: &'a HashMap<(i32, i32), Vec<&Brick>>) -> HashSet<&'a Brick> {
|
||||
let mut candidates: Vec<&Brick> = Vec::new();
|
||||
for coordinate in brick.shadow() {
|
||||
candidates.extend(shadow_bricks.get(&coordinate).unwrap());
|
||||
}
|
||||
|
||||
let mut output = HashSet::new();
|
||||
for other_brick in candidates {
|
||||
if other_brick.bottom() == brick.top() + 1 {
|
||||
output.insert(other_brick);
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
fn lower(brick: &Brick, below: &Brick) -> Brick {
|
||||
let mut output = brick.clone();
|
||||
let distance = brick.bottom() - below.top() - 1;
|
||||
if distance > 0 {
|
||||
output = Brick{start: (brick.start.0, brick.start.1, brick.start.2 - distance),
|
||||
end: (brick.end.0, brick.end.1, brick.end.2 - 1)};
|
||||
}
|
||||
return output;
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user