diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a8a7fbf..03a0373 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -68,3 +68,8 @@ day-13: stage: build script: - cd day13; cargo run --release ./input + +day-14: + stage: build + script: + - cd day14; cargo run --release ./input diff --git a/day14/Cargo.toml b/day14/Cargo.toml new file mode 100644 index 0000000..85aa832 --- /dev/null +++ b/day14/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "day14" +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/day14/input b/day14/input new file mode 100644 index 0000000..5074877 --- /dev/null +++ b/day14/input @@ -0,0 +1,102 @@ +SCVHKHVSHPVCNBKBPVHV + +SB -> B +HH -> P +VF -> N +BS -> S +NC -> C +BF -> H +BN -> H +SP -> H +BK -> H +FF -> N +VN -> B +FN -> C +FS -> S +PP -> F +ON -> H +FV -> F +KO -> F +PK -> H +VB -> S +HS -> B +NV -> O +PN -> S +VH -> B +OS -> P +BP -> H +OV -> B +HK -> S +NN -> K +SV -> C +PB -> F +SK -> F +FB -> S +NB -> K +HF -> P +FK -> K +KV -> P +PV -> F +BC -> S +FO -> N +HC -> F +CP -> B +KK -> F +PC -> S +HN -> O +SH -> H +CK -> P +CO -> F +HP -> K +PS -> C +KP -> F +OF -> K +KS -> F +NO -> V +CB -> K +NF -> N +SF -> F +SC -> P +FC -> V +BV -> B +SS -> O +KC -> K +FH -> C +OP -> C +CF -> K +VO -> V +VK -> H +KH -> O +NP -> V +NH -> O +NS -> V +BH -> C +CH -> S +CC -> F +CS -> P +SN -> F +BO -> S +NK -> S +OO -> P +VV -> F +FP -> V +OK -> C +SO -> H +KN -> P +HO -> O +PO -> H +VS -> N +PF -> N +CV -> F +BB -> H +VC -> H +HV -> B +CN -> S +OH -> K +KF -> K +HB -> S +OC -> H +KB -> P +OB -> C +VP -> C +PH -> K diff --git a/day14/src/main.rs b/day14/src/main.rs new file mode 100644 index 0000000..4c1e09f --- /dev/null +++ b/day14/src/main.rs @@ -0,0 +1,67 @@ +use std::{fs, env, collections::HashMap}; + +fn read_input(path: &str) -> String { + return fs::read_to_string(path).expect("Cannot read file."); +} + +fn parse_input(s: &str) -> (HashMap<(char, char), u64>, + HashMap<(char, char), char>, + HashMap) { + let mut l = s.lines(); + let mut i = HashMap::new(); + let mut p = HashMap::new(); + let mut c = HashMap::new(); + let z: Vec = l.next().unwrap().chars().collect(); + for x in 0..z.len() - 1 { + c.insert(z[x], *c.get(&z[x]).unwrap_or(&0) + 1); + p.insert((z[x], z[x + 1]), *p.get(&(z[x], z[x + 1])).unwrap_or(&0) + 1); + } + c.insert(*z.last().unwrap(), *c.get(z.last().unwrap()).unwrap_or(&0) + 1); + l.next(); + for x in l { + let s = x.split_once(" -> ").unwrap(); + let mut a = s.0.chars(); + i.insert((a.next().unwrap(), a.next().unwrap()), s.1.chars().next().unwrap()); + } + return (p, i, c); +} + +fn apply_n_passes(p: &HashMap<(char, char), u64>, + i: &HashMap<(char, char), char>, + mut l: HashMap, n: u32) + -> (HashMap<(char, char), u64>, HashMap) { + let mut c = p.clone(); + for _o in 0..n { + let mut v = HashMap::new(); + for x in c.clone() { + let p = *i.get(&(x.0.0, x.0.1)).unwrap(); + l.insert(p, l.get(&p).unwrap_or(&0) + x.1); + v.insert((x.0.0, p), *v.get(&(x.0.0, p)).unwrap_or(&0) + x.1); + v.insert((p, x.0.1), *v.get(&(p, x.0.1)).unwrap_or(&0) + x.1); + } + c = v; + } + return (c, l); +} + +fn get_min_max_occurences(p: &HashMap) -> (u64, u64) { + return p.iter().fold((u64::MAX, u64::MIN), |acc, e| + (if *e.1 < acc.0 { *e.1 } else { acc.0 }, + if *e.1 > acc.1 { *e.1 } else { acc.1 })); +} + +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); + let mut c = apply_n_passes(&vec_in.0, &vec_in.1, vec_in.2.clone(), 10); + let mut m = get_min_max_occurences(&c.1); + println!("[{}]", &arg); + println!("\t[Part 1] => Answer is '{}'.", m.1 - m.0); + c = apply_n_passes(&c.0, &vec_in.1, vec_in.2, 30); + m = get_min_max_occurences(&c.1); + println!("\t[Part 2] => Answer is '{}'.", m.1 - m.0); + } +} +