diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 371ec3a..72daea1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -78,3 +78,8 @@ day-15: stage: build script: - cd day15; cargo run --release ./input + +day-16: + stage: build + script: + - cd day16; cargo run --release ./input diff --git a/day16/Cargo.toml b/day16/Cargo.toml new file mode 100644 index 0000000..597b6da --- /dev/null +++ b/day16/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "day16" +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/day16/input b/day16/input new file mode 100644 index 0000000..933fe91 --- /dev/null +++ b/day16/input @@ -0,0 +1 @@ +C20D718021600ACDC372CD8DE7A057252A49C940239D68978F7970194EA7CCB310088760088803304A0AC1B100721EC298D3307440041CD8B8005D12DFD27CBEEF27D94A4E9B033006A45FE71D665ACC0259C689B1F99679F717003225900465800804E39CE38CE161007E52F1AEF5EE6EC33600BCC29CFFA3D8291006A92CA7E00B4A8F497E16A675EFB6B0058F2D0BD7AE1371DA34E730F66009443C00A566BFDBE643135FEDF321D000C6269EA66545899739ADEAF0EB6C3A200B6F40179DE31CB7B277392FA1C0A95F6E3983A100993801B800021B0722243D00042E0DC7383D332443004E463295176801F29EDDAA853DBB5508802859F2E9D2A9308924F9F31700AA4F39F720C733A669EC7356AC7D8E85C95E123799D4C44C0109C0AF00427E3CC678873F1E633C4020085E60D340109E3196023006040188C910A3A80021B1763FC620004321B4138E52D75A20096E4718D3E50016B19E0BA802325E858762D1802B28AD401A9880310E61041400043E2AC7E8A4800434DB24A384A4019401C92C154B43595B830002BC497ED9CC27CE686A6A43925B8A9CFFE3A9616E5793447004A4BBB749841500B26C5E6E306899C5B4C70924B77EF254B48688041CD004A726ED3FAECBDB2295AEBD984E08E0065C101812E006380126005A80124048CB010D4C03DC900E16A007200B98E00580091EE004B006902004B00410000AF00015933223100688010985116A311803D05E3CC4B300660BC7283C00081CF26491049F3D690E9802739661E00D400010A8B91F2118803310A2F43396699D533005E37E8023311A4BB9961524A4E2C027EC8C6F5952C2528B333FA4AD386C0A56F39C7DB77200C92801019E799E7B96EC6F8B7558C014977BD00480010D89D106240803518E31C4230052C01786F272FF354C8D4D437DF52BC2C300567066550A2A900427E0084C254739FB8E080111E0 diff --git a/day16/src/main.rs b/day16/src/main.rs new file mode 100644 index 0000000..3b7ccf0 --- /dev/null +++ b/day16/src/main.rs @@ -0,0 +1,87 @@ +use std::{fs, env}; + +#[derive(Debug)] +struct Packet { + v: u8, + c: i64, + s: Vec +} + +fn read_input(path: &str) -> String { + return fs::read_to_string(path).expect("Cannot read file."); +} + +fn parse_input(s: &str) -> Vec { + let s = s.lines().last().unwrap(); + let mut x = vec![]; + for c in s.chars() { + let v = c.to_digit(16).unwrap(); + x.push((v & 0b1000) != 0); + x.push((v & 0b100) != 0); + x.push((v & 0b10) != 0); + x.push((v & 1) != 0); + } + return x; +} + +fn get_int(v: &Vec) -> i64 { + return v.iter().fold(0, |acc, e| (acc << 1) + if *e { 1 } else { 0 }); +} + +fn get_packet(x: &mut Vec) -> Packet { + let v = get_int(&x.drain(0..3).collect()) as u8; + let t = get_int(&x.drain(0..3).collect()) as u8; + let c; + let mut s = vec![]; + if t == 4 { + let mut i = vec![]; + let mut w = true; + while w { + w = x.remove(0); + i.append(&mut x.drain(0..4).collect()); + } + + c = get_int(&i); + } else { + if x.remove(0) { + let n = get_int(&x.drain(0..11).collect()); + for _i in 0..n { s.push(get_packet(x)); } + } else { + let mut n = get_int(&x.drain(0..15).collect()) as usize; + while n != 0 { + let b = x.len(); + s.push(get_packet(x)); + n -= b - x.len(); + } + } + c = match t { + 0 => { s.iter().fold(0, |acc, e| acc + e.c) } + 1 => { s.iter().fold(1, |acc, e| acc * e.c) } + 2 => { s.iter().fold(i64::MAX, |acc, e| if e.c < acc { e.c } else { acc }) } + 3 => { s.iter().fold(i64::MIN, |acc, e| if e.c > acc { e.c } else { acc }) } + 5 => { if s[0].c > s[1].c { 1 } else { 0 } } + 6 => { if s[0].c < s[1].c { 1 } else { 0 } } + 7 => { if s[0].c == s[1].c { 1 } else { 0 } } + _ => { panic!() } + }; + } + + return Packet { v, c, s }; +} + +fn get_version_sum(p: &Packet) -> u32 { + return p.v as u32 + p.s.iter().fold(0, |acc, s| acc + get_version_sum(s)); +} + +fn main() { + let args: Vec = env::args().collect(); + for arg in args.iter().skip(1) { + let input = read_input(&arg); + let mut x = parse_input(&input); + let p = get_packet(&mut x); + println!("[{}]", &arg); + println!("\t[Part 1] => Answer is '{}'.", get_version_sum(&p)); + println!("\t[Part 2] => Answer is '{}'.", p.c); + } +} +