Skip to content

Commit 966c31f

Browse files
committed
WIP need to count inner sides
1 parent 6b1e289 commit 966c31f

File tree

2 files changed

+100
-44
lines changed

2 files changed

+100
-44
lines changed

day12/src/main.rs

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,41 @@ impl UnweightedGraph for Map {
1616
}
1717
}
1818

19+
fn sides(region: &HashSet<Vec2D>, map: &Map) -> usize {
20+
if region.len() == 1 {
21+
return 4;
22+
}
23+
24+
let top_left = region.iter().min_by_key(|pos| pos.x + pos.y).unwrap();
25+
26+
let mut sides = 0;
27+
28+
let mut normal = Vec2D::new(0, -1);
29+
let mut pos = *top_left;
30+
31+
loop {
32+
if !region.contains(&(pos + normal)) && !region.contains(&(pos + normal.rotated_right())) {
33+
normal = normal.rotated_right();
34+
sides += 1;
35+
} else if region.contains(&(pos + normal.rotated_right()))
36+
&& region.contains(&(pos + normal.rotated_right() + normal))
37+
{
38+
pos = pos + normal.rotated_right() + normal;
39+
normal = normal.rotated_left();
40+
sides += 1;
41+
} else {
42+
pos += normal.rotated_right();
43+
}
44+
if pos == *top_left && normal == (0, -1) {
45+
break;
46+
}
47+
}
48+
49+
println!("region {} has {sides} sides", map[*top_left]);
50+
51+
sides
52+
}
53+
1954
#[aoc_main]
2055
fn solve(input: Input) -> impl Into<Solution> {
2156
let map = Map::from(input.char_grid());
@@ -49,7 +84,14 @@ fn solve(input: Input) -> impl Into<Solution> {
4984
})
5085
.sum_usize();
5186

52-
(part1)
87+
let part2 = region_map
88+
.iter()
89+
.map(|(c, regions)| {
90+
regions.iter().map(|region| region.len() * sides(region, &map)).sum_usize()
91+
})
92+
.sum_usize();
93+
94+
(part1, part2)
5395
}
5496

5597
#[cfg(test)]
@@ -59,11 +101,13 @@ mod tests {
59101
fn test_examples() {
60102
use utils::assert_example;
61103
assert_example!(
62-
r#"AAAA
104+
r#"
105+
AAAA
63106
BBCD
64107
BBCC
65108
EEEC"#,
66-
"140"
109+
140,
110+
80
67111
);
68112

69113
assert_example!(
@@ -88,5 +132,24 @@ MIIISIJEEE
88132
MMMISSJEEE",
89133
1930
90134
);
135+
136+
assert_part2!(
137+
"EEEEE
138+
EXXXX
139+
EEEEE
140+
EXXXX
141+
EEEEE",
142+
236
143+
);
144+
145+
assert_part2!(
146+
"AAAAAA
147+
AAABBA
148+
AAABBA
149+
ABBAAA
150+
ABBAAA
151+
AAAAAA",
152+
368
153+
);
91154
}
92155
}

utils/src/math/vec2d.rs

Lines changed: 34 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
use parse_display::FromStr;
22

3-
#[derive(Copy, Clone, Debug, Eq, Hash, FromStr, PartialOrd, Ord)]
3+
#[derive(Copy, Clone, Debug, Eq, Hash, FromStr, PartialOrd, Ord, derive_more::Display)]
4+
#[display("({x}, {y})")]
45
// Parses [1, 2] or (1, 2) or {1, 2}
56
#[from_str(regex = r"[\[\(\{](?<x>-?\d+),\s*(?<y>-?\d+)[\]\)\}]")]
67
pub struct Vec2D {
78
pub x: i64,
89
pub y: i64,
910
}
1011

11-
impl<T> PartialEq<T> for Vec2D where T: Into<Vec2D> + Copy {
12+
impl<T> PartialEq<T> for Vec2D
13+
where
14+
T: Into<Vec2D> + Copy,
15+
{
1216
fn eq(&self, other: &T) -> bool {
1317
let other: Vec2D = (*other).into();
1418
self.x == other.x && self.y == other.y
@@ -70,25 +74,15 @@ impl Vec2D {
7074
}
7175

7276
pub fn diagonal_neighbors(&self) -> impl Iterator<Item = Vec2D> + '_ {
73-
[
74-
Vec2D { x: 1, y: 1 },
75-
Vec2D { x: -1, y: 1 },
76-
Vec2D { x: 1, y: -1 },
77-
Vec2D { x: -1, y: -1 },
78-
]
79-
.iter()
80-
.map(move |&dir| *self + dir)
77+
[Vec2D { x: 1, y: 1 }, Vec2D { x: -1, y: 1 }, Vec2D { x: 1, y: -1 }, Vec2D { x: -1, y: -1 }]
78+
.iter()
79+
.map(move |&dir| *self + dir)
8180
}
8281

8382
pub fn orthogonal_neighbors(&self) -> impl Iterator<Item = Vec2D> + '_ {
84-
[
85-
Vec2D { x: 1, y: 0 },
86-
Vec2D { x: -1, y: 0 },
87-
Vec2D { x: 0, y: 1 },
88-
Vec2D { x: 0, y: -1 },
89-
]
90-
.iter()
91-
.map(move |&dir| *self + dir)
83+
[Vec2D { x: 1, y: 0 }, Vec2D { x: -1, y: 0 }, Vec2D { x: 0, y: 1 }, Vec2D { x: 0, y: -1 }]
84+
.iter()
85+
.map(move |&dir| *self + dir)
9286
}
9387

9488
pub fn all_neighbors(&self) -> impl Iterator<Item = Vec2D> + '_ {
@@ -128,14 +122,11 @@ where
128122
type Output = Vec2D;
129123

130124
fn mul(self, rhs: T) -> Self::Output {
131-
Vec2D::new(
132-
self.x * rhs.to_i64().unwrap(),
133-
self.y * rhs.to_i64().unwrap(),
134-
)
125+
Vec2D::new(self.x * rhs.to_i64().unwrap(), self.y * rhs.to_i64().unwrap())
135126
}
136127
}
137128

138-
impl <T> std::ops::MulAssign<T> for Vec2D
129+
impl<T> std::ops::MulAssign<T> for Vec2D
139130
where
140131
T: num::ToPrimitive + num::Integer,
141132
{
@@ -151,7 +142,7 @@ macro_rules! impl_left_mul {
151142
$(
152143
impl std::ops::Mul<Vec2D> for $t {
153144
type Output = Vec2D;
154-
145+
155146
fn mul(self, rhs: Vec2D) -> Self::Output {
156147
rhs * self
157148
}
@@ -161,7 +152,10 @@ macro_rules! impl_left_mul {
161152
}
162153
impl_left_mul!(i8, i16, i32, i64, isize, u8, u16, u32, u64, usize);
163154

164-
impl<T> std::ops::Add<T> for Vec2D where T: Into<Vec2D> {
155+
impl<T> std::ops::Add<T> for Vec2D
156+
where
157+
T: Into<Vec2D>,
158+
{
165159
type Output = Vec2D;
166160

167161
fn add(self, rhs: T) -> Self::Output {
@@ -170,13 +164,19 @@ impl<T> std::ops::Add<T> for Vec2D where T: Into<Vec2D> {
170164
}
171165
}
172166

173-
impl<T> std::ops::AddAssign<T> for Vec2D where T: Into<Vec2D> {
167+
impl<T> std::ops::AddAssign<T> for Vec2D
168+
where
169+
T: Into<Vec2D>,
170+
{
174171
fn add_assign(&mut self, rhs: T) {
175172
*self = *self + rhs;
176173
}
177174
}
178175

179-
impl<T> std::ops::Sub<T> for Vec2D where T: Into<Vec2D> {
176+
impl<T> std::ops::Sub<T> for Vec2D
177+
where
178+
T: Into<Vec2D>,
179+
{
180180
type Output = Vec2D;
181181

182182
fn sub(self, rhs: T) -> Self::Output {
@@ -185,7 +185,10 @@ impl<T> std::ops::Sub<T> for Vec2D where T: Into<Vec2D> {
185185
}
186186
}
187187

188-
impl<T> std::ops::SubAssign<T> for Vec2D where T: Into<Vec2D> {
188+
impl<T> std::ops::SubAssign<T> for Vec2D
189+
where
190+
T: Into<Vec2D>,
191+
{
189192
fn sub_assign(&mut self, rhs: T) {
190193
*self = *self - rhs;
191194
}
@@ -246,7 +249,7 @@ mod tests {
246249
assert_eq!(Vec2D::new(1, -2).manhattan_dist(), 3);
247250
}
248251

249-
#[test]
252+
#[test]
250253
fn inside_box() {
251254
assert!(Vec2D::new(1, 2).inside_box((0, 0), (2, 3)));
252255
assert!(Vec2D::new(1, 2).inside_box((1, 2), (1, 2)));
@@ -275,21 +278,11 @@ mod tests {
275278
#[test]
276279
fn neighbors() {
277280
assert_eq!(
278-
HashSet::from([
279-
Vec2D::new(2, 2),
280-
Vec2D::new(0, 2),
281-
Vec2D::new(1, 3),
282-
Vec2D::new(1, 1)
283-
]),
281+
HashSet::from([Vec2D::new(2, 2), Vec2D::new(0, 2), Vec2D::new(1, 3), Vec2D::new(1, 1)]),
284282
Vec2D::new(1, 2).orthogonal_neighbors().collect(),
285283
);
286284
assert_eq!(
287-
HashSet::from([
288-
Vec2D::new(2, 3),
289-
Vec2D::new(0, 3),
290-
Vec2D::new(2, 1),
291-
Vec2D::new(0, 1)
292-
]),
285+
HashSet::from([Vec2D::new(2, 3), Vec2D::new(0, 3), Vec2D::new(2, 1), Vec2D::new(0, 1)]),
293286
Vec2D::new(1, 2).diagonal_neighbors().collect(),
294287
);
295288
assert_eq!(

0 commit comments

Comments
 (0)