Solve day 3 in Rust
This commit is contained in:
parent
a321ce3f22
commit
2258f965c1
@ -3,9 +3,10 @@ mod puzzles;
|
||||
use crate::puzzle::Puzzle;
|
||||
use puzzles::day1;
|
||||
use puzzles::day2;
|
||||
use puzzles::day3;
|
||||
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() {
|
||||
[false, true].iter().for_each(|is_real_data| {
|
||||
|
||||
70
rust/puzzles/day3.rs
Normal file
70
rust/puzzles/day3.rs
Normal 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))
|
||||
}
|
||||
@ -1,2 +1,3 @@
|
||||
pub(crate) mod day1;
|
||||
pub(crate) mod day2;
|
||||
pub(crate) mod day3;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user