generated from fspoettel/advent-of-code-rust
-
Notifications
You must be signed in to change notification settings - Fork 0
/
18.rs
103 lines (86 loc) · 2.68 KB
/
18.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use itertools::Itertools;
advent_of_code::solution!(18);
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum Direction {
Up,
Down,
Right,
Left,
}
impl Direction {
fn transition(&self) -> (isize, isize) {
match self {
Direction::Up => (0, -1),
Direction::Down => (0, 1),
Direction::Right => (1, 0),
Direction::Left => (-1, 0),
}
}
}
fn content_of_lagoon(directions: &[(Direction, isize)]) -> isize {
let (points, exterior) = directions.iter().fold(
(vec![(0, 0)], 0),
|(mut acc, exterior), (direction, length)| {
let (x, y) = acc.last().unwrap();
let (dx, dy) = direction.transition();
acc.push((x + dx * length, y + dy * length));
(acc, exterior + length)
},
);
let area: isize = points
.iter()
.tuple_windows()
.map(|((x_minus, _), (_, y), (x_plus, _))| y * (x_minus - x_plus))
.sum();
area / 2 + exterior / 2 + 1
}
pub fn part_one(input: &str) -> Option<isize> {
let data: Vec<(Direction, isize)> = input
.lines()
.map(|line| {
let mut data = line.split(' ');
let direction = match data.next() {
Some("U") => Direction::Up,
Some("D") => Direction::Down,
Some("R") => Direction::Right,
Some("L") => Direction::Left,
_ => panic!(),
};
let length: isize = data.next().unwrap().parse().unwrap();
(direction, length)
})
.collect();
Some(content_of_lagoon(&data))
}
pub fn part_two(input: &str) -> Option<isize> {
let data: Vec<(Direction, isize)> = input
.lines()
.map(|line| {
let hexadecimal_number = line.split(' ').nth(2).unwrap();
let length = isize::from_str_radix(&hexadecimal_number[2..7], 16).unwrap();
let direction = match hexadecimal_number.chars().nth(7) {
Some('0') => Direction::Right,
Some('1') => Direction::Down,
Some('2') => Direction::Left,
Some('3') => Direction::Up,
_ => panic!(),
};
(direction, length)
})
.collect();
Some(content_of_lagoon(&data))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part_one() {
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
assert_eq!(result, Some(62));
}
#[test]
fn test_part_two() {
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
assert_eq!(result, Some(952408144115));
}
}