151 lines
4.7 KiB
Rust
151 lines
4.7 KiB
Rust
use std::fs::File;
|
|
use std::io::{self, BufRead};
|
|
use std::path::Path;
|
|
use std::cmp::Ordering;
|
|
|
|
#[derive(Debug)]
|
|
enum Elem {
|
|
Number(u8),
|
|
List(Vec<Elem>),
|
|
}
|
|
|
|
use crate::Elem::{Number, List};
|
|
|
|
// I modified my input because the only 2 digits number was 10
|
|
// I replaced all 10s with ':' so that I can parse more easely
|
|
|
|
fn parse_line(line: &str, mut ind: usize) -> (Elem, usize) {
|
|
let mut elems: Vec<Elem> = vec![];
|
|
let mut len = 0;
|
|
while ind < line.len() {
|
|
let a = line[ind..ind+1].chars().next().unwrap();
|
|
match a {
|
|
'[' => { // Creer une List, la push sur le vecteur en cours
|
|
|
|
println!("Entering sublist from index {} to {}", ind, ind+1);
|
|
let (a, b) = parse_line(line, ind+1);
|
|
println!("Sublist len was {}, Left sublist, now at index {}", b, ind+b);
|
|
ind += b;
|
|
len += b;
|
|
elems.push(a);
|
|
},
|
|
']' => {
|
|
println!("Returning list with index {}", ind);
|
|
return (List(elems), len + 1);
|
|
} // Remonter le vecteur en cours de 1,
|
|
'0'..=':' => {
|
|
println!("Pushing {}", a as u8 - b'0');
|
|
elems.push(Number(a as u8 - b'0')); // Creer un nombre, le push sur le vecteur en cours
|
|
},
|
|
_ => (),
|
|
};
|
|
ind += 1;
|
|
len += 1;
|
|
}
|
|
unreachable!("parse_line end of function");
|
|
//println!("unreachable !!!! UNREACHABLE");
|
|
//(List(elems), len)
|
|
}
|
|
|
|
fn compare(lhs: &Elem, rhs: &Elem) -> Ordering {
|
|
let mut lhs_v = &vec![];
|
|
let mut rhs_v = &vec![];
|
|
|
|
if let List(a) = lhs {
|
|
lhs_v = a;
|
|
}
|
|
if let List(a) = rhs {
|
|
rhs_v = a;
|
|
}
|
|
|
|
println!("[ start list");
|
|
for i in 0..lhs_v.len() {
|
|
if i >= rhs_v.len() {
|
|
println!("Right side ran out of items, so inputs are NOT in the right order");
|
|
return Ordering::Greater;
|
|
}
|
|
match (&lhs_v[i], &rhs_v[i]) {
|
|
(List(_), List(_)) => {
|
|
let c = compare(&lhs_v[i], &rhs_v[i]);
|
|
if c != Ordering::Equal {
|
|
return c;
|
|
}
|
|
},
|
|
(List(_), Number(b)) => {
|
|
println!("Mixed types; convert right to [{}] and retry comparison", b);
|
|
let c = compare(&lhs_v[i], &List(vec![Number(*b)]));
|
|
if c != Ordering::Equal {
|
|
return c;
|
|
}
|
|
},
|
|
(Number(a), List(_)) => {
|
|
println!("Mixed types; convert left to [{}] and retry comparison", a);
|
|
let c = compare(&List(vec![Number(*a)]), &rhs_v[i]);
|
|
if c != Ordering::Equal {
|
|
return c;
|
|
}
|
|
},
|
|
(Number(a), Number(b)) => {
|
|
println!("Compare {} vs {}", a, b);
|
|
if a < b {
|
|
println!("Left side is smaller, so input are in the right order");
|
|
return Ordering::Less;
|
|
}
|
|
if a > b {
|
|
println!("Right side is smaller, so input are NOT in the right order");
|
|
return Ordering::Greater;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if rhs_v.len() > lhs_v.len() {
|
|
println!("Left side ran out of items, so inputs are in the right order");
|
|
return Ordering::Less;
|
|
}
|
|
println!("end list ]");
|
|
Ordering::Equal
|
|
}
|
|
|
|
fn main() {
|
|
let file_path = String::from("../aoc_13a/input");
|
|
println!("In file {}", file_path);
|
|
let mut data: Vec<Elem> = vec![];
|
|
|
|
if let Ok(lines) = read_lines(file_path) {
|
|
// Consumes the iterator, returns an (Optional) String
|
|
for (i, line) in lines.enumerate() {
|
|
if let Ok(ip) = line {
|
|
match i % 3 {
|
|
0..=1 => data.push(parse_line(&ip, 1).0),
|
|
_ => (),
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
data.push(List(vec![List(vec![Number(2)])]));
|
|
data.push(List(vec![List(vec![Number(6)])]));
|
|
data.sort_by(|a, b| compare(a, b));
|
|
|
|
let mut a = None;
|
|
let mut b = None;
|
|
for i in 0..data.len() {
|
|
if compare(&data[i], &List(vec![List(vec![Number(2)])])) == Ordering::Equal {
|
|
a = Some(i + 1);
|
|
}
|
|
if compare(&data[i], &List(vec![List(vec![Number(6)])])) == Ordering::Equal {
|
|
b = Some(i + 1);
|
|
}
|
|
}
|
|
let a = a.unwrap();
|
|
let b = b.unwrap();
|
|
println!("{} {} {}", a, b, a * b);
|
|
//println!("{:?}", data);
|
|
}
|
|
|
|
fn read_lines<P>(filename: P) -> io::Result<io::Lines<io::BufReader<File>>>
|
|
where P: AsRef<Path>, {
|
|
let file = File::open(filename)?;
|
|
Ok(io::BufReader::new(file).lines())
|
|
}
|