Day 5 problems complete

master
Joey Pollack 1 year ago
parent f67c240888
commit ce37c9a218

@ -19,6 +19,7 @@ pub struct Day5
pub final_result: i32,
rules: Vec<Rule>,
updates: Vec<Update>,
}
//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@ -28,19 +29,75 @@ impl Day5
{
pub fn new() -> Day5
{
Day5 { data_set: DataSet::Test, run_mode: RunMode::FirstCase, do_debug_prints: false, final_result: 0, rules: vec![] }
Day5 { data_set: DataSet::Test, run_mode: RunMode::FirstCase,
do_debug_prints: false, final_result: 0, rules: vec![], updates: vec![] }
}
fn solve_first_case(self: &mut Self) -> String
{
// verify all updates
let valid_count = check_updates(&mut self.updates, &self.rules, self.do_debug_prints);
if self.do_debug_prints
{
println!("DEBUG: valid updates found: {}", valid_count);
}
// Sum the middle page of each valid update
let mut sum = 0;
for update in &self.updates
{
if UpdateStatus::Valid == update.status
{
let mid_idx = update.pages.len() / 2;
sum += update.pages[mid_idx];
}
}
self.final_result = sum;
self.final_result.to_string()
}
fn solve_second_case(self: &mut Self) -> String
{
// verify
let _ = check_updates(&mut self.updates, &self.rules, self.do_debug_prints);
// fix any broken updates and sum their mid pages
let mut sum = 0;
for update in &mut self.updates
{
if UpdateStatus::Valid == update.status
{
continue;
}
let mut fixed = false;
let mut i = 0;
while i < self.rules.len()
{
if !self.rules[i].verify_update(&update.pages, self.do_debug_prints)
{
self.rules[i].make_valid(&mut update.pages, self.do_debug_prints);
i = 0;
fixed = true;
}
else
{
i += 1;
}
}
if fixed && self.do_debug_prints
{
println!("DEBUG: Fixed update: {:#?}", update.pages);
}
let mid_idx = update.pages.len() / 2;
sum += update.pages[mid_idx];
}
self.final_result = sum;
self.final_result.to_string()
}
}
@ -52,7 +109,7 @@ impl Solver for Day5
{
fn print_test()
{
println!("DAY 4 TEST PRINT");
println!("DAY 5 TEST PRINT");
}
fn init(self: &mut Self, data_set: DataSet, run_mode: RunMode, enable_debug_prints: bool)
@ -81,9 +138,35 @@ impl Solver for Day5
let data_split = data.split(split_pattern);
for row in data_split
{
if self.do_debug_prints
{
println!("DEBUG: Loading row: {}", row);
}
if row.is_empty()
{
if self.do_debug_prints
{
println!("DEBUG: Skipping empty row");
}
continue;
}
// Rules contain "|", update lists do not
if row.contains("|")
{
self.rules.push(Rule::parse(row).expect(&format!("Failed to create rule from: {}", row) ));
self.rules.push(Rule::parse(row).expect(&format!("ERROR: Failed to create rule from: {}", row) ));
}
else
{
let mut pages: Vec<i32> = vec![];
for page in row.split(",")
{
let page_i = page.parse::<i32>().expect(&format!("ERROR: Failed to parse update page: {}", page));
pages.push(page_i);
}
self.updates.push(Update::new(pages));
}
}
@ -92,10 +175,23 @@ impl Solver for Day5
println!("Rules:");
for rule in &self.rules
{
println!("\tRule: {}|{}", rule.first, rule.second);
println!("\t{}|{}", rule.first, rule.second);
}
println!("Updates:");
for update in &self.updates
{
print!("\t");
for page in &update.pages
{
print!("{},", page);
}
println!();
}
}
}
fn solve(self: &mut Self) -> String
@ -120,6 +216,30 @@ impl Solver for Day5
// EXTRA STUFF
//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fn check_updates(updates: &mut Vec<Update>, rules: &Vec<Rule>, enable_debug_prints: bool) -> i32
{
let mut valid_count = 0;
for update in updates
{
for rules in rules
{
if !rules.verify_update(&update.pages, enable_debug_prints)
{
update.status = UpdateStatus::Invalid;
break;
}
}
if UpdateStatus::Unknown == update.status
{
update.status = UpdateStatus::Valid;
valid_count += 1;
}
}
return valid_count;
}
#[derive(Copy, Clone, Debug)]
struct Rule
{
@ -129,7 +249,7 @@ struct Rule
impl Rule
{
fn new(first: i32, second: i32) -> Rule
fn _new(first: i32, second: i32) -> Rule
{
Rule { first, second }
}
@ -150,4 +270,79 @@ impl Rule
Ok(Rule { first, second})
}
fn verify_update(self: &Rule, update: &Vec<i32>, enable_debug_output: bool) -> bool
{
let mut found_second = false;
for page in update
{
if *page == self.first
{
if found_second
{
if enable_debug_output
{
println!("DEBUG: Update ({:#?}) fails rule: {}|{} -- found first after second", update, self.first, self.second);
}
return false;
}
}
if *page == self.second
{
found_second = true;
}
}
return true;
}
fn make_valid(self: &Rule, update: &mut Vec<i32>, enable_debug_output: bool)
{
let mut first_idx = 0;
let mut second_idx = 0;
for (i, page) in update.iter().enumerate()
{
if *page == self.first
{
first_idx = i;
}
if *page == self.second
{
second_idx = i;
}
}
if first_idx > second_idx
{
update.swap(first_idx, second_idx);
}
}
}
#[derive(Copy, Clone, PartialEq, Debug)]
enum UpdateStatus
{
Valid,
Invalid,
Unknown,
}
#[derive(Clone, Debug)]
struct Update
{
pages: Vec<i32>,
status: UpdateStatus,
}
impl Update
{
fn new(pages: Vec<i32>) -> Update
{
Update { pages, status: UpdateStatus::Unknown }
}
}

@ -71,14 +71,14 @@ fn main()
// DAY 5
let mut day_5 = Day5::new();
day_5.init(DataSet::Test, RunMode::FirstCase, true);
day_5.init(DataSet::Full, RunMode::FirstCase, false);
let day5_result = day_5.solve();
println!("Day 5 Part 1 Final Result: {}", day5_result);
// let mut day_5 = Day5::new();
// day_5.init(DataSet::Test, RunMode::SecondCase, false);
// let day5_result = day_5.solve();
// println!("Day 5 Part 2 Final Result: {}", day5_result);
let mut day_5 = Day5::new();
day_5.init(DataSet::Full, RunMode::SecondCase, false);
let day5_result = day_5.solve();
println!("Day 5 Part 2 Final Result: {}", day5_result);
println!("-------------------------");

Loading…
Cancel
Save