diff --git a/day13/src/main.rs b/day13/src/main.rs index 318344c..4877fb0 100644 --- a/day13/src/main.rs +++ b/day13/src/main.rs @@ -1,4 +1,5 @@ use std::env; +use std::cmp::Ordering; use std::fs::File; use std::io::{BufReader, BufRead}; @@ -17,40 +18,43 @@ fn parse_num(s: &[u8]) -> (u64, usize) { } // Assuming no malformed input -fn is_in_order(left: &[u8], right: &[u8]) -> bool { - //println!(">> {:?}, {:?} -- {:?}", str::from_utf8(left), str::from_utf8(right)); +fn compare(left: &[u8], right: &[u8]) -> Ordering { if left.len() == 0 { - return true; + return Ordering::Less; } if right.len() == 0 { - return false; + return Ordering::Greater; } let (l, r) = (left[0], right[0]); if l == b',' && r == b',' { - is_in_order(&left[1..], &right[1..]) + compare(&left[1..], &right[1..]) } else if l == b'[' && r == b'[' { - is_in_order(&left[1..], &right[1..]) + compare(&left[1..], &right[1..]) } else if l == b']' && r == b']' { - is_in_order(&left[1..], &right[1..]) + compare(&left[1..], &right[1..]) } else if l == b']' { - true + Ordering::Less } else if r == b']' { - false + Ordering::Greater } else if l == b'[' { let (num, len) = parse_num(right); - is_in_order(&left, &[b"[", num.to_string().as_bytes(), b"]", &right[len..]].concat()) + compare( + &left, + &[b"[", num.to_string().as_bytes(), b"]", &right[len..]].concat()) } else if r == b'[' { let (num, len) = parse_num(left); - is_in_order(&[b"[", num.to_string().as_bytes(), b"]", &left[len..]].concat(), &right) + compare( + &[b"[", num.to_string().as_bytes(), b"]", &left[len..]].concat(), + &right) } else { let (lnum, llen) = parse_num(left); let (rnum, rlen) = parse_num(right); if lnum < rnum { - true + Ordering::Less } else if lnum > rnum { - false + Ordering::Greater } else { - is_in_order(&left[llen..], &right[rlen..]) + compare(&left[llen..], &right[rlen..]) } } @@ -58,17 +62,20 @@ fn is_in_order(left: &[u8], right: &[u8]) -> bool { fn main() { let file = File::open(&env::args().nth(1).expect("input")).expect("io err"); - let lines: Vec = BufReader::new(file).lines().flatten().collect(); - // TODO: array_chunks() for lazy iter? - let blocks: Vec<_> = lines.chunks(3).collect(); + let mut lines: Vec<_> = BufReader::new(file).lines().flatten() + .filter(|line| line != "").collect(); + lines.push(String::from("[[2]]")); + lines.push(String::from("[[6]]")); + lines.sort_unstable_by(|s1, s2| compare(s1.as_bytes(), s2.as_bytes())); - let mut sum = 0; - for (i, block) in blocks.iter().enumerate() { - // TODO: return error here instead of assert? - assert!((block.len() == 3 && block[2] == "") || block.len() == 2); - if is_in_order(block[0].as_bytes(), block[1].as_bytes()) { - sum += i + 1; + let (mut six, mut two): (usize, usize) = (0, 0); + for (i, line) in lines.iter().enumerate() { + if line == "[[6]]" { + six = i + 1; + } + if line == "[[2]]" { + two = i + 1; } } - println!("Answer: {:?}", sum); + println!("{:?}", six*two); } diff --git a/day13/src/main1.rs b/day13/src/main1.rs new file mode 100644 index 0000000..318344c --- /dev/null +++ b/day13/src/main1.rs @@ -0,0 +1,74 @@ +use std::env; +use std::fs::File; +use std::io::{BufReader, BufRead}; + +fn parse_num(s: &[u8]) -> (u64, usize) { + let mut num: u64 = 0; + let mut len = 0; + for i in 0..s.len() { + if s[i].is_ascii_digit() { + num = num*10 + (s[i] as u64 - '0' as u64); + len += 1; + } else { + break; + } + } + (num, len) +} + +// Assuming no malformed input +fn is_in_order(left: &[u8], right: &[u8]) -> bool { + //println!(">> {:?}, {:?} -- {:?}", str::from_utf8(left), str::from_utf8(right)); + if left.len() == 0 { + return true; + } + if right.len() == 0 { + return false; + } + let (l, r) = (left[0], right[0]); + if l == b',' && r == b',' { + is_in_order(&left[1..], &right[1..]) + } else if l == b'[' && r == b'[' { + is_in_order(&left[1..], &right[1..]) + } else if l == b']' && r == b']' { + is_in_order(&left[1..], &right[1..]) + } else if l == b']' { + true + } else if r == b']' { + false + } else if l == b'[' { + let (num, len) = parse_num(right); + is_in_order(&left, &[b"[", num.to_string().as_bytes(), b"]", &right[len..]].concat()) + } else if r == b'[' { + let (num, len) = parse_num(left); + is_in_order(&[b"[", num.to_string().as_bytes(), b"]", &left[len..]].concat(), &right) + } else { + let (lnum, llen) = parse_num(left); + let (rnum, rlen) = parse_num(right); + if lnum < rnum { + true + } else if lnum > rnum { + false + } else { + is_in_order(&left[llen..], &right[rlen..]) + } + } + +} + +fn main() { + let file = File::open(&env::args().nth(1).expect("input")).expect("io err"); + let lines: Vec = BufReader::new(file).lines().flatten().collect(); + // TODO: array_chunks() for lazy iter? + let blocks: Vec<_> = lines.chunks(3).collect(); + + let mut sum = 0; + for (i, block) in blocks.iter().enumerate() { + // TODO: return error here instead of assert? + assert!((block.len() == 3 && block[2] == "") || block.len() == 2); + if is_in_order(block[0].as_bytes(), block[1].as_bytes()) { + sum += i + 1; + } + } + println!("Answer: {:?}", sum); +}