Solve day 3 in Rust

This commit is contained in:
George Thomas 2025-12-19 14:51:36 +00:00
parent a321ce3f22
commit 2258f965c1
3 changed files with 73 additions and 1 deletions

View File

@ -3,9 +3,10 @@ mod puzzles;
use crate::puzzle::Puzzle; use crate::puzzle::Puzzle;
use puzzles::day1; use puzzles::day1;
use puzzles::day2; use puzzles::day2;
use puzzles::day3;
use std::fs; use std::fs;
const PUZZLES: [&dyn SomePuzzle; 2] = [&day1::PUZZLE, &day2::PUZZLE]; const PUZZLES: [&dyn SomePuzzle; 3] = [&day1::PUZZLE, &day2::PUZZLE, &day3::PUZZLE];
fn main() { fn main() {
[false, true].iter().for_each(|is_real_data| { [false, true].iter().for_each(|is_real_data| {

70
rust/puzzles/day3.rs Normal file
View File

@ -0,0 +1,70 @@
use crate::puzzle::Puzzle;
use nom::{
Parser,
character::complete::{newline, satisfy},
combinator::eof,
error::Error,
multi::{many1, separated_list1},
sequence::terminated,
};
pub const PUZZLE: Puzzle<Vec<Vec<u8>>, 2> = Puzzle {
number: 3,
parser: |input| {
terminated::<_, _, Error<&str>, _, _>(
terminated(
separated_list1(
newline,
many1(satisfy(|c| c.is_digit(10)).map(|c| c as u8 - '0' as u8)),
),
newline,
),
eof,
)
.parse(input)
.unwrap()
.1
},
parts: [
|input| {
input
.iter()
.map(|bank| {
digits_to_int(&max_batteries(2, &bank).expect("battery list too short"))
})
.sum::<usize>()
.to_string()
},
|input| {
input
.iter()
.map(|bank| {
digits_to_int(&max_batteries(12, &bank).expect("battery list too short"))
})
.sum::<usize>()
.to_string()
},
],
};
fn max_batteries(n: usize, v: &[u8]) -> Option<Vec<u8>> {
let mut result = Vec::with_capacity(n);
let mut remaining = n;
let mut slice = v;
while remaining > 0 {
let (b, i) = find_max(&slice[..slice.len() - remaining + 1]);
result.push(b);
remaining -= 1;
slice = &slice[i + 1..];
}
Some(result)
}
fn find_max<A: Ord + Copy>(v: &[A]) -> (A, usize) {
let (n, x) = v.iter().enumerate().rev().max_by_key(|x| x.1).unwrap();
(*x, n)
}
fn digits_to_int(digits: &[u8]) -> usize {
digits.iter().fold(0, |acc, &d| acc * 10 + (d as usize))
}

View File

@ -1,2 +1,3 @@
pub(crate) mod day1; pub(crate) mod day1;
pub(crate) mod day2; pub(crate) mod day2;
pub(crate) mod day3;