From de3f90b5164fdcf77bbd0ad66efe7b9d1a51e126 Mon Sep 17 00:00:00 2001 From: Charles Date: Thu, 5 Dec 2024 22:50:40 -0800 Subject: [PATCH] add: day 5, day 6 --- src/bin/d5p1.rs | 64 +++++++++++++++++++++++++++++++++++ src/bin/d5p1.txt | 28 +++++++++++++++ src/bin/d5p2.rs | 61 +++++++++++++++++++++++++++++++++ src/bin/d6p1.rs | 88 ++++++++++++++++++++++++++++++++++++++++++++++++ src/bin/d6p1.txt | 10 ++++++ src/lib.rs | 2 +- 6 files changed, 252 insertions(+), 1 deletion(-) create mode 100644 src/bin/d5p1.rs create mode 100644 src/bin/d5p1.txt create mode 100644 src/bin/d5p2.rs create mode 100644 src/bin/d6p1.rs create mode 100644 src/bin/d6p1.txt diff --git a/src/bin/d5p1.rs b/src/bin/d5p1.rs new file mode 100644 index 0000000..3b350ca --- /dev/null +++ b/src/bin/d5p1.rs @@ -0,0 +1,64 @@ +use std::collections::{HashMap, HashSet}; + +use advent_of_code_2024::{make_main, SResult}; + +make_main!(); + +fn solve(lines: Vec) -> SResult { + let mut page_order: HashMap> = HashMap::default(); + // Read in the orders + let mut i = 0; + while i < lines.len() { + if lines[i].trim() == "" { + break; + } + let (a, b) = lines[i].split_once("|").unwrap(); + let (a, b) = (a.parse::().unwrap(), b.parse::().unwrap()); + let hs = page_order.entry(a).or_insert_with(|| HashSet::new()); + hs.insert(b); + i += 1; + } + + // Check remaining lines for order + let mut total = 0; + for line in &lines[i + 1..] { + let parts: Vec = line + .split(",") + .map(|v| v.parse::().unwrap()) + .collect(); + let mut seen: HashSet = HashSet::new(); + let mut invalid = false; + for val in &parts { + if let Some(after) = page_order.get(&val) { + for a in after.iter() { + if seen.contains(a) { + invalid = true; + break; + } + } + if invalid { + break; + } + } + seen.insert(*val); + } + if !invalid { + total += parts[parts.len()/2]; + } + } + + Ok(total) +} + +#[cfg(test)] +mod tests { + use advent_of_code_2024::input; + + use super::*; + #[test] + fn sample_input() { + let strings: Vec = input!("d5p1.txt"); + let got = solve(strings).unwrap(); + assert_eq!(got, 143); + } +} diff --git a/src/bin/d5p1.txt b/src/bin/d5p1.txt new file mode 100644 index 0000000..d4d4441 --- /dev/null +++ b/src/bin/d5p1.txt @@ -0,0 +1,28 @@ +47|53 +97|13 +97|61 +97|47 +75|29 +61|13 +75|53 +29|13 +97|29 +53|29 +61|53 +97|53 +61|29 +47|13 +75|47 +97|75 +47|61 +75|61 +47|29 +75|13 +53|13 + +75,47,61,53,29 +97,61,53,29,13 +75,29,13 +75,97,47,61,53 +61,13,29 +97,13,75,29,47 \ No newline at end of file diff --git a/src/bin/d5p2.rs b/src/bin/d5p2.rs new file mode 100644 index 0000000..e1e613f --- /dev/null +++ b/src/bin/d5p2.rs @@ -0,0 +1,61 @@ +use std::{cmp::Ordering, collections::{HashMap, HashSet}}; + +use advent_of_code_2024::{make_main, SResult}; + +make_main!(); + +fn solve(lines: Vec) -> SResult<(usize, usize)> { + let mut order: HashMap> = HashMap::default(); + // Read in the orders + let mut i = 0; + while i < lines.len() { + if lines[i].trim() == "" { + break; + } + let (a, b) = lines[i].split_once("|").unwrap(); + let (a, b) = (a.parse::().unwrap(), b.parse::().unwrap()); + order.entry(a).or_insert_with(HashSet::new).insert(b); + order.entry(b).or_insert_with(HashSet::new); + i += 1; + } + + // Check remaining lines for order + let mut p1total = 0; + let mut p2total = 0; + for line in &lines[i + 1..] { + let parts: Vec = line + .split(",") + .map(|v| v.parse::().unwrap()) + .collect(); + let mut sorted = parts.clone(); + sorted.sort_by(|a, b| { + if order[a].contains(b) { + Ordering::Less + } else if order[b].contains(a) { + Ordering::Greater + } else { + Ordering::Equal + } + }); + if sorted != parts { + p2total += sorted[parts.len()/2]; + } else { + p1total += parts[parts.len()/2]; + } + } + + Ok((p1total, p2total)) +} + +#[cfg(test)] +mod tests { + use advent_of_code_2024::input; + + use super::*; + #[test] + fn sample_input() { + let strings: Vec = input!("d5p1.txt"); + let got = solve(strings).unwrap(); + assert_eq!(got, (143, 123)); + } +} diff --git a/src/bin/d6p1.rs b/src/bin/d6p1.rs new file mode 100644 index 0000000..f51a429 --- /dev/null +++ b/src/bin/d6p1.rs @@ -0,0 +1,88 @@ +use std::collections::HashSet; + +use advent_of_code_2024::{make_main, next, Pair, SResult}; + +make_main!(); + +fn solve(lines: Vec) -> SResult<(usize, usize)> { + // Convert lines to our map + let vels = vec![('>', (0, 1)), ('v', (1, 0)), ('<', (0, -1)), ('^', (-1, 0))]; + let mut map = Vec::with_capacity(lines.len()); + let mut start_position: Pair = (0, 0); + let mut cur_icon = 0; + for (i, line) in lines.iter().enumerate() { + map.push(line.chars().collect::>()); + for (j, c) in line.chars().enumerate() { + for (index, (cc, _)) in vels.iter().enumerate() { + if c == *cc { + cur_icon = index; + start_position = (i, j); + break; + } + } + } + } + + let (count, paths) = walk(&map, start_position, cur_icon, &vels).unwrap(); + + // Try placing problems + let mut blocks: HashSet = HashSet::new(); + for path in paths.iter() { + let next = match next(path.0, vels[path.1].1, map.len()) { + Some(n) => n, + None => continue, + }; + let o = map[next.0][next.1]; + if o == '#' { + continue; + } + map[next.0][next.1] = '#'; + if let None = walk(&map, start_position, cur_icon, &vels) { + blocks.insert(next); + } + map[next.0][next.1] = o; + } + + Ok((count, blocks.len())) +} + +// Returns the number of covered squares if the path ends; else, None. +fn walk( + map: &[Vec], + mut cur_position: Pair, + mut cur_icon: usize, + vels: &[(char, Pair)], +) -> Option<(usize, HashSet<(Pair, usize)>)> { + let mut seen_cells: HashSet = HashSet::new(); + let mut seen_with_direction: HashSet<(Pair, usize)> = HashSet::new(); + loop { + if seen_with_direction.contains(&(cur_position, cur_icon)) { + return None; + } + seen_cells.insert(cur_position); + seen_with_direction.insert((cur_position, cur_icon)); + if let Some(next) = next(cur_position, vels[cur_icon].1, map.len()) { + if map[next.0][next.1] == '#' { + cur_icon = (cur_icon + 1) % vels.len(); + } else { + cur_position = next; + } + } else { + break; + } + } + Some((seen_cells.len(), seen_with_direction)) +} + +#[cfg(test)] +mod tests { + use advent_of_code_2024::input; + + use super::*; + #[test] + fn sample_input() { + let strings: Vec = input!("d6p1.txt"); + let got = solve(strings).unwrap(); + assert_eq!(got, (41, 6)); + } +} diff --git a/src/bin/d6p1.txt b/src/bin/d6p1.txt new file mode 100644 index 0000000..b60e466 --- /dev/null +++ b/src/bin/d6p1.txt @@ -0,0 +1,10 @@ +....#..... +.........# +.......... +..#....... +.......#.. +.......... +.#..^..... +........#. +#......... +......#... \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 859536d..5d8d9c6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,7 +5,7 @@ macro_rules! make_main { use std::io; let lines: Vec = io::stdin().lines().map(|s| s.unwrap()).collect(); let res = solve(lines)?; - println!("{}", res); + println!("{:?}", res); Ok(()) } };