diff --git a/src/bin/03.rs b/src/bin/03.rs new file mode 100644 index 0000000..451493a --- /dev/null +++ b/src/bin/03.rs @@ -0,0 +1,83 @@ +use std::collections::HashSet; + +pub fn part_one(input: &str) -> Option { + let l = input.lines(); + let mut result: u32 = 0; + for line in l { + // using hashsets for this is very overkill but I don't care + let (pocket1, pocket2) = line.split_at(line.len()/2); + let mut pk1set = HashSet::new(); + let mut pk2set = HashSet::new(); + + // in general, you shouldn't iterate over a string by bytes. Only doing it here because input is certain to be 1byte ASCII + for b in pocket1.bytes() { pk1set.insert(b); }; + for b in pocket2.bytes() { pk2set.insert(b); }; + + // the single elegant line that this exists to set up + let shared = pk1set.intersection(&pk2set).next().unwrap(); + + // the shared item is an ASCII byte. The priority system is alphabetical with lowercase before uppercase. + // this is close to how ASCII works but with the cases swapped. So subtract 0x40 to get the alphabetical position, if it's over 26 (lowercase) then subtract 32 more, otherwise add 26. + // this is ugly math but idk a better way to do it so here it is. + + if shared-0x40 >= 27 { + result += (shared-0x40-32) as u32; + } else { + result += (shared-0x40+26) as u32; + } + } + Some(result) + +} + +pub fn part_two(input: &str) -> Option { + //just brute force it tbf + let mut result = 0; + let lines: Vec<&str> = input.lines().collect(); + let mut shared = 0; + for i in 0..(lines.len()/3) { + 'search: for x in lines[i*3].bytes() { + for y in lines[i*3+1].bytes() { + for z in lines[i*3+2].bytes() { + if x == y && y == z { + shared = z; + break 'search; + } + } + } + } + // the shared item is an ASCII byte. The priority system is alphabetical with lowercase before uppercase. + // this is close to how ASCII works but with the cases swapped. So subtract 0x40 to get the alphabetical position, if it's over 26 (lowercase) then subtract 32 more, otherwise add 26. + // this is ugly math but idk a better way to do it so here it is. + + if shared-0x40 >= 27 { + result += (shared-0x40-32) as u32; + } else { + result += (shared-0x40+26) as u32; + } + } + Some(result) +} + +fn main() { + let input = &advent_of_code::read_file("inputs", 3); + advent_of_code::solve!(1, part_one, input); + advent_of_code::solve!(2, part_two, input); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_part_one() { + let input = advent_of_code::read_file("examples", 3); + assert_eq!(part_one(&input), Some(157)); + } + + #[test] + fn test_part_two() { + let input = advent_of_code::read_file("examples", 3); + assert_eq!(part_two(&input), Some(70)); + } +} diff --git a/src/examples/03.txt b/src/examples/03.txt new file mode 100644 index 0000000..9919ffa --- /dev/null +++ b/src/examples/03.txt @@ -0,0 +1,6 @@ +vJrwpWtwJgWrhcsFMMfFFhFp +jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL +PmmdzqPrVvPwwTWBwg +wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn +ttgJtRGJQctTZtZT +CrZsJsPPZsGzwwsLwLmpwMDw \ No newline at end of file