|
|
|
@ -7,6 +7,8 @@
|
|
|
|
* @brief pre-advent testing
|
|
|
|
* @brief pre-advent testing
|
|
|
|
******************************************************************************/
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// use std::path::absolute;
|
|
|
|
|
|
|
|
|
|
|
|
use solver::solver::{Solver, SolverOption, SolverState};
|
|
|
|
use solver::solver::{Solver, SolverOption, SolverState};
|
|
|
|
use utils::utils;
|
|
|
|
use utils::utils;
|
|
|
|
|
|
|
|
|
|
|
|
@ -18,6 +20,7 @@ pub struct Day1
|
|
|
|
input: String,
|
|
|
|
input: String,
|
|
|
|
dial_position: i32,
|
|
|
|
dial_position: i32,
|
|
|
|
rotations: Vec<i32>,
|
|
|
|
rotations: Vec<i32>,
|
|
|
|
|
|
|
|
// full_rots: Vec<i32>,
|
|
|
|
zeros: u64,
|
|
|
|
zeros: u64,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -40,34 +43,70 @@ impl Solver for Day1
|
|
|
|
|
|
|
|
|
|
|
|
fn solve(&mut self, _input: String) -> Result<u64, String>
|
|
|
|
fn solve(&mut self, _input: String) -> Result<u64, String>
|
|
|
|
{
|
|
|
|
{
|
|
|
|
let verbose = self.solver_state.check_option(SolverOption::Verbose);
|
|
|
|
// let verbose = self.solver_state.check_option(SolverOption::Verbose);
|
|
|
|
|
|
|
|
// let count_passes = self.solver_state.get_value("count_passing_zeros") == "true";
|
|
|
|
println!("Starting Dial Pos: {}", self.dial_position);
|
|
|
|
println!("Starting Dial Pos: {}", self.dial_position);
|
|
|
|
println!("Number of rotations: {}", self.rotations.len());
|
|
|
|
println!("Number of rotations: {}", self.rotations.len());
|
|
|
|
for rot in &self.rotations
|
|
|
|
for rot in &self.rotations
|
|
|
|
{
|
|
|
|
{
|
|
|
|
self.dial_position += rot;
|
|
|
|
let (new_pos, num_zeros) = Day1::process_rot(self.dial_position, *rot);
|
|
|
|
if self.dial_position < 0
|
|
|
|
self.dial_position = new_pos;
|
|
|
|
{
|
|
|
|
self.zeros += num_zeros;
|
|
|
|
self.dial_position = DIAL_MAX_POS + self.dial_position + 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
// self.dial_position += rot;
|
|
|
|
else if self.dial_position > DIAL_MAX_POS
|
|
|
|
// if verbose
|
|
|
|
{
|
|
|
|
// {
|
|
|
|
self.dial_position -= DIAL_MAX_POS + 1;
|
|
|
|
// println!("Applied rotation {}", rot);
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
if verbose
|
|
|
|
// if self.dial_position < 0
|
|
|
|
{
|
|
|
|
// {
|
|
|
|
println!("Applied rotation {}, dial pos: {}", rot, self.dial_position);
|
|
|
|
// if count_passes && (self.dial_position - rot != 0)
|
|
|
|
}
|
|
|
|
// {
|
|
|
|
|
|
|
|
// if verbose && self.dial_position != 0 && self.dial_position != 0
|
|
|
|
if 0 == self.dial_position
|
|
|
|
// {
|
|
|
|
{
|
|
|
|
// println!("Counting a passing zero");
|
|
|
|
self.zeros += 1;
|
|
|
|
// }
|
|
|
|
if verbose
|
|
|
|
// self.zeros += 1;
|
|
|
|
{
|
|
|
|
// }
|
|
|
|
println!("Zero found, total: {}", self.zeros);
|
|
|
|
// self.dial_position = DIAL_MAX_POS + self.dial_position + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
|
|
|
|
// else if self.dial_position > DIAL_MAX_POS
|
|
|
|
|
|
|
|
// {
|
|
|
|
|
|
|
|
// self.dial_position -= DIAL_MAX_POS + 1;
|
|
|
|
|
|
|
|
// if count_passes && self.dial_position != 0
|
|
|
|
|
|
|
|
// {
|
|
|
|
|
|
|
|
// if verbose
|
|
|
|
|
|
|
|
// {
|
|
|
|
|
|
|
|
// println!("Counting a passing zero");
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// self.zeros += 1;
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if count_passes
|
|
|
|
|
|
|
|
// {
|
|
|
|
|
|
|
|
// if verbose && self.full_rots[i] as u64 > 0
|
|
|
|
|
|
|
|
// {
|
|
|
|
|
|
|
|
// println!("Counting extra rotation zeros: {}", self.full_rots[i]);
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// self.zeros += self.full_rots[i] as u64;
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if verbose
|
|
|
|
|
|
|
|
// {
|
|
|
|
|
|
|
|
// println!("New dial pos: {}", self.dial_position);
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if 0 == self.dial_position
|
|
|
|
|
|
|
|
// {
|
|
|
|
|
|
|
|
// self.zeros += 1;
|
|
|
|
|
|
|
|
// if verbose
|
|
|
|
|
|
|
|
// {
|
|
|
|
|
|
|
|
// println!("Zero found, total: {}", self.zeros);
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(self.zeros)
|
|
|
|
Ok(self.zeros)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -82,7 +121,8 @@ impl Day1
|
|
|
|
{
|
|
|
|
{
|
|
|
|
pub fn new() -> Day1
|
|
|
|
pub fn new() -> Day1
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Day1 { solver_state: SolverState::new(), input: "".to_string(), dial_position: 50, rotations: vec![], zeros: 0 }
|
|
|
|
Day1 { solver_state: SolverState::new(), input: "".to_string(), dial_position: 50,
|
|
|
|
|
|
|
|
rotations: vec![], zeros: 0 }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn parse_rots(&mut self)
|
|
|
|
fn parse_rots(&mut self)
|
|
|
|
@ -99,21 +139,60 @@ impl Day1
|
|
|
|
// NOTE: Trusting there are no errors in the input file!
|
|
|
|
// NOTE: Trusting there are no errors in the input file!
|
|
|
|
|
|
|
|
|
|
|
|
let trimmed = &line[1..];
|
|
|
|
let trimmed = &line[1..];
|
|
|
|
let mut mag: i32 = trimmed.parse().expect(&format!("Failed to parse rotation value: {}", trimmed));
|
|
|
|
let mag: i32 = trimmed.parse().expect(&format!("Failed to parse rotation value: {}", trimmed));
|
|
|
|
// mag = mag % DIAL_MAX_POS;
|
|
|
|
// mag = mag % DIAL_MAX_POS;
|
|
|
|
if mag > DIAL_MAX_POS
|
|
|
|
// if mag > DIAL_MAX_POS
|
|
|
|
{
|
|
|
|
// {
|
|
|
|
mag %= DIAL_MAX_POS + 1
|
|
|
|
// let num_full_rots = mag / DIAL_MAX_POS;
|
|
|
|
}
|
|
|
|
// mag %= DIAL_MAX_POS + 1;
|
|
|
|
|
|
|
|
// self.full_rots.push(num_full_rots);
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// else
|
|
|
|
|
|
|
|
// {
|
|
|
|
|
|
|
|
// self.full_rots.push(0);
|
|
|
|
|
|
|
|
// }
|
|
|
|
let rot = mag * coef;
|
|
|
|
let rot = mag * coef;
|
|
|
|
self.rotations.push(rot);
|
|
|
|
self.rotations.push(rot);
|
|
|
|
// println!("as: {}", rot);
|
|
|
|
// println!("as: {}", rot);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// fn process_rot(&mut self, )
|
|
|
|
/// Returns the new dial_position and number of zeros landed on during this rotation
|
|
|
|
|
|
|
|
fn process_rot(dial_pos: i32, rot: i32) -> (i32, u64) // (new dial pos, num zeros passed)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
let direction = match rot >= 0
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
true => 1,
|
|
|
|
|
|
|
|
false => -1,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let mag = rot.abs();
|
|
|
|
|
|
|
|
let mut dial_pos = dial_pos;
|
|
|
|
|
|
|
|
let mut zeros = 0;
|
|
|
|
|
|
|
|
for _ in 0..mag
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
dial_pos += (1 * direction);
|
|
|
|
|
|
|
|
if dial_pos == (DIAL_MAX_POS + 1)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
dial_pos = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if dial_pos == -1
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
dial_pos = DIAL_MAX_POS;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if dial_pos == 0
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
zeros += 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(dial_pos, zeros)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
#[allow(dead_code)]
|
|
|
|
fn print_rot(r: i32)
|
|
|
|
fn print_rot(r: i32)
|
|
|
|
|