Day 13 partial solution
This commit is contained in:
120
src/day13/main.rs
Normal file
120
src/day13/main.rs
Normal 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}");
|
||||
}
|
Reference in New Issue
Block a user