add: day 5, day 6

This commit is contained in:
Charles
2024-12-05 22:50:40 -08:00
parent 23776b4926
commit de3f90b516
6 changed files with 252 additions and 1 deletions
+64
View File
@@ -0,0 +1,64 @@
use std::collections::{HashMap, HashSet};
use advent_of_code_2024::{make_main, SResult};
make_main!();
fn solve(lines: Vec<String>) -> SResult<usize> {
let mut page_order: HashMap<usize, HashSet<usize>> = 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::<usize>().unwrap(), b.parse::<usize>().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<usize> = line
.split(",")
.map(|v| v.parse::<usize>().unwrap())
.collect();
let mut seen: HashSet<usize> = 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<String> = input!("d5p1.txt");
let got = solve(strings).unwrap();
assert_eq!(got, 143);
}
}
+28
View File
@@ -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
+61
View File
@@ -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<String>) -> SResult<(usize, usize)> {
let mut order: HashMap<usize, HashSet<usize>> = 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::<usize>().unwrap(), b.parse::<usize>().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<usize> = line
.split(",")
.map(|v| v.parse::<usize>().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<String> = input!("d5p1.txt");
let got = solve(strings).unwrap();
assert_eq!(got, (143, 123));
}
}
+88
View File
@@ -0,0 +1,88 @@
use std::collections::HashSet;
use advent_of_code_2024::{make_main, next, Pair, SResult};
make_main!();
fn solve(lines: Vec<String>) -> 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::<Vec<char>>());
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<Pair> = 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<char>],
mut cur_position: Pair,
mut cur_icon: usize,
vels: &[(char, Pair<i64>)],
) -> Option<(usize, HashSet<(Pair, usize)>)> {
let mut seen_cells: HashSet<Pair> = 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<String> = input!("d6p1.txt");
let got = solve(strings).unwrap();
assert_eq!(got, (41, 6));
}
}
+10
View File
@@ -0,0 +1,10 @@
....#.....
.........#
..........
..#.......
.......#..
..........
.#..^.....
........#.
#.........
......#...
+1 -1
View File
@@ -5,7 +5,7 @@ macro_rules! make_main {
use std::io;
let lines: Vec<String> = io::stdin().lines().map(|s| s.unwrap()).collect();
let res = solve(lines)?;
println!("{}", res);
println!("{:?}", res);
Ok(())
}
};