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;
|
||||
let lines: Vec<String> = io::stdin().lines().map(|s| s.unwrap()).collect();
|
||||
let res = solve(lines)?;
|
||||
println!("{}", res);
|
||||
println!("{:?}", res);
|
||||
Ok(())
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user