diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 16b85d0..97d2a7b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -88,3 +88,8 @@ day-17: stage: build script: - cd day17; cargo run --release ./input + +day-18: + stage: build + script: + - cd day18; cargo run --release ./input diff --git a/day18/Cargo.toml b/day18/Cargo.toml new file mode 100644 index 0000000..fa53f27 --- /dev/null +++ b/day18/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "day18" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/day18/input b/day18/input new file mode 100644 index 0000000..983da28 --- /dev/null +++ b/day18/input @@ -0,0 +1,100 @@ +[[0,6],[[[4,0],[6,6]],[[2,2],9]]] +[[9,[[1,6],[6,0]]],[[1,[0,8]],[[0,8],[9,8]]]] +[[[0,[2,1]],3],[[[2,4],[1,2]],[7,5]]] +[[[[8,3],[8,5]],[[7,8],[5,5]]],[9,2]] +[[8,[1,9]],[[[9,9],[9,2]],1]] +[[[[3,7],[2,1]],[0,9]],4] +[[[[3,8],[6,0]],[0,7]],[[[6,3],[2,0]],9]] +[[[9,[7,0]],[8,[9,6]]],[[5,6],4]] +[[[[3,6],[3,6]],[0,2]],[[[8,3],9],[[3,4],8]]] +[[7,[8,4]],1] +[6,[[3,[5,6]],[0,6]]] +[[[7,[4,7]],[[4,5],[4,3]]],[[5,5],[0,[4,2]]]] +[[[0,[2,9]],[[2,4],[4,8]]],[[8,[9,5]],[[9,6],0]]] +[[[[2,0],[9,7]],[[3,2],0]],[7,7]] +[[5,[2,1]],[[3,[5,1]],[[8,5],[1,8]]]] +[[[[9,7],6],[[7,8],7]],[[[6,8],9],[[9,5],7]]] +[[4,2],[[[0,1],[7,2]],[[0,2],[5,5]]]] +[[1,8],[[5,[7,9]],[[3,1],[7,1]]]] +[[[4,[4,6]],6],5] +[[[5,[3,6]],6],[[[8,0],[8,6]],[[3,3],[0,1]]]] +[[4,[[2,6],[0,9]]],[[0,6],[4,2]]] +[[[[9,4],[6,5]],7],[[[1,5],[0,9]],[4,[4,2]]]] +[[7,[[6,5],8]],[[[5,6],0],[6,[3,5]]]] +[[[5,[6,4]],[8,[0,4]]],[[3,[9,3]],4]] +[[[[4,0],6],[6,[6,5]]],[[9,[6,3]],[[9,6],7]]] +[[[[2,2],4],[8,[7,2]]],[2,1]] +[5,[9,[[5,9],4]]] +[[[1,[7,7]],[[2,2],8]],[[[9,7],5],[4,3]]] +[[[[6,8],1],1],[1,[[2,0],6]]] +[[[[0,5],8],[[8,9],[9,3]]],[[[5,5],[4,2]],2]] +[[[9,[2,5]],[6,[1,7]]],[5,[3,[2,2]]]] +[[[7,6],8],[[[1,9],3],[5,2]]] +[8,[[2,[0,7]],8]] +[[[[8,1],[0,0]],5],1] +[[1,[[4,8],0]],[[9,[7,8]],5]] +[[[[1,3],1],[[9,8],[6,6]]],5] +[[[3,2],[[0,5],[0,1]]],[[9,[9,3]],[4,9]]] +[[[0,[2,4]],[[3,3],[6,5]]],[[1,[2,1]],[[3,4],9]]] +[[2,[3,[7,6]]],[5,5]] +[[[[8,2],0],[[9,6],[9,0]]],[[[6,2],[5,0]],9]] +[7,[9,7]] +[3,[[[5,5],1],[8,5]]] +[[[5,5],[5,6]],[9,5]] +[[[9,7],[1,2]],[8,[5,[7,0]]]] +[[[1,[5,2]],[7,[8,9]]],[2,[[4,5],[2,3]]]] +[[[4,[2,2]],[5,[4,7]]],[[[0,3],2],[5,[2,6]]]] +[[0,[[6,5],5]],[[7,[7,2]],3]] +[[[4,[9,4]],[1,9]],[7,[[7,1],[6,1]]]] +[1,[0,2]] +[[[[5,1],[2,1]],[[7,8],6]],[[3,[4,9]],2]] +[[9,[[4,0],[8,8]]],[[[6,6],[2,8]],[1,[1,5]]]] +[[[1,2],[7,0]],[7,[[3,0],5]]] +[[[6,[0,8]],3],[[3,7],1]] +[[[[6,1],[1,0]],9],[[4,8],[3,[0,8]]]] +[[6,[3,[5,8]]],9] +[[[[5,0],[7,7]],[[3,1],[4,8]]],5] +[[[3,7],[9,0]],[[[0,2],7],0]] +[8,9] +[[8,[[0,8],4]],[1,[[4,6],2]]] +[[[5,5],3],[[6,6],[0,[6,3]]]] +[[[7,[3,7]],[[6,1],[9,4]]],[[[8,9],1],[[8,7],6]]] +[[6,[[0,9],[2,3]]],[[1,[5,3]],[8,4]]] +[[[3,5],8],[[[2,4],[7,5]],5]] +[[0,[[7,0],[9,4]]],[[[0,0],[6,7]],[6,5]]] +[[[[1,9],[6,4]],0],[6,[3,[4,8]]]] +[[[[1,6],[0,4]],8],[[8,8],6]] +[[[[7,4],[9,6]],7],[[1,6],[1,0]]] +[1,[[[6,8],5],5]] +[8,4] +[9,[[9,[3,9]],0]] +[5,[[[4,9],7],[[1,0],0]]] +[[[6,1],[0,[2,3]]],[[[7,8],[5,9]],9]] +[3,[[3,[3,4]],[6,[7,8]]]] +[[[7,[7,1]],[4,[2,0]]],[6,[7,3]]] +[[6,9],[[3,[4,7]],3]] +[1,[[9,[5,1]],[7,[7,5]]]] +[[3,2],[[9,[6,8]],[[1,0],2]]] +[[[[3,2],8],[7,6]],9] +[[3,[[9,5],6]],[5,9]] +[[[3,[6,3]],[[7,0],[5,7]]],[[3,3],[[4,9],[4,8]]]] +[[[0,[4,3]],2],[3,[0,[1,3]]]] +[[[7,[3,4]],[7,[3,1]]],[[0,[4,7]],6]] +[[[1,[7,4]],[[8,7],3]],4] +[[[5,5],[[0,3],2]],[1,[[9,4],6]]] +[[[[6,0],[8,8]],[6,[6,0]]],[5,6]] +[[[1,[5,4]],[[5,9],[1,7]]],[[5,[4,7]],[4,[4,4]]]] +[[0,[[2,6],0]],[[6,[4,3]],5]] +[[[1,[5,3]],[9,[1,2]]],[[[4,8],[5,6]],0]] +[[0,7],[1,[7,7]]] +[4,[[7,[7,2]],[[9,1],7]]] +[2,[[1,6],[6,9]]] +[[[4,[4,5]],9],[[[1,7],6],[3,[7,3]]]] +[[6,[[1,1],[7,8]]],[[[5,2],[8,1]],5]] +[[[5,5],[[4,1],[1,2]]],[[3,8],[3,4]]] +[[[[1,9],[0,3]],[4,[0,9]]],4] +[[[4,9],0],[[9,0],[8,[7,5]]]] +[[6,[5,3]],[[[6,6],4],[[6,8],4]]] +[[[[1,1],2],1],[1,[[6,4],2]]] +[[[[6,3],[1,5]],[6,[7,7]]],[6,6]] +[[[[3,0],[5,6]],1],[[[9,3],[1,7]],[[3,4],[2,7]]]] diff --git a/day18/src/main.rs b/day18/src/main.rs new file mode 100644 index 0000000..84e018d --- /dev/null +++ b/day18/src/main.rs @@ -0,0 +1,118 @@ +use std::{fs, env}; + +fn read_input(path: &str) -> String { + return fs::read_to_string(path).expect("Cannot read file."); +} + +fn parse_input(s: &str) -> Vec> { + let mut r = vec![]; + for l in s.lines() { + let mut d = 0; + let mut v = vec![]; + for c in l.chars() { + if c == '[' { + d += 1; + } else if c == ']' { + d -= 1; + } else if c.is_digit(10) { + v.push((d, c.to_digit(10).unwrap())); + } + } + r.push(v); + } + return r; +} + +fn sum(l: &Vec<(u8, u32)>, r: &Vec<(u8, u32)>) -> Vec<(u8, u32)> { + let mut v = vec![]; + v.append(&mut l.iter().map(|x| (x.0 + 1, x.1)).collect()); + v.append(&mut r.iter().map(|x| (x.0 + 1, x.1)).collect()); + return v; +} + +fn reduce(v: &mut Vec<(u8, u32)>) { + while explode(v) || split(v) {} +} + +fn explode(v: &mut Vec<(u8, u32)>) -> bool { + for i in 0..v.len() - 1 { + if v[i].0 > 4 && v[i + 1].0 > 4 { + if i > 0 { + v[i - 1].1 += v[i].1; + } + if i + 2 < v.len() { + v[i + 2].1 += v[i + 1].1; + } + v.remove(i + 1); + v[i].0 -= 1; + v[i].1 = 0; + return true; + } + } + return false; +} + +fn split(v: &mut Vec<(u8, u32)>) -> bool { + for i in 0..v.len() { + if v[i].1 >= 10 { + let d = v[i].1 as f32 / 2f32; + v[i].1 = d.floor() as u32; + v[i].0 += 1; + v.insert(i + 1, (v[i].0, d.ceil() as u32)); + return true; + } + } + return false; +} + +fn compute(v: &Vec>) -> Vec<(u8, u32)> { + if v.is_empty() { return vec![]; } + let mut r = v[0].clone(); + for x in 1..v.len() { + r = sum(&r, &v[x]); + reduce(&mut r); + } + return r; +} + +fn get_magnitude(mut v: Vec<(u8, u32)>) -> u32 { + if v.is_empty() { return 0; } + for d in (0..=4).rev() { + let mut t = vec![]; + let mut s = false; + for i in 0..v.len() { + if s { s = false; continue; } + if i + 1 < v.len() && v[i].0 == d && v[i + 1].0 == d { + t.push((d - 1, 3 * v[i].1 + 2 * v[i + 1].1)); + s = true; + } else { t.push(v[i]); } + } + v = t; + } + return v[0].1; +} + +fn get_max_magnitude(v: &Vec>) -> u32 { + let mut m = vec![]; + for a in v { + for b in v { + if a != b { + let c = vec![a.to_owned(), b.to_owned()]; + m.push(get_magnitude(compute(&c))); + } + } + } + return m.iter().fold(u32::MIN, |acc, i| if *i > acc { *i } else { acc }); +} + +fn main() { + let args: Vec = env::args().collect(); + for arg in args.iter().skip(1) { + let input = read_input(&arg); + let vec_in = parse_input(&input); + println!("[{}]", &arg); + println!("\t[Part 1] => Answer is '{}'.", get_magnitude(compute(&vec_in))); + println!("\t[Part 2] => Answer is '{}'.", get_max_magnitude(&vec_in)); + } +} +