mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-26 13:20:32 +01:00
Implement day 05.
This was a nice exercise in not allocating memory. Or at least it was, for part 1.
This commit is contained in:
1
2018/inputs/05
Normal file
1
2018/inputs/05
Normal file
File diff suppressed because one or more lines are too long
@@ -29,6 +29,25 @@ pub fn prime_sieve(dest: &mut[bool]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Trim ascii whitespace from a byte vector.
|
||||||
|
///
|
||||||
|
/// This method does no allocations, guaranteed.
|
||||||
|
pub fn trim_back(input: &mut Vec<u8>) {
|
||||||
|
let mut to_truncate = 0;
|
||||||
|
for b in input.iter().rev() {
|
||||||
|
if b.is_ascii_whitespace() {
|
||||||
|
to_truncate += 1;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if to_truncate > 0 {
|
||||||
|
let new_len = input.len() - to_truncate;
|
||||||
|
input.truncate(new_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Solution trait
|
/// Solution trait
|
||||||
///
|
///
|
||||||
/// Every day's solution should implement this function so that it can
|
/// Every day's solution should implement this function so that it can
|
||||||
|
|||||||
68
2018/src/day05.rs
Normal file
68
2018/src/day05.rs
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
use std::io::Read;
|
||||||
|
|
||||||
|
use common;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct Day05 {}
|
||||||
|
|
||||||
|
impl Day05 {
|
||||||
|
pub fn new() -> Day05 {
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce(mut data: Vec<u8>) -> usize {
|
||||||
|
let mut dptr = 0;
|
||||||
|
for iptr in 0..data.len() {
|
||||||
|
if dptr > 0 && (data[iptr].eq_ignore_ascii_case(&data[dptr - 1])) && data[iptr] != data[dptr - 1] {
|
||||||
|
dptr -= 1;
|
||||||
|
} else {
|
||||||
|
data[dptr] = data[iptr];
|
||||||
|
dptr += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dptr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl common::Solution for Day05 {
|
||||||
|
fn part1(&mut self, input: &mut Read) -> String {
|
||||||
|
let mut data = Vec::new();
|
||||||
|
input.read_to_end(&mut data).expect("Can't read input!");
|
||||||
|
common::trim_back(&mut data);
|
||||||
|
|
||||||
|
format!("{}", Day05::reduce(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2(&mut self, input: &mut Read) -> String {
|
||||||
|
let mut data = Vec::new();
|
||||||
|
input.read_to_end(&mut data).expect("Can't read input!");
|
||||||
|
common::trim_back(&mut data);
|
||||||
|
|
||||||
|
let min_len = (b'a'..=b'z').map(|option| data.iter().filter(|&x| !x.eq_ignore_ascii_case(&option)).map(|&x| x).collect())
|
||||||
|
.map(|x| Day05::reduce(x))
|
||||||
|
.min().unwrap();
|
||||||
|
|
||||||
|
format!("{}", min_len)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use common::Solution;
|
||||||
|
use day05::Day05;
|
||||||
|
|
||||||
|
const SAMPLE_INPUT: &[u8] = b"dabAcCaCBAcCcaDA\n";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sample_part1() {
|
||||||
|
let mut instance = Day05::new();
|
||||||
|
assert_eq!("10", instance.part1(&mut SAMPLE_INPUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sample_part2() {
|
||||||
|
let mut instance = Day05::new();
|
||||||
|
assert_eq!("4", instance.part2(&mut SAMPLE_INPUT));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ pub mod day01;
|
|||||||
pub mod day02;
|
pub mod day02;
|
||||||
pub mod day03;
|
pub mod day03;
|
||||||
pub mod day04;
|
pub mod day04;
|
||||||
|
pub mod day05;
|
||||||
|
|
||||||
fn get_impl(day: &str) -> Box<common::Solution> {
|
fn get_impl(day: &str) -> Box<common::Solution> {
|
||||||
match day.parse() {
|
match day.parse() {
|
||||||
@@ -18,6 +19,7 @@ fn get_impl(day: &str) -> Box<common::Solution> {
|
|||||||
Ok(2) => Box::new(day02::Day02::new()),
|
Ok(2) => Box::new(day02::Day02::new()),
|
||||||
Ok(3) => Box::new(day03::Day03::new()),
|
Ok(3) => Box::new(day03::Day03::new()),
|
||||||
Ok(4) => Box::new(day04::Day04::new()),
|
Ok(4) => Box::new(day04::Day04::new()),
|
||||||
|
Ok(5) => Box::new(day05::Day05::new()),
|
||||||
Ok(val) => panic!("Unimplemented day {}", val),
|
Ok(val) => panic!("Unimplemented day {}", val),
|
||||||
_ => panic!("Invalid number"),
|
_ => panic!("Invalid number"),
|
||||||
}
|
}
|
||||||
@@ -63,7 +65,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_get_impl() {
|
fn test_get_impl() {
|
||||||
// Verify that we can load all days
|
// Verify that we can load all days
|
||||||
let last_implemented = 4;
|
let last_implemented = 5;
|
||||||
for d in 1..=last_implemented {
|
for d in 1..=last_implemented {
|
||||||
get_impl(&format!("{}", d));
|
get_impl(&format!("{}", d));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user