diff --git a/2018/src/day5.rs b/2018/src/day5.rs new file mode 100644 index 0000000..e2d8849 --- /dev/null +++ b/2018/src/day5.rs @@ -0,0 +1,105 @@ +use std::collections::HashMap; +use std::collections::HashSet; +use std::fmt; + +const INPUT: &str = include_str!("input/day5.txt"); +// const INPUT: &str = "dabAcCaCBAcCcaDA"; + +#[derive(Debug, PartialEq, Eq, Clone)] +enum Polarity { + Upper, + Lower, +} + +#[derive(Debug, Clone)] +struct Unit { + name: String, + polarity: Polarity, +} + +type Polymer = Vec; +impl fmt::Display for Unit { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let c = match self.polarity { + Polarity::Upper => self.name.to_uppercase(), + Polarity::Lower => self.name.to_lowercase(), + }; + write!(f, "{}", c) + } +} + +fn parse_input(s: String) -> Polymer { + let mut polymer = Vec::new(); + for c in s.chars() { + polymer.push(Unit { + name: c.to_lowercase().to_string(), + polarity: if c.is_lowercase() { + Polarity::Lower + } else { + Polarity::Upper + }, + }); + } + polymer +} + +fn can_cancel(u1: &Unit, u2: &Unit) -> bool { + u1.name == u2.name && u1.polarity != u2.polarity +} + +// TODO: optimize +fn reduce(p: &mut Polymer) -> &Polymer { + let mut i = 0; + while i + 1 < p.len() { + if can_cancel(&p[i], &p[i + 1]) { + p.remove(i + 1); + p.remove(i); + return p; + } + i += 1; + } + p +} + +fn reduce_fully(p: &mut Polymer) -> &Polymer { + let mut old_len = p.len(); + loop { + reduce(p); + let new_len = p.len(); + if new_len == old_len { + break; + } + old_len = new_len; + } + p +} + +pub fn part1() -> usize { + let mut polymer = parse_input(INPUT.to_string()); + reduce_fully(&mut polymer); + polymer.len() +} + +fn unit_types(p: Polymer) -> HashSet { + let mut types = HashSet::new(); + for u in p { + types.insert(u.name); + } + types +} + +fn remove_all(p: Polymer, t: String) -> Polymer { + p.into_iter().filter(|u| u.name != t).collect() +} + +pub fn part2() -> &'static str { + let original = parse_input(INPUT.to_string()); + let types = unit_types(original.clone()); + let mut lengths = HashMap::new(); + for t in types { + let mut cleaned = remove_all(original.clone(), t.clone()); + reduce_fully(&mut cleaned); + lengths.insert(t, cleaned.len()); + } + "TODO" +} diff --git a/2018/src/main.rs b/2018/src/main.rs index bde3e90..8049e74 100644 --- a/2018/src/main.rs +++ b/2018/src/main.rs @@ -2,6 +2,7 @@ mod day1; mod day2; mod day3; mod day4; +// mod day5; // TODO: optimize fn main() { println!("Day 1 part 1: {}", day1::part1()); @@ -12,4 +13,6 @@ fn main() { println!("Day 3 part 2: {}", day3::part2()); println!("Day 4 part 1: {}", day4::part1()); println!("Day 4 part 2: {}", day4::part2()); + // println!("Day 5 part 1: {}", day5::part1()); // TODO: optimize + // println!("Day 5 part 2: {}", day5::part2()); // TODO: optimize }