Skip to content

Commit 16b1a37

Browse files
committed
improvements
1 parent 063996d commit 16b1a37

File tree

24 files changed

+441
-723
lines changed

24 files changed

+441
-723
lines changed

README.md

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,33 +11,33 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.
1111

1212
| Day | Part 1 | Part 2 |
1313
| :---: | :---: | :---: |
14-
| [Day 1](./src/bin/01.rs) | `777.4µs` | `1.5ms` |
15-
| [Day 2](./src/bin/02.rs) | `51.3µs` | `51.7µs` |
16-
| [Day 3](./src/bin/03.rs) | `443.7µs` | `486.8µs` |
17-
| [Day 4](./src/bin/04.rs) | `175.8µs` | `181.3µs` |
18-
| [Day 5](./src/bin/05.rs) | `98.9µs` | `99.1µs` |
19-
| [Day 6](./src/bin/06.rs) | `203.0ns` | `800.0ns` |
20-
| [Day 7](./src/bin/07.rs) | `395.7µs` | `396.9µs` |
21-
| [Day 8](./src/bin/08.rs) | `310.2µs` | `1.4ms` |
22-
| [Day 9](./src/bin/09.rs) | `291.8µs` | `301.6µs` |
23-
| [Day 10](./src/bin/10.rs) | `1.7ms` | `1.7ms` |
24-
| [Day 11](./src/bin/11.rs) | `255.9µs` | `259.0µs` |
25-
| [Day 12](./src/bin/12.rs) | `2.4ms` | `73.3ms` |
26-
| [Day 13](./src/bin/13.rs) | `136.1µs` | `140.3µs` |
27-
| [Day 14](./src/bin/14.rs) | `251.9µs` | `161.8ms` |
28-
| [Day 15](./src/bin/15.rs) | `77.2µs` | `253.0µs` |
29-
| [Day 16](./src/bin/16.rs) | `1.2ms` | `296.8ms` |
30-
| [Day 17](./src/bin/17.rs) | `86.9ms` | `365.8ms` |
31-
| [Day 18](./src/bin/18.rs) | `40.4µs` | `41.3µs` |
32-
| [Day 19](./src/bin/19.rs) | `340.2µs` | `570.5µs` |
33-
| [Day 20](./src/bin/20.rs) | `2.0ms` | `8.0ms` |
34-
| [Day 21](./src/bin/21.rs) | `2.0ms` | `34.9ms` |
35-
| [Day 22](./src/bin/22.rs) | `2.8ms` | `25.4ms` |
36-
| [Day 23](./src/bin/23.rs) | `895.0µs` | `307.4ms` |
37-
| [Day 24](./src/bin/24.rs) | `527.2µs` | `102.1µs` |
38-
| [Day 25](./src/bin/25.rs) | `19.5ms` | `26.0ns` |
39-
40-
**Total: 1404.45ms**
14+
| [Day 1](./src/bin/01.rs) | `780.4µs` | `1.5ms` |
15+
| [Day 2](./src/bin/02.rs) | `46.4µs` | `46.4µs` |
16+
| [Day 3](./src/bin/03.rs) | `207.6µs` | `241.4µs` |
17+
| [Day 4](./src/bin/04.rs) | `99.3µs` | `100.1µs` |
18+
| [Day 5](./src/bin/05.rs) | `69.4µs` | `74.0µs` |
19+
| [Day 6](./src/bin/06.rs) | `111.0ns` | `667.0ns` |
20+
| [Day 7](./src/bin/07.rs) | `356.6µs` | `357.5µs` |
21+
| [Day 8](./src/bin/08.rs) | `291.2µs` | `1.3ms` |
22+
| [Day 9](./src/bin/09.rs) | `218.9µs` | `219.8µs` |
23+
| [Day 10](./src/bin/10.rs) | `1.3ms` | `1.3ms` |
24+
| [Day 11](./src/bin/11.rs) | `164.2µs` | `164.6µs` |
25+
| [Day 12](./src/bin/12.rs) | `2.3ms` | `62.0ms` |
26+
| [Day 13](./src/bin/13.rs) | `63.4µs` | `68.3µs` |
27+
| [Day 14](./src/bin/14.rs) | `220.2µs` | `143.5ms` |
28+
| [Day 15](./src/bin/15.rs) | `71.0µs` | `222.1µs` |
29+
| [Day 16](./src/bin/16.rs) | `922.9µs` | `240.2ms` |
30+
| [Day 17](./src/bin/17.rs) | `52.2ms` | `178.5ms` |
31+
| [Day 18](./src/bin/18.rs) | `33.3µs` | `32.9µs` |
32+
| [Day 19](./src/bin/19.rs) | `269.9µs` | `487.2µs` |
33+
| [Day 20](./src/bin/20.rs) | `1.9ms` | `8.0ms` |
34+
| [Day 21](./src/bin/21.rs) | `1.7ms` | `32.5ms` |
35+
| [Day 22](./src/bin/22.rs) | `2.6ms` | `24.1ms` |
36+
| [Day 23](./src/bin/23.rs) | `788.5µs` | `296.9ms` |
37+
| [Day 24](./src/bin/24.rs) | `512.2µs` | `98.5µs` |
38+
| [Day 25](./src/bin/25.rs) | `13.2ms` | `23.0ns` |
39+
40+
**Total: 1072.23ms**
4141
<!--- benchmarking table --->
4242

4343
---

src/bin/01.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,8 @@ fn part_x(data: Vec<&str>, digit_map: FastMap<&str, u8>) -> u32 {
2121
}
2222
}
2323

24-
let mut tmp_result_iter = tmp_result.into_iter();
25-
let first = *tmp_result_iter.next().unwrap();
26-
let last = *tmp_result_iter.next_back().unwrap_or(&first);
24+
let first = **tmp_result.first().unwrap();
25+
let last = **tmp_result.last().unwrap();
2726
result += first as u32 * 10 + last as u32;
2827
}
2928

src/bin/02.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
advent_of_code::solution!(2);
22

3+
use advent_of_code::maneatingape::parse::*;
4+
35
struct Game {
46
id: u32,
57
sets: Vec<Set>,
@@ -19,9 +21,9 @@ impl From<&str> for Set {
1921
item.split(", ")
2022
.filter_map(|x| x.split_once(' '))
2123
.for_each(|(n, color)| match color {
22-
"red" => result.red = n.parse().unwrap(),
23-
"green" => result.green = n.parse().unwrap(),
24-
"blue" => result.blue = n.parse().unwrap(),
24+
"red" => result.red = n.unsigned(),
25+
"green" => result.green = n.unsigned(),
26+
"blue" => result.blue = n.unsigned(),
2527
_ => unreachable!(),
2628
});
2729

@@ -33,7 +35,7 @@ impl From<&str> for Game {
3335
fn from(item: &str) -> Self {
3436
let (game_id, game_data) = item.split_once(": ").unwrap();
3537

36-
let id = game_id[5..].parse().unwrap();
38+
let id = game_id.unsigned();
3739
let sets = game_data.split("; ").map(Set::from).collect();
3840

3941
Game { id, sets }

src/bin/03.rs

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
advent_of_code::solution!(3);
22

3-
use advent_of_code::util::point::Point;
4-
53
use advent_of_code::maneatingape::hash::*;
6-
7-
use regex::Regex;
4+
use advent_of_code::maneatingape::parse::*;
5+
use advent_of_code::maneatingape::point::*;
86

97
#[derive(Default)]
108
struct Number {
@@ -18,16 +16,23 @@ fn parse_data(input: &str) -> (Vec<Number>, Symbols) {
1816
let mut numbers = vec![];
1917
let mut symbols = Symbols::new();
2018

21-
let re_numbers = Regex::new(r"\d+").unwrap();
22-
2319
for (y, line) in input.lines().enumerate() {
24-
for m in re_numbers.find_iter(line) {
25-
let value = m.as_str().parse().unwrap();
26-
let locations = (m.start()..m.end())
27-
.map(|x| Point::new(x as i32, y as i32))
28-
.collect();
20+
let mut i = 0;
21+
while i < line.len() {
22+
if line[i..].as_bytes()[0].is_ascii_digit() {
23+
let value = (&line[i..]).unsigned::<u32>();
24+
let value_len = value.ilog10() as usize + 1;
25+
26+
let locations = (0..value_len)
27+
.map(|x| Point::new((i + x) as i32, y as i32))
28+
.collect();
2929

30-
numbers.push(Number { value, locations });
30+
numbers.push(Number { value, locations });
31+
32+
i += value_len;
33+
} else {
34+
i += 1;
35+
}
3136
}
3237
}
3338

@@ -43,19 +48,8 @@ fn parse_data(input: &str) -> (Vec<Number>, Symbols) {
4348
}
4449

4550
fn find_symbol_location(number: &Number, symbols: &Symbols) -> Option<Point> {
46-
const NEIGHBORS: [Point; 8] = [
47-
Point::new(-1, -1),
48-
Point::new(-1, 0),
49-
Point::new(-1, 1),
50-
Point::new(0, -1),
51-
Point::new(0, 1),
52-
Point::new(1, -1),
53-
Point::new(1, 0),
54-
Point::new(1, 1),
55-
];
56-
5751
for &number_location in number.locations.iter() {
58-
for n in NEIGHBORS {
52+
for n in DIAGONAL {
5953
let new_location = number_location + n;
6054

6155
if symbols.contains_key(&new_location) {

src/bin/04.rs

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
advent_of_code::solution!(4);
22

3+
use advent_of_code::maneatingape::parse::*;
4+
35
struct Card {
46
my_numbers: Vec<u32>,
57
winning_numbers: Vec<u32>,
@@ -9,18 +11,9 @@ fn parse_data(input: &str) -> Vec<Card> {
911
input
1012
.lines()
1113
.map(|line| {
12-
let (_, line) = line.split_once(':').unwrap();
13-
let (winning_numbers, my_numbers) = line.split_once('|').unwrap();
14-
15-
let winning_numbers = winning_numbers
16-
.split_ascii_whitespace()
17-
.map(|x| x.parse().unwrap())
18-
.collect();
19-
20-
let my_numbers = my_numbers
21-
.split_ascii_whitespace()
22-
.map(|x| x.parse().unwrap())
23-
.collect();
14+
let (winning_numbers_str, my_numbers_str) = line.split_once('|').unwrap();
15+
let winning_numbers = winning_numbers_str.iter_unsigned().skip(1).collect();
16+
let my_numbers = my_numbers_str.iter_unsigned().collect();
2417

2518
Card {
2619
my_numbers,

src/bin/05.rs

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
advent_of_code::solution!(5);
22

3+
use advent_of_code::maneatingape::iter::*;
4+
use advent_of_code::maneatingape::parse::*;
5+
36
type Seed = u64;
47

58
#[derive(Clone, Copy)]
@@ -36,30 +39,22 @@ impl MapPart {
3639
fn parse_data(input: &str) -> (Vec<Seed>, Vec<Vec<MapPart>>) {
3740
let mut parts = input.split("\n\n");
3841

39-
let seeds = parts.next().unwrap()[7..]
40-
.split_ascii_whitespace()
41-
.map(|x| x.parse().unwrap())
42+
let seeds = parts.next().unwrap().iter_unsigned().collect();
43+
44+
let maps = parts
45+
.map(|part| {
46+
part.iter_unsigned()
47+
.chunk::<3>()
48+
.map(|[min_target, min_source, n]| MapPart {
49+
min_source,
50+
max_source: min_source + n - 1,
51+
min_target,
52+
max_target: min_source + n - 1,
53+
})
54+
.collect()
55+
})
4256
.collect();
4357

44-
let mut maps = vec![];
45-
for part in parts {
46-
let mut part_result = vec![];
47-
for line in part.lines().skip(1) {
48-
let tmp = line
49-
.split_ascii_whitespace()
50-
.map(|x| x.parse().unwrap())
51-
.collect::<Vec<_>>();
52-
53-
part_result.push(MapPart {
54-
min_source: tmp[1],
55-
max_source: tmp[1] + tmp[2] - 1,
56-
min_target: tmp[0],
57-
max_target: tmp[0] + tmp[2] - 1,
58-
});
59-
}
60-
maps.push(part_result);
61-
}
62-
6358
(seeds, maps)
6459
}
6560

src/bin/06.rs

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
advent_of_code::solution!(6);
22

3+
use advent_of_code::maneatingape::parse::*;
4+
35
struct Race {
46
time: u64,
57
distance: u64,
@@ -8,15 +10,8 @@ struct Race {
810
fn parse_data(input: &str) -> Vec<Race> {
911
let (time, distance) = input.split_once('\n').unwrap();
1012

11-
let time = time[5..]
12-
.split_ascii_whitespace()
13-
.map(|x| x.parse().unwrap());
14-
15-
let distance = distance[9..]
16-
.split_ascii_whitespace()
17-
.map(|x| x.parse().unwrap());
18-
19-
time.zip(distance)
13+
time.iter_unsigned()
14+
.zip(distance.iter_unsigned())
2015
.map(|(time, distance)| Race { time, distance })
2116
.collect()
2217
}
@@ -57,15 +52,15 @@ pub fn part_two(input: &str) -> Option<u64> {
5752
.iter()
5853
.map(|race| race.time)
5954
.fold(String::new(), |acc, x| acc + &x.to_string())
60-
.parse()
61-
.unwrap();
55+
.as_str()
56+
.unsigned();
6257

6358
let distance = races
6459
.iter()
6560
.map(|race| race.distance)
6661
.fold(String::new(), |acc, x| acc + &x.to_string())
67-
.parse()
68-
.unwrap();
62+
.as_str()
63+
.unsigned();
6964

7065
let race = Race { time, distance };
7166

src/bin/07.rs

Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
advent_of_code::solution!(7);
22

33
use advent_of_code::maneatingape::hash::*;
4+
use advent_of_code::maneatingape::parse::*;
45

56
struct Hand {
67
cards: Vec<char>,
@@ -29,7 +30,7 @@ fn parse_data(input: &str) -> Vec<Hand> {
2930
.lines()
3031
.map(|line| {
3132
let cards = line[..5].chars().collect();
32-
let bid = line[6..].parse().unwrap();
33+
let bid = (&line[6..]).unsigned();
3334
Hand { cards, bid }
3435
})
3536
.collect()
@@ -49,29 +50,15 @@ fn calculate_power(hand: &Hand, joker_mode: bool) -> HandPower {
4950
};
5051

5152
let best_value = counter.values().max().unwrap_or(&0) + jokers;
52-
53-
if best_value == 5 {
54-
return HandPower::FiveOfKind;
55-
}
56-
if best_value == 4 {
57-
return HandPower::FourOfKind;
58-
}
59-
if best_value == 3 {
60-
if counter.values().count() == 2 {
61-
return HandPower::FullHouse;
62-
} else {
63-
return HandPower::ThreeOfKind;
64-
}
53+
match (best_value, counter.len()) {
54+
(5, _) => HandPower::FiveOfKind,
55+
(4, _) => HandPower::FourOfKind,
56+
(3, 2) => HandPower::FullHouse,
57+
(3, _) => HandPower::ThreeOfKind,
58+
(2, 3) => HandPower::TwoPairs,
59+
(2, _) => HandPower::Pair,
60+
_ => HandPower::None,
6561
}
66-
if best_value == 2 {
67-
if counter.values().count() == 3 {
68-
return HandPower::TwoPairs;
69-
} else {
70-
return HandPower::Pair;
71-
}
72-
}
73-
74-
HandPower::None
7562
}
7663

7764
fn part_x(hands: &[Hand], joker_mode: bool) -> u32 {
@@ -109,7 +96,6 @@ fn part_x(hands: &[Hand], joker_mode: bool) -> u32 {
10996
state.sort_unstable_by(|a, b| {
11097
if a.power == b.power {
11198
let mut values_iter = a.values.iter().zip(b.values.iter());
112-
11399
return values_iter
114100
.find(|(av, bv)| av != bv)
115101
.map(|(av, bv)| av.cmp(bv))

src/bin/08.rs

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
advent_of_code::solution!(8);
22

33
use advent_of_code::maneatingape::hash::*;
4+
use advent_of_code::maneatingape::math::*;
45

56
type MyLocation = [char; 3];
67

@@ -65,19 +66,6 @@ pub fn part_one(input: &str) -> Option<u64> {
6566
Some(result)
6667
}
6768

68-
fn gcd(a: u64, b: u64) -> u64 {
69-
let mut a = a;
70-
let mut b = b;
71-
while b != 0 {
72-
(a, b) = (b, a % b);
73-
}
74-
a
75-
}
76-
77-
fn lcm(a: u64, b: u64) -> u64 {
78-
(a * b) / gcd(a, b)
79-
}
80-
8169
pub fn part_two(input: &str) -> Option<u64> {
8270
let state = parse_data(input);
8371

@@ -90,7 +78,7 @@ pub fn part_two(input: &str) -> Option<u64> {
9078
let result = locations
9179
.into_iter()
9280
.map(|loc| part_x(&state, loc, |loc| loc[2] == 'Z'))
93-
.fold(1, lcm);
81+
.fold(1, IntegerMathOps::lcm);
9482

9583
Some(result)
9684
}

0 commit comments

Comments
 (0)