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, pub final_result: i32,
rules: Vec<Rule>, rules: Vec<Rule>,
updates: Vec<Update>,
} }
//||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| //|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@ -28,19 +29,75 @@ impl Day5
{ {
pub fn new() -> 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 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() self.final_result.to_string()
} }
fn solve_second_case(self: &mut Self) -> 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() self.final_result.to_string()
} }
} }
@ -52,7 +109,7 @@ impl Solver for Day5
{ {
fn print_test() 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) 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); let data_split = data.split(split_pattern);
for row in data_split 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("|") 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,9 +175,22 @@ impl Solver for Day5
println!("Rules:"); println!("Rules:");
for rule in &self.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!();
}
}
} }
@ -120,6 +216,30 @@ impl Solver for Day5
// EXTRA STUFF // 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)] #[derive(Copy, Clone, Debug)]
struct Rule struct Rule
{ {
@ -129,7 +249,7 @@ struct Rule
impl Rule impl Rule
{ {
fn new(first: i32, second: i32) -> Rule fn _new(first: i32, second: i32) -> Rule
{ {
Rule { first, second } Rule { first, second }
} }
@ -150,4 +270,79 @@ impl Rule
Ok(Rule { first, second}) 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 // DAY 5
let mut day_5 = Day5::new(); 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(); let day5_result = day_5.solve();
println!("Day 5 Part 1 Final Result: {}", day5_result); println!("Day 5 Part 1 Final Result: {}", day5_result);
// let mut day_5 = Day5::new(); let mut day_5 = Day5::new();
// day_5.init(DataSet::Test, RunMode::SecondCase, false); day_5.init(DataSet::Full, RunMode::SecondCase, false);
// let day5_result = day_5.solve(); let day5_result = day_5.solve();
// println!("Day 5 Part 2 Final Result: {}", day5_result); println!("Day 5 Part 2 Final Result: {}", day5_result);
println!("-------------------------"); println!("-------------------------");

Loading…
Cancel
Save