Skip to content

Commit be0547b

Browse files
committed
Improve day 1-4 solutions
1 parent 7ccfaa5 commit be0547b

File tree

4 files changed

+91
-60
lines changed

4 files changed

+91
-60
lines changed

src/day01.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ pub struct Day {
77
}
88

99
impl Puzzle for Day {
10+
/// We are given two lists of integers and asked to find the total Manhattan distance between
11+
/// the two lists in their sorted orders.
12+
///
13+
/// Time complexity: O(n log n)
14+
/// Auxiliary space complexity: O(1)
1015
fn solve_part_1(&self) -> String {
1116
let mut left = self.left.clone();
1217
let mut right = self.right.clone();
@@ -19,23 +24,27 @@ impl Puzzle for Day {
1924
.to_string()
2025
}
2126

27+
/// We are given a set of two lists and asked to calculate a similarity score based on element
28+
/// frequency.
29+
///
30+
/// Time complexity: O(n)
31+
/// Auxiliary space complexity: O(n)
2232
fn solve_part_2(&self) -> String {
2333
let mut freq = HashMap::new();
24-
for r in self.right.iter() {
25-
*freq.entry(r).or_insert(0) += 1;
34+
for &num in &self.right {
35+
*freq.entry(num).or_insert(0) += 1;
2636
}
2737
self.left
2838
.iter()
29-
.filter_map(|&i| freq.get(&i).map(|&c| i * c))
39+
.map(|&num| num * freq.get(&num).copied().unwrap_or(0))
3040
.sum::<i32>()
3141
.to_string()
3242
}
3343
}
3444

3545
impl Day {
3646
pub fn create(input: &str) -> Box<dyn Puzzle> {
37-
let mut left = Vec::new();
38-
let mut right = Vec::new();
47+
let (mut left, mut right) = (Vec::new(), Vec::new());
3948
for line in input.lines() {
4049
let mut parts = line.split_whitespace();
4150
left.push(parts.next().unwrap().parse().unwrap());

src/day02.rs

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ pub struct Day {
55
}
66

77
impl Puzzle for Day {
8+
/// We're given sequences of integers and asked to determine if they meet certain properties.
9+
///
10+
/// Time complexity: O(n) per report
11+
/// Auxiliary space complexity: O(1)
812
fn solve_part_1(&self) -> String {
913
self.levels
1014
.iter()
@@ -13,6 +17,11 @@ impl Puzzle for Day {
1317
.to_string()
1418
}
1519

20+
/// We're given sequences of integers and asked to determine if they would meet certain
21+
/// properties if at most one element were removed.
22+
///
23+
/// Time complexity: O(n^2) per report (can be optimized to O(n)).
24+
/// Auxiliary space complexity: O(n) per report (can be optimized to O(1)).
1625
fn solve_part_2(&self) -> String {
1726
self.levels
1827
.iter()
@@ -27,9 +36,13 @@ fn is_safe_with_removal(level: &[i32]) -> bool {
2736
return true;
2837
}
2938
for i in 0..level.len() {
30-
let mut modified = level.to_vec();
31-
modified.remove(i);
32-
if is_safe(&modified) {
39+
if is_safe(
40+
&level
41+
.iter()
42+
.enumerate()
43+
.filter_map(|(index, &val)| if index == i { None } else { Some(val) })
44+
.collect::<Vec<_>>(),
45+
) {
3346
return true;
3447
}
3548
}
@@ -56,14 +69,14 @@ fn is_safe(level: &[i32]) -> bool {
5669

5770
impl Day {
5871
pub fn create(input: &str) -> Box<dyn Puzzle> {
59-
let mut levels = Vec::new();
60-
for line in input.lines() {
61-
let mut level = Vec::new();
62-
for part in line.split_whitespace() {
63-
level.push(part.parse().unwrap());
64-
}
65-
levels.push(level);
66-
}
72+
let levels = input
73+
.lines()
74+
.map(|line| {
75+
line.split_whitespace()
76+
.map(|num| num.parse().unwrap())
77+
.collect()
78+
})
79+
.collect();
6780
Box::new(Day { levels })
6881
}
6982
}

src/day03.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ pub struct Day {
66
}
77

88
impl Puzzle for Day {
9+
/// We're given a string to parse that contains multiply instructions, and we're asked to find
10+
/// the sum of the results of each multiplication.
11+
///
12+
/// Time complexity: O(n)
13+
/// Auxiliary space complexity: O(1)
914
fn solve_part_1(&self) -> String {
1015
let re = regex!(r"mul\((\d+),(\d+)\)");
1116
re.captures_iter(&self.memory)
@@ -14,6 +19,12 @@ impl Puzzle for Day {
1419
.to_string()
1520
}
1621

22+
/// We're given a string to parse that contains multiply instructions and state instructions,
23+
/// and we're asked to find the sum of the results of each multiplication that takes place in a
24+
/// given state.
25+
///
26+
/// Time complexity: O(n)
27+
/// Auxiliary space complexity: O(1)
1728
fn solve_part_2(&self) -> String {
1829
let re = regex!(r"(?:do\(\))|(?:don't\(\))|mul\((\d+),(\d+)\)");
1930
let mut sum = 0;

src/day04.rs

Lines changed: 42 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ pub struct Day {
55
}
66

77
impl Puzzle for Day {
8+
/// We're given a grid of characters and asked to count the number of occurrences of a string
9+
/// in any direction.
10+
///
11+
/// Time complexity: O(n*m)
12+
/// Auxiliary space complexity: O(1)
813
fn solve_part_1(&self) -> String {
914
let mut count = 0;
1015
for row in 0..self.grid.len() {
@@ -15,6 +20,11 @@ impl Puzzle for Day {
1520
count.to_string()
1621
}
1722

23+
/// We're given a grid of characters and asked to count the number of occurrences of a
24+
/// particular pattern in the grid.
25+
///
26+
/// Time complexity: O(n*m)
27+
/// Auxiliary space complexity: O(1)
1828
fn solve_part_2(&self) -> String {
1929
let mut count = 0;
2030
for row in 0..self.grid.len() {
@@ -28,67 +38,55 @@ impl Puzzle for Day {
2838
}
2939
}
3040

31-
static XMAS: &str = "XMAS";
32-
3341
fn count_xmas(grid: &[Vec<char>], row: usize, col: usize) -> i32 {
34-
let mut count = 0;
35-
for drow in -1..=1 {
36-
for dcol in -1..=1 {
37-
if drow == 0 && dcol == 0 {
38-
continue;
39-
}
40-
if is_xmas(grid, row as isize, col as isize, (drow, dcol)) {
41-
count += 1;
42-
}
43-
}
44-
}
45-
count
42+
const DIRECTIONS: [(i8, i8); 8] = [
43+
(-1, -1),
44+
(-1, 0),
45+
(-1, 1),
46+
(0, -1),
47+
(0, 1),
48+
(1, -1),
49+
(1, 0),
50+
(1, 1),
51+
];
52+
DIRECTIONS
53+
.iter()
54+
.filter(|&&dir| is_xmas(grid, row as isize, col as isize, dir))
55+
.count() as i32
4656
}
4757

4858
fn is_xmas(grid: &[Vec<char>], mut row: isize, mut col: isize, dir: (i8, i8)) -> bool {
49-
let mut i = 0;
50-
while in_bounds(grid, row, col) && i < XMAS.len() {
51-
if grid[row as usize][col as usize] != XMAS.chars().nth(i).unwrap() {
59+
const XMAS: &str = "XMAS";
60+
for expected in XMAS.chars() {
61+
if !in_bounds(grid, row, col) || grid[row as usize][col as usize] != expected {
5262
return false;
5363
}
5464
row += dir.0 as isize;
5565
col += dir.1 as isize;
56-
i += 1;
5766
}
58-
i == 4
67+
true
5968
}
6069

6170
fn is_x_mas(grid: &[Vec<char>], row: isize, col: isize) -> bool {
62-
if grid[row as usize][col as usize] != 'A'
63-
|| !in_bounds(grid, row - 1, col - 1)
64-
|| !in_bounds(grid, row - 1, col + 1)
65-
|| !in_bounds(grid, row + 1, col - 1)
66-
|| !in_bounds(grid, row + 1, col + 1)
67-
{
71+
if grid[row as usize][col as usize] != 'A' {
6872
return false;
6973
}
70-
let up_left = grid[(row - 1) as usize][(col - 1) as usize];
71-
let up_right = grid[(row - 1) as usize][(col + 1) as usize];
72-
let down_left = grid[(row + 1) as usize][(col - 1) as usize];
73-
let down_right = grid[(row + 1) as usize][(col + 1) as usize];
74-
let mut matches = 0;
75-
if up_left == 'M' && down_right == 'S' {
76-
matches += 1;
77-
}
78-
if up_left == 'S' && down_right == 'M' {
79-
matches += 1;
80-
}
81-
if up_right == 'M' && down_left == 'S' {
82-
matches += 1;
83-
}
84-
if up_right == 'S' && down_left == 'M' {
85-
matches += 1;
86-
}
87-
matches == 2
74+
let diagonals = [
75+
((row - 1, col - 1), (row + 1, col + 1)),
76+
((row - 1, col + 1), (row + 1, col - 1)),
77+
];
78+
diagonals.iter().all(|&(loc1, loc2)| {
79+
if !in_bounds(grid, loc1.0, loc1.1) || !in_bounds(grid, loc2.0, loc2.1) {
80+
return false;
81+
}
82+
let val1 = grid[loc1.0 as usize][loc1.1 as usize];
83+
let val2 = grid[loc2.0 as usize][loc2.1 as usize];
84+
(val1 == 'M' && val2 == 'S') || (val1 == 'S' && val2 == 'M')
85+
})
8886
}
8987

9088
fn in_bounds(grid: &[Vec<char>], row: isize, col: isize) -> bool {
91-
row >= 0 && row < grid.len() as isize && col >= 0 && col < grid[0].len() as isize
89+
row >= 0 && (row as usize) < grid.len() && col >= 0 && (col as usize) < grid[0].len()
9290
}
9391

9492
impl Day {

0 commit comments

Comments
 (0)