perf improvements and solution for year2022 day01
This commit is contained in:
parent
96edd60a7c
commit
f0a198d6f9
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"rust-analyzer.showUnlinkedFileNotification": false
|
||||
}
|
2255
input/year2022/day01.txt
Normal file
2255
input/year2022/day01.txt
Normal file
File diff suppressed because it is too large
Load Diff
@ -10,3 +10,7 @@ pub mod year2016 {
|
||||
pub mod day02;
|
||||
pub mod day03;
|
||||
}
|
||||
|
||||
pub mod year2022 {
|
||||
pub mod day01;
|
||||
}
|
24
src/main.rs
24
src/main.rs
@ -6,7 +6,7 @@ struct Solution {
|
||||
year: u32,
|
||||
day: u32,
|
||||
input: &'static str,
|
||||
run: fn(&str) -> (String, String),
|
||||
run: fn(&str) -> (String, Duration, String, Duration),
|
||||
}
|
||||
|
||||
macro_rules! solution {
|
||||
@ -23,9 +23,13 @@ macro_rules! solution {
|
||||
]),
|
||||
run: |input: &str| {
|
||||
use aoc::$year::$day::*;
|
||||
let part1_start = Instant::now();
|
||||
let part1 = part1(&input).to_string();
|
||||
let part1_elapsed = part1_start.elapsed();
|
||||
let part2_start = Instant::now();
|
||||
let part2 = part2(&input).to_string();
|
||||
(part1, part2)
|
||||
let part2_elapsed = part2_start.elapsed();
|
||||
(part1, part1_elapsed, part2, part2_elapsed)
|
||||
},
|
||||
}
|
||||
};
|
||||
@ -54,18 +58,18 @@ fn main() {
|
||||
} in solutions
|
||||
{
|
||||
let start = Instant::now();
|
||||
let (aw1, aw2) = (run)(input);
|
||||
let (aw1, el1, aw2, el2) = (run)(input);
|
||||
let elapsed = start.elapsed();
|
||||
overall_duration += elapsed;
|
||||
println!("{year} Day {day:02} ({:?})", elapsed);
|
||||
println!(" Part 1: {aw1}");
|
||||
println!(" Part 2: {aw2}");
|
||||
println!("{year} Day {day:02} ({elapsed:?})");
|
||||
println!(" Part 1: {aw1} ({el1:?})");
|
||||
println!(" Part 2: {aw2} ({el2:?})");
|
||||
}
|
||||
println!("Total solutions: {count} ({overall_duration:?})")
|
||||
}
|
||||
|
||||
fn solutions() -> impl Iterator<Item = Solution> {
|
||||
std::iter::empty().chain(year2016())
|
||||
std::iter::empty().chain(year2016()).chain(year2022())
|
||||
}
|
||||
|
||||
fn year2016() -> Vec<Solution> {
|
||||
@ -75,3 +79,9 @@ fn year2016() -> Vec<Solution> {
|
||||
solution!(year2016, day03),
|
||||
]
|
||||
}
|
||||
|
||||
fn year2022() -> Vec<Solution> {
|
||||
vec![
|
||||
solution!(year2022, day01),
|
||||
]
|
||||
}
|
@ -2,11 +2,11 @@ use std::collections::HashSet;
|
||||
|
||||
use crate::util::{index::*, parse::ParseExt};
|
||||
|
||||
fn parse(input: &str) -> Vec<(u8, u32)> {
|
||||
fn parse(input: &str) -> impl Iterator<Item = (u8, u32)> + '_ {
|
||||
let dirs = input.bytes().filter(u8::is_ascii_uppercase);
|
||||
let steps = input.u32s();
|
||||
let steps: Vec<_> = input.u32s().collect();
|
||||
|
||||
dirs.zip(steps).collect()
|
||||
dirs.zip(steps)
|
||||
}
|
||||
|
||||
pub fn part1(input: &str) -> impl std::fmt::Display {
|
||||
|
@ -25,11 +25,7 @@ pub fn part1(input: &str) -> impl std::fmt::Display {
|
||||
#[inline]
|
||||
#[rustfmt::skip]
|
||||
fn within(coord: &Ix2) -> bool {
|
||||
[
|
||||
[0, 0], [1, 0], [2, 0],
|
||||
[0, 1], [1, 1], [2, 1],
|
||||
[0, 2], [1, 2], [2, 2]
|
||||
].contains(&coord.0)
|
||||
coord.x() >= 0 && coord.x() <= 2 && coord.y() >= 0 && coord.y() <= 2
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -54,13 +50,14 @@ pub fn part2(input: &str) -> impl std::fmt::Display {
|
||||
#[inline]
|
||||
#[rustfmt::skip]
|
||||
fn within(coord: &Ix2) -> bool {
|
||||
[
|
||||
[2, 0],
|
||||
[1, 1], [2, 1], [3, 1],
|
||||
[0, 2], [1, 2], [2, 2], [3, 2], [4, 2],
|
||||
[1, 3], [2, 3], [3, 3],
|
||||
[2, 4],
|
||||
].contains(&coord.0)
|
||||
match coord.0 {
|
||||
[0, 2] |
|
||||
[1, 1] | [1, 2] | [1, 3] |
|
||||
[2, 0] | [2, 1] | [2, 2] | [2, 3] | [2, 4] |
|
||||
[3, 1] | [3, 2] | [3, 3] |
|
||||
[4, 2] => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::util::parse::ParseExt;
|
||||
|
||||
#[inline]
|
||||
fn valid_triangle(v: &[u32; 3]) -> bool {
|
||||
v[0] + v[1] > v[2] && v[1] + v[2] > v[0] && v[0] + v[2] > v[1]
|
||||
}
|
||||
@ -9,6 +10,10 @@ pub fn part1(input: &str) -> impl std::fmt::Display {
|
||||
.lines()
|
||||
.map(|s| {
|
||||
s.u32s()
|
||||
// This is faster than `collect().try_into().expect("")`
|
||||
// presumably because of the allocation of the Vec
|
||||
// and the additional check for the Option for each line
|
||||
// incure a bit of overhead
|
||||
.fold(([0u32; 3], 0), |(mut a, i), v| {
|
||||
a[i] = v;
|
||||
(a, i + 1)
|
||||
@ -31,14 +36,10 @@ pub fn part2(input: &str) -> impl std::fmt::Display {
|
||||
let l1: Vec<u32> = l1.u32s().collect();
|
||||
let l2: Vec<u32> = l2.u32s().collect();
|
||||
let l3: Vec<u32> = l3.u32s().collect();
|
||||
if valid_triangle(&[l1[0], l2[0], l3[0]]) {
|
||||
valid += 1;
|
||||
}
|
||||
if valid_triangle(&[l1[1], l2[1], l3[1]]) {
|
||||
valid += 1;
|
||||
}
|
||||
if valid_triangle(&[l1[2], l2[2], l3[2]]) {
|
||||
valid += 1;
|
||||
for i in 0..2 {
|
||||
if valid_triangle(&[l1[i], l2[i], l3[i]]) {
|
||||
valid += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
valid
|
||||
@ -51,5 +52,5 @@ fn test_part1() {
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
assert_eq!("", part2("").to_string());
|
||||
assert_eq!("2", part2("100 200 300\n101 201 301\n102 202 302").to_string());
|
||||
}
|
||||
|
25
src/year2022/day01.rs
Normal file
25
src/year2022/day01.rs
Normal file
@ -0,0 +1,25 @@
|
||||
use crate::util::parse::ParseExt;
|
||||
|
||||
fn calories(input: &str) -> impl Iterator<Item = u32> + '_ {
|
||||
input.split("\n\n").map(|set| set.u32s().sum())
|
||||
}
|
||||
|
||||
pub fn part1(input: &str) -> impl std::fmt::Display {
|
||||
calories(input).max().expect("must have one max")
|
||||
}
|
||||
|
||||
pub fn part2(input: &str) -> impl std::fmt::Display {
|
||||
let mut items: Vec<_> = calories(input).collect();
|
||||
items.sort_unstable();
|
||||
items.iter().rev().take(3).sum::<u32>()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
assert_eq!("24000", part1("1000\n2000\n3000\n\n4000\n\n5000\n6000\n\n7000\n8000\n9000\n\n10000").to_string())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
assert_eq!("4", part2("R8, R4, R4, R8").to_string())
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user