64 lines
2.0 KiB
Rust
64 lines
2.0 KiB
Rust
use crate::solvers::Solver;
|
|
use std::io::BufRead;
|
|
|
|
pub struct SecretEntrance {}
|
|
|
|
impl SecretEntrance {
|
|
const START_POSITION: i32 = 50;
|
|
const DIAL_SIZE: i32 = 100;
|
|
const ZERO_POSITION: i32 = 0;
|
|
const POSITIVE_SIGN_CHAR: char = 'R';
|
|
const NEGATIVE_SIGN_CHAR: char = 'L';
|
|
|
|
fn update_position(
|
|
position: i32,
|
|
distance: i32,
|
|
mut zero_hits: u64,
|
|
mut zero_passes: u64,
|
|
) -> (i32, u64, u64) {
|
|
let mut new_position = position + distance;
|
|
let rounds = new_position.div_euclid(Self::DIAL_SIZE);
|
|
zero_passes += u64::try_from(rounds.abs()).unwrap();
|
|
new_position -= Self::DIAL_SIZE * rounds;
|
|
if new_position == Self::ZERO_POSITION {
|
|
zero_hits += 1;
|
|
if position != Self::ZERO_POSITION && distance < 0 {
|
|
zero_passes += 1;
|
|
}
|
|
} else if position == Self::ZERO_POSITION && distance < 0 {
|
|
zero_passes -= 1;
|
|
}
|
|
(new_position, zero_hits, zero_passes)
|
|
}
|
|
}
|
|
|
|
impl Solver for SecretEntrance {
|
|
const PUZZLE_INDEX: u8 = 1;
|
|
const PUZZLE_NAME: &'static str = "Secret Entrance";
|
|
|
|
fn process_data<R: BufRead>(&self, reader: R) -> (u64, u64) {
|
|
let mut position = Self::START_POSITION;
|
|
let mut zero_hits = 0;
|
|
let mut zero_passes = 0;
|
|
let format: String = format!(
|
|
"{{[{}{}]}}{{d}}",
|
|
Self::POSITIVE_SIGN_CHAR,
|
|
Self::NEGATIVE_SIGN_CHAR
|
|
);
|
|
for line in reader.lines().map_while(Result::ok) {
|
|
let (sign, distance) = scan_fmt!(&line, &format, char, i32).unwrap();
|
|
(position, zero_hits, zero_passes) = Self::update_position(
|
|
position,
|
|
if sign == Self::POSITIVE_SIGN_CHAR {
|
|
distance
|
|
} else {
|
|
-distance
|
|
},
|
|
zero_hits,
|
|
zero_passes,
|
|
);
|
|
}
|
|
(zero_hits, zero_passes)
|
|
}
|
|
}
|