Skip to content

Commit 02e285c

Browse files
committed
Year 2020 speed and code quality improvements
1 parent f9fd77b commit 02e285c

File tree

5 files changed

+45
-50
lines changed

5 files changed

+45
-50
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,8 @@ Performance is reasonable even on older hardware, for example a 2011 MacBook Pro
205205
| --- | --- | --- | --: |
206206
| 1 | [Report Repair](https://adventofcode.com/2020/day/1) | [Source](src/year2020/day01.rs) | 12 |
207207
| 2 | [Password Philosophy](https://adventofcode.com/2020/day/2) | [Source](src/year2020/day02.rs) | 35 |
208-
| 3 | [Toboggan Trajectory](https://adventofcode.com/2020/day/3) | [Source](src/year2020/day03.rs) | 12 |
209-
| 4 | [Passport Processing](https://adventofcode.com/2020/day/4) | [Source](src/year2020/day04.rs) | 49 |
208+
| 3 | [Toboggan Trajectory](https://adventofcode.com/2020/day/3) | [Source](src/year2020/day03.rs) | 8 |
209+
| 4 | [Passport Processing](https://adventofcode.com/2020/day/4) | [Source](src/year2020/day04.rs) | 38 |
210210
| 5 | [Binary Boarding](https://adventofcode.com/2020/day/5) | [Source](src/year2020/day05.rs) | 11 |
211211
| 6 | [Custom Customs](https://adventofcode.com/2020/day/6) | [Source](src/year2020/day06.rs) | 35 |
212212
| 7 | [Handy Haversacks](https://adventofcode.com/2020/day/7) | [Source](src/year2020/day07.rs) | 69 |

src/year2020/day03.rs

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,29 +11,22 @@ pub fn parse(input: &str) -> Grid<u8> {
1111
Grid::parse(input)
1212
}
1313

14-
pub fn part1(input: &Grid<u8>) -> u64 {
14+
pub fn part1(input: &Grid<u8>) -> usize {
1515
toboggan(input, 3, 1)
1616
}
1717

18-
pub fn part2(input: &Grid<u8>) -> u64 {
19-
toboggan(input, 1, 1)
20-
* toboggan(input, 3, 1)
21-
* toboggan(input, 5, 1)
22-
* toboggan(input, 7, 1)
23-
* toboggan(input, 1, 2)
18+
pub fn part2(input: &Grid<u8>) -> usize {
19+
[(1, 1), (3, 1), (5, 1), (7, 1), (1, 2)]
20+
.into_iter()
21+
.map(|(dx, dy)| toboggan(input, dx, dy))
22+
.product()
2423
}
2524

26-
fn toboggan(grid: &Grid<u8>, dx: i32, dy: i32) -> u64 {
27-
let mut point = ORIGIN;
28-
let mut trees = 0;
29-
30-
while point.y < grid.height {
31-
if grid[point] == b'#' {
32-
trees += 1;
33-
}
34-
point.x = (point.x + dx) % grid.width;
35-
point.y += dy;
36-
}
37-
38-
trees
25+
fn toboggan(grid: &Grid<u8>, dx: i32, dy: i32) -> usize {
26+
(0..grid.height / dy)
27+
.filter(|&i| {
28+
let point = Point::new((i * dx) % grid.width, i * dy);
29+
grid[point] == b'#'
30+
})
31+
.count()
3932
}

src/year2020/day04.rs

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,36 +5,44 @@
55
//! maximize speed we'll instead hand code validation functions for each of the
66
//! passport field criteria.
77
use crate::util::iter::*;
8+
use crate::util::parse::*;
89
use std::ops::RangeInclusive;
910

10-
type Passport<'a> = Vec<[&'a str; 2]>;
11+
type Input = (u32, u32);
1112

12-
pub fn parse(input: &str) -> Vec<Passport<'_>> {
13-
input.split("\n\n").map(parse_block).collect()
14-
}
13+
pub fn parse(input: &str) -> Input {
14+
let mut passport = Vec::new();
15+
let mut part_one = 0;
16+
let mut part_two = 0;
17+
18+
for block in input.split("\n\n") {
19+
parse_block(&mut passport, block);
20+
21+
if passport.len() == 7 {
22+
part_one += 1;
23+
part_two += passport.iter().all(validate_field) as u32;
24+
}
1525

16-
pub fn part1(input: &[Passport<'_>]) -> usize {
17-
input.iter().filter(|passport| passport.len() == 7).count()
26+
passport.clear();
27+
}
28+
29+
(part_one, part_two)
1830
}
1931

20-
pub fn part2(input: &[Passport<'_>]) -> usize {
21-
input
22-
.iter()
23-
.filter(|passport| passport.len() == 7)
24-
.filter(|passport| passport.iter().all(validate_field))
25-
.count()
32+
pub fn part1(input: &Input) -> u32 {
33+
input.0
2634
}
2735

28-
fn parse_block(block: &str) -> Passport<'_> {
29-
let mut fields = Vec::with_capacity(7);
36+
pub fn part2(input: &Input) -> u32 {
37+
input.1
38+
}
3039

40+
fn parse_block<'a>(passport: &mut Vec<[&'a str; 2]>, block: &'a str) {
3141
for pair @ [key, _] in block.split([':', ' ', '\n']).chunk::<2>() {
3242
if key != "cid" {
33-
fields.push(pair);
43+
passport.push(pair);
3444
}
3545
}
36-
37-
fields
3846
}
3947

4048
fn validate_field(&[key, value]: &[&str; 2]) -> bool {
@@ -51,7 +59,7 @@ fn validate_field(&[key, value]: &[&str; 2]) -> bool {
5159
}
5260

5361
fn validate_range(s: &str, range: RangeInclusive<u32>) -> bool {
54-
s.parse().is_ok_and(|n| range.contains(&n))
62+
range.contains(&s.unsigned())
5563
}
5664

5765
fn validate_height(hgt: &str) -> bool {

src/year2020/day05.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,10 @@ pub struct Input {
1313
}
1414

1515
pub fn parse(input: &str) -> Input {
16-
let mut min = u32::MAX;
17-
let mut max = u32::MIN;
18-
let mut xor = 0;
19-
20-
for line in input.lines() {
16+
let (min, max, xor) = input.lines().fold((u32::MAX, u32::MIN, 0), |(min, max, xor), line| {
2117
let id = line.bytes().fold(0, |acc, b| (acc << 1) | (b == b'B' || b == b'R') as u32);
22-
min = min.min(id);
23-
max = max.max(id);
24-
xor ^= id;
25-
}
18+
(min.min(id), max.max(id), xor ^ id)
19+
});
2620

2721
Input { min, max, xor }
2822
}

src/year2020/day18.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ fn next(bytes: &mut Bytes<'_>) -> Option<u8> {
7070

7171
/// Convenience wrapper to return the value of either the next raw digit literal or a
7272
/// sub-expression nested in parentheses.
73-
fn value(bytes: &mut Bytes<'_>, helper: impl Fn(&mut Bytes<'_>) -> u64) -> u64 {
73+
fn value(bytes: &mut Bytes<'_>, helper: fn(&mut Bytes<'_>) -> u64) -> u64 {
7474
match next(bytes).unwrap() {
7575
b'(' => helper(bytes),
7676
b => b.to_decimal() as u64,

0 commit comments

Comments
 (0)