Day 13 partial solution

This commit is contained in:
2022-12-14 00:02:13 +01:00
parent 466df5506a
commit c38853b577
4 changed files with 596 additions and 0 deletions

120
src/day13/main.rs Normal file
View File

@ -0,0 +1,120 @@
use std::fmt::Display;
use base::read_file;
#[derive(Debug, Eq, PartialEq)]
struct List {
elements: Vec<ListElement>,
}
#[derive(Debug, Eq, PartialEq)]
enum ListElement {
Number(u32),
Sublist(List),
}
fn add_to_list(next: &Vec<char>, start: usize) -> (List, usize) {
let mut list = List { elements: vec![] };
let mut index = start;
if start == 0 {
index = 1;
}
while index < next.len() {
match next[index] {
'[' => {
let (sublist, new_idx) = add_to_list(next, index + 1);
index = new_idx;
list.elements.push(ListElement::Sublist(sublist));
}
']' => {
return (list, index + 1);
}
_ => {
let mut number = String::new();
if next[index].is_digit(10) {
number.push(next[index]);
while next[index + 1].is_digit(10) {
index += 1;
number.push(next[index]);
}
list.elements.push(ListElement::Number(number.parse::<u32>().unwrap()));
}
}
}
index += 1;
}
return (list, index);
}
fn are_in_right_order(lhs: &List, rhs: &List) -> Option<bool> {
let mut left_iter = lhs.elements.iter();
let mut right_iter = rhs.elements.iter();
loop {
let next_left = left_iter.next();
let next_right = right_iter.next();
if next_left.is_some() && next_right.is_some() {
let left = next_left.unwrap();
let right = next_right.unwrap();
match left {
ListElement::Number(ln) => {
match right {
ListElement::Number(rn) => {
println!("Compare {} vs {}", ln, rn);
if ln < rn {
println!("Left side is smaller; Right order");
return Some(true);
} else if rn < ln {
println!("Right side is smaller; Not right order");
return Some(false);
}
}
ListElement::Sublist(rl) => {
if let Some(value) = are_in_right_order(&List { elements: vec![ListElement::Number(*ln)] }, rl) {
return Some(value);
}
}
}
}
ListElement::Sublist(ll) => {
let value = match right {
ListElement::Number(rh) => { are_in_right_order(ll, &List { elements: vec![ListElement::Number(*rh)] }) }
ListElement::Sublist(rl) => {
are_in_right_order(ll, rl)
}
};
if let Some(value) = value {
return Some(value);
}
}
}
} else if next_left.is_some() && next_right.is_none() {
println!("Right side run out of items; Not right order");
return Some(false);
} else if next_left.is_none() && next_right.is_some() {
println!("Left side run out of items; Right order");
return Some(true);
} else {
println!("Both sides run out of items. Going back");
return None;
}
}
}
fn main() {
let lines = read_file("day13.txt");
let mut lists = vec![];
for line in lines {
if !line.is_empty() {
lists.push(add_to_list(&mut line.chars().collect::<Vec<_>>(), 0).0);
}
}
let task1 = lists.chunks_exact(2).enumerate().filter(|(_, chunk)| are_in_right_order(&chunk[0], &chunk[1]).unwrap()).fold(0, |acc, (idx, _)| {
println!("Found machting pair at: {idx}");
acc + idx + 1
});
println!("Task1: {task1}");
}