add: day 5, day 6
This commit is contained in:
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
....#.....
|
||||||
|
.........#
|
||||||
|
..........
|
||||||
|
..#.......
|
||||||
|
.......#..
|
||||||
|
..........
|
||||||
|
.#..^.....
|
||||||
|
........#.
|
||||||
|
#.........
|
||||||
|
......#...
|
||||||
+1
-1
@@ -5,7 +5,7 @@ macro_rules! make_main {
|
|||||||
use std::io;
|
use std::io;
|
||||||
let lines: Vec<String> = io::stdin().lines().map(|s| s.unwrap()).collect();
|
let lines: Vec<String> = io::stdin().lines().map(|s| s.unwrap()).collect();
|
||||||
let res = solve(lines)?;
|
let res = solve(lines)?;
|
||||||
println!("{}", res);
|
println!("{:?}", res);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user