mirror of
https://github.com/wezm/advent-of-code.git
synced 2024-11-10 01:42:33 +00:00
100 lines
2.3 KiB
Rust
100 lines
2.3 KiB
Rust
|
use std::fs;
|
||
|
|
||
|
struct Polymer {
|
||
|
units: Vec<char>,
|
||
|
}
|
||
|
|
||
|
fn reacts(chr1: char, chr2: char) -> bool {
|
||
|
// The is_ascii_lowercase probably isn't strictly necessary but ¯\_(ツ)_/¯
|
||
|
(chr1.is_ascii_uppercase() && chr2 == chr1.to_ascii_lowercase())
|
||
|
|| (chr1.is_ascii_lowercase() && chr2 == chr1.to_ascii_uppercase())
|
||
|
}
|
||
|
|
||
|
impl Polymer {
|
||
|
fn new() -> Self {
|
||
|
Polymer { units: Vec::new() }
|
||
|
}
|
||
|
|
||
|
fn last(&self) -> Option<char> {
|
||
|
self.units.last().map(|c| *c)
|
||
|
}
|
||
|
|
||
|
fn push(&mut self, chr: char) {
|
||
|
// if the char being pushed is the same as the top of stack then pop it, otherwise push
|
||
|
if self.last().map(|top| reacts(top, chr)).unwrap_or(false) {
|
||
|
self.units.pop();
|
||
|
} else {
|
||
|
self.units.push(chr);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn into_string(self) -> String {
|
||
|
self.units.iter().collect()
|
||
|
}
|
||
|
|
||
|
fn len(&self) -> usize {
|
||
|
self.units.len()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn main() {
|
||
|
let input = fs::read_to_string("input/day5.txt").expect("input");
|
||
|
|
||
|
part1(input.trim());
|
||
|
part2(input.trim());
|
||
|
}
|
||
|
|
||
|
fn part1(input: &str) {
|
||
|
let result = reduce(input);
|
||
|
|
||
|
println!("{}", result.len());
|
||
|
}
|
||
|
|
||
|
fn part2(input: &str) {
|
||
|
let shortest_length = "abcdefghijklmnopqrstuvwxyz"
|
||
|
.chars()
|
||
|
.map(|letter| {
|
||
|
// Remove letter/LETTER and LETTER/letter
|
||
|
let input = input
|
||
|
.replace(letter, "")
|
||
|
.replace(letter.to_ascii_uppercase(), "");
|
||
|
reduce(&input)
|
||
|
})
|
||
|
.min_by(|polymer_a, polymer_b| polymer_a.len().cmp(&polymer_b.len()));
|
||
|
|
||
|
println!("Part 2: {:?}", shortest_length.map(|polymer| polymer.len()));
|
||
|
}
|
||
|
|
||
|
fn reduce(input: &str) -> Polymer {
|
||
|
input.chars().fold(Polymer::new(), |mut polymer, chr| {
|
||
|
polymer.push(chr);
|
||
|
polymer
|
||
|
})
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn test_reacts() {
|
||
|
assert!(reacts('a', 'A'));
|
||
|
assert!(reacts('A', 'a'));
|
||
|
assert!(!reacts('A', 'A'));
|
||
|
assert!(!reacts('a', 'a'));
|
||
|
assert!(!reacts('a', 'B'));
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn test_part1() {
|
||
|
let input = "dabAcCaCBAcCcaDA";
|
||
|
let result = reduce(input);
|
||
|
|
||
|
assert_eq!(result.len(), 10);
|
||
|
assert_eq!(result.into_string(), "dabCBAcaDA".to_string());
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn test_part1_snippet() {
|
||
|
let input = "wUuXxrRbeEaAuUMmJUuXxvoFfMmOTjJmMtVvmMVWpdDPwGgAalVv";
|
||
|
let result = reduce(input);
|
||
|
|
||
|
assert_eq!(result.into_string(), "wbJl".to_string());
|
||
|
}
|