Use address halos to calculate part halos

This commit is contained in:
Savanni D'Gerinel 2023-12-03 13:48:50 -05:00
parent 234f53b8b5
commit 8d034b83f9
1 changed files with 74 additions and 35 deletions

View File

@ -22,6 +22,32 @@ struct Addr {
col: usize, col: usize,
} }
impl Addr {
fn halo(&self) -> impl Iterator<Item = Addr> {
let row = self.row as i32;
let col = self.col as i32;
vec![
(row - 1, col - 1),
(row, col - 1),
(row + 1, col - 1),
//
(row - 1, col),
(row, col),
(row + 1, col),
//
(row - 1, col + 1),
(row, col + 1),
(row + 1, col + 1),
]
.into_iter()
.filter(|(row, col)| *row >= 0 && *col >= 0)
.map(|(row, col)| Addr {
row: row as usize,
col: col as usize,
})
}
}
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
struct Part { struct Part {
value: u32, value: u32,
@ -31,39 +57,38 @@ struct Part {
} }
impl Part { impl Part {
fn span(&self) -> Vec<Addr> { fn span<'a>(&'a self) -> impl Iterator<Item = Addr> + 'a {
(self.start..self.end + 1) (self.start..self.end + 1).map(|addr| Addr {
.map(|addr| Addr { row: self.row,
row: self.row, col: addr,
col: addr, })
})
.collect()
} }
fn halo(&self, max_row: usize, max_col: usize) -> Vec<Addr> { fn halo<'a>(&'a self, max_row: usize, max_col: usize) -> impl IntoIterator<Item = Addr> {
let mut halo: Vec<(i32, i32)> = vec![]; println!("{:?}", self);
let addresses = self
for r in self.start..self.end + 1 { .span()
halo.push((self.row as i32 - 1, r as i32)); .map(|addr| addr.halo())
halo.push((self.row as i32 + 1, r as i32)); .flatten()
} .filter(|Addr { row, col }| {
*row as i32 >= 0
halo.push((self.row as i32 - 1, self.start as i32 - 1)); && *row as i32 <= max_row as i32
halo.push((self.row as i32, self.start as i32 - 1)); && *col as i32 >= 0
halo.push((self.row as i32 + 1, self.start as i32 - 1)); && *col as i32 <= max_col as i32
halo.push((self.row as i32 - 1, self.end as i32 + 1));
halo.push((self.row as i32, self.end as i32 + 1));
halo.push((self.row as i32 + 1, self.end as i32 + 1));
halo.into_iter()
.filter(|(row, col)| {
*row >= 0 && *row <= max_row as i32 && *col >= 0 && *col <= max_col as i32
}) })
.map(|(row, col)| Addr { .fold(HashSet::new(), |mut acc, val| {
row: row as usize, let _ = acc.insert(val);
col: col as usize, acc
}) });
.collect()
println!("{:?}", addresses);
println!("{:?}", self.span().collect::<HashSet<Addr>>());
println!("{:?}", addresses.difference(&self.span().collect()));
addresses
.difference(&self.span().collect())
.map(|addr| addr.clone())
.collect::<HashSet<Addr>>()
} }
} }
@ -112,8 +137,10 @@ fn find_gears(schematic: String) -> Vec<Gear> {
end: addr.col, end: addr.col,
} }
.halo(max_row - 1, max_col - 1) .halo(max_row - 1, max_col - 1)
.into_iter()
.collect::<HashSet<Addr>>()
}) })
.collect::<Vec<Vec<Addr>>>(); .collect::<Vec<HashSet<Addr>>>();
let mut gears = vec![]; let mut gears = vec![];
for splat in splats { for splat in splats {
@ -130,7 +157,7 @@ fn find_gears(schematic: String) -> Vec<Gear> {
gears gears
} }
fn part_within_halo(halo1: Vec<Addr>, part: Part) -> bool { fn part_within_halo(halo1: impl IntoIterator<Item = Addr>, part: Part) -> bool {
let halo1: HashSet<Addr> = halo1.into_iter().collect::<HashSet<Addr>>(); let halo1: HashSet<Addr> = halo1.into_iter().collect::<HashSet<Addr>>();
let halo2: HashSet<Addr> = part.span().into_iter().collect::<HashSet<Addr>>(); let halo2: HashSet<Addr> = part.span().into_iter().collect::<HashSet<Addr>>();
@ -352,7 +379,9 @@ mod test {
end: 2, end: 2,
}; };
assert_eq!( assert_eq!(
part.halo(schematic.len() - 1, schematic[0].len() - 1), part.halo(schematic.len() - 1, schematic[0].len() - 1)
.into_iter()
.collect::<HashSet<Addr>>(),
vec![ vec![
Addr { row: 1, col: 0 }, Addr { row: 1, col: 0 },
Addr { row: 1, col: 1 }, Addr { row: 1, col: 1 },
@ -360,6 +389,8 @@ mod test {
Addr { row: 0, col: 3 }, Addr { row: 0, col: 3 },
Addr { row: 1, col: 3 } Addr { row: 1, col: 3 }
] ]
.into_iter()
.collect::<HashSet<Addr>>()
); );
assert_eq!( assert_eq!(
@ -369,7 +400,9 @@ mod test {
start: 1, start: 1,
end: 1 end: 1
} }
.halo(schematic.len() - 1, schematic[0].len() - 1), .halo(schematic.len() - 1, schematic[0].len() - 1)
.into_iter()
.collect::<HashSet<Addr>>(),
vec![ vec![
Addr { row: 0, col: 1 }, Addr { row: 0, col: 1 },
Addr { row: 2, col: 1 }, Addr { row: 2, col: 1 },
@ -380,6 +413,8 @@ mod test {
Addr { row: 1, col: 2 }, Addr { row: 1, col: 2 },
Addr { row: 2, col: 2 } Addr { row: 2, col: 2 }
] ]
.into_iter()
.collect::<HashSet<Addr>>()
); );
assert_eq!( assert_eq!(
Part { Part {
@ -388,7 +423,9 @@ mod test {
start: 2, start: 2,
end: 4, end: 4,
} }
.halo(schematic.len() - 1, schematic[0].len() - 1), .halo(schematic.len() - 1, schematic[0].len() - 1)
.into_iter()
.collect::<HashSet<Addr>>(),
vec![ vec![
Addr { row: 5, col: 2 }, Addr { row: 5, col: 2 },
Addr { row: 7, col: 2 }, Addr { row: 7, col: 2 },
@ -403,6 +440,8 @@ mod test {
Addr { row: 6, col: 5 }, Addr { row: 6, col: 5 },
Addr { row: 7, col: 5 }, Addr { row: 7, col: 5 },
] ]
.into_iter()
.collect::<HashSet<Addr>>()
); );
} }