Compare commits
2 commits
a67033d39b
...
8f513f74cc
Author | SHA1 | Date | |
---|---|---|---|
8f513f74cc | |||
6a54618880 |
9 changed files with 148 additions and 48 deletions
|
@ -19,13 +19,11 @@ impl Solution for Day01 {
|
||||||
left.sort();
|
left.sort();
|
||||||
right.sort();
|
right.sort();
|
||||||
|
|
||||||
let sum: i32 = left
|
left.into_iter()
|
||||||
.into_iter()
|
|
||||||
.zip(right)
|
.zip(right)
|
||||||
.map(|(a, b)| (a - b).abs())
|
.map(|(a, b)| (a - b).abs())
|
||||||
.sum();
|
.sum::<i32>()
|
||||||
|
.into()
|
||||||
Answer::Number(sum as u64)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part_b(&self, input: &str) -> Answer {
|
fn part_b(&self, input: &str) -> Answer {
|
||||||
|
@ -37,12 +35,10 @@ impl Solution for Day01 {
|
||||||
|
|
||||||
let counts = right.into_iter().counts();
|
let counts = right.into_iter().counts();
|
||||||
|
|
||||||
let sum = left
|
left.into_iter()
|
||||||
.into_iter()
|
|
||||||
.map(|n| counts.get(&n).unwrap_or(&0) * (n as usize))
|
.map(|n| counts.get(&n).unwrap_or(&0) * (n as usize))
|
||||||
.sum::<usize>();
|
.sum::<usize>()
|
||||||
|
.into()
|
||||||
Answer::Number(sum as u64)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,20 +10,19 @@ impl Solution for Day02 {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part_a(&self, input: &str) -> Answer {
|
fn part_a(&self, input: &str) -> Answer {
|
||||||
let reports = input
|
input
|
||||||
.lines()
|
.lines()
|
||||||
.filter(|l| {
|
.filter(|l| {
|
||||||
let nums = l.split_whitespace().map(|n| n.parse::<i32>().unwrap());
|
let nums = l.split_whitespace().map(|n| n.parse::<i32>().unwrap());
|
||||||
|
|
||||||
is_valid(&nums)
|
is_valid(&nums)
|
||||||
})
|
})
|
||||||
.count();
|
.count()
|
||||||
|
.into()
|
||||||
Answer::Number(reports as u64)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part_b(&self, input: &str) -> Answer {
|
fn part_b(&self, input: &str) -> Answer {
|
||||||
let reports = input
|
input
|
||||||
.lines()
|
.lines()
|
||||||
.filter(|l| {
|
.filter(|l| {
|
||||||
let nums = l.split_whitespace().map(|n| n.parse::<i32>().unwrap());
|
let nums = l.split_whitespace().map(|n| n.parse::<i32>().unwrap());
|
||||||
|
@ -45,9 +44,8 @@ impl Solution for Day02 {
|
||||||
|
|
||||||
valid
|
valid
|
||||||
})
|
})
|
||||||
.count();
|
.count()
|
||||||
|
.into()
|
||||||
Answer::Number(reports as u64)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,13 +13,11 @@ impl Solution for Day03 {
|
||||||
fn part_a(&self, input: &str) -> Answer {
|
fn part_a(&self, input: &str) -> Answer {
|
||||||
let re = Regex::new(r"mul\((\d+),(\d+)\)").unwrap();
|
let re = Regex::new(r"mul\((\d+),(\d+)\)").unwrap();
|
||||||
|
|
||||||
let sum = re
|
re.captures_iter(input)
|
||||||
.captures_iter(input)
|
|
||||||
.map(|c| c.extract())
|
.map(|c| c.extract())
|
||||||
.map(|(_, [a, b])| a.parse::<u64>().unwrap() * b.parse::<u64>().unwrap())
|
.map(|(_, [a, b])| a.parse::<u64>().unwrap() * b.parse::<u64>().unwrap())
|
||||||
.sum::<u64>();
|
.sum::<u64>()
|
||||||
|
.into()
|
||||||
Answer::Number(sum)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part_b(&self, input: &str) -> Answer {
|
fn part_b(&self, input: &str) -> Answer {
|
||||||
|
|
|
@ -17,9 +17,7 @@ impl Solution for Day04 {
|
||||||
.map(xmas_count)
|
.map(xmas_count)
|
||||||
.sum::<usize>();
|
.sum::<usize>();
|
||||||
|
|
||||||
let sum = horizontal + vertical + diag_45 + diag_135;
|
(horizontal + vertical + diag_45 + diag_135).into()
|
||||||
|
|
||||||
Answer::Number(sum as u64)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part_b(&self, input: &str) -> Answer {
|
fn part_b(&self, input: &str) -> Answer {
|
||||||
|
@ -32,7 +30,7 @@ impl Solution for Day04 {
|
||||||
+ cross_mas_count(&input_180)
|
+ cross_mas_count(&input_180)
|
||||||
+ cross_mas_count(&input_270);
|
+ cross_mas_count(&input_270);
|
||||||
|
|
||||||
Answer::Number(sum as u64)
|
sum.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ impl Solution for Day05 {
|
||||||
.into_grouping_map()
|
.into_grouping_map()
|
||||||
.collect::<HashSet<_>>();
|
.collect::<HashSet<_>>();
|
||||||
|
|
||||||
let sum = input
|
input
|
||||||
.lines()
|
.lines()
|
||||||
.map(|l| {
|
.map(|l| {
|
||||||
l.split(",")
|
l.split(",")
|
||||||
|
@ -33,9 +33,8 @@ impl Solution for Day05 {
|
||||||
let middle = (nums.len() - 1) / 2;
|
let middle = (nums.len() - 1) / 2;
|
||||||
nums[middle]
|
nums[middle]
|
||||||
})
|
})
|
||||||
.sum::<u64>();
|
.sum::<u64>()
|
||||||
|
.into()
|
||||||
Answer::Number(sum)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part_b(&self, input: &str) -> Answer {
|
fn part_b(&self, input: &str) -> Answer {
|
||||||
|
@ -48,7 +47,7 @@ impl Solution for Day05 {
|
||||||
.into_grouping_map()
|
.into_grouping_map()
|
||||||
.collect::<HashSet<_>>();
|
.collect::<HashSet<_>>();
|
||||||
|
|
||||||
let sum = input
|
input
|
||||||
.lines()
|
.lines()
|
||||||
.map(|l| {
|
.map(|l| {
|
||||||
l.split(",")
|
l.split(",")
|
||||||
|
@ -83,9 +82,8 @@ impl Solution for Day05 {
|
||||||
let middle = (nums.len() - 1) / 2;
|
let middle = (nums.len() - 1) / 2;
|
||||||
nums[middle]
|
nums[middle]
|
||||||
})
|
})
|
||||||
.sum::<u64>();
|
.sum::<u64>()
|
||||||
|
.into()
|
||||||
Answer::Number(sum)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ impl Solution for Day06 {
|
||||||
direction: Direction::Up,
|
direction: Direction::Up,
|
||||||
};
|
};
|
||||||
|
|
||||||
Answer::Number(get_positions(&grid, guard).len() as u64)
|
get_positions(&grid, guard).len().into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part_b(&self, input: &str) -> Answer {
|
fn part_b(&self, input: &str) -> Answer {
|
||||||
|
@ -48,7 +48,7 @@ impl Solution for Day06 {
|
||||||
direction: Direction::Up,
|
direction: Direction::Up,
|
||||||
};
|
};
|
||||||
|
|
||||||
let count = get_positions(&grid, guard)
|
get_positions(&grid, guard)
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|&&coords| {
|
.filter(|&&coords| {
|
||||||
let tmp_guard = Guard {
|
let tmp_guard = Guard {
|
||||||
|
@ -58,9 +58,8 @@ impl Solution for Day06 {
|
||||||
|
|
||||||
is_infinite_loop(&grid, tmp_guard, coords)
|
is_infinite_loop(&grid, tmp_guard, coords)
|
||||||
})
|
})
|
||||||
.count();
|
.count()
|
||||||
|
.into()
|
||||||
Answer::Number(count as u64)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ impl Solution for Day07 {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part_a(&self, input: &str) -> Answer {
|
fn part_a(&self, input: &str) -> Answer {
|
||||||
let sum = input
|
input
|
||||||
.lines()
|
.lines()
|
||||||
.map(|l| l.split_once(": ").unwrap())
|
.map(|l| l.split_once(": ").unwrap())
|
||||||
.map(|(a, b)| {
|
.map(|(a, b)| {
|
||||||
|
@ -38,13 +38,12 @@ impl Solution for Day07 {
|
||||||
|
|
||||||
None
|
None
|
||||||
})
|
})
|
||||||
.sum::<u64>();
|
.sum::<u64>()
|
||||||
|
.into()
|
||||||
Answer::Number(sum)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part_b(&self, input: &str) -> Answer {
|
fn part_b(&self, input: &str) -> Answer {
|
||||||
let sum = input
|
input
|
||||||
.lines()
|
.lines()
|
||||||
.map(|l| l.split_once(": ").unwrap())
|
.map(|l| l.split_once(": ").unwrap())
|
||||||
.map(|(a, b)| {
|
.map(|(a, b)| {
|
||||||
|
@ -74,9 +73,8 @@ impl Solution for Day07 {
|
||||||
|
|
||||||
None
|
None
|
||||||
})
|
})
|
||||||
.sum::<u64>();
|
.sum::<u64>()
|
||||||
|
.into()
|
||||||
Answer::Number(sum)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
113
src/solutions/day_08.rs
Normal file
113
src/solutions/day_08.rs
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
|
use crate::common::{Answer, Solution};
|
||||||
|
|
||||||
|
pub struct Day08;
|
||||||
|
|
||||||
|
impl Solution for Day08 {
|
||||||
|
fn name(&self) -> &'static str {
|
||||||
|
"Resonant Collinearity"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part_a(&self, input: &str) -> Answer {
|
||||||
|
let bound_x = 0..(input.lines().count() as i64);
|
||||||
|
let bound_y = 0..(input.lines().next().unwrap().len() as i64);
|
||||||
|
|
||||||
|
let antennas = input
|
||||||
|
.lines()
|
||||||
|
.enumerate()
|
||||||
|
.flat_map(|(x, l)| {
|
||||||
|
l.chars()
|
||||||
|
.enumerate()
|
||||||
|
.filter(|(_, c)| *c != '.')
|
||||||
|
.map(move |(y, c)| (c, (x as i64, y as i64)))
|
||||||
|
})
|
||||||
|
.into_group_map();
|
||||||
|
|
||||||
|
antennas
|
||||||
|
.iter()
|
||||||
|
.flat_map(|(_, pos)| pos.iter().tuple_combinations::<(_, _)>())
|
||||||
|
.flat_map(|((x1, y1), (x2, y2))| {
|
||||||
|
let diff_x = x1 - x2;
|
||||||
|
let diff_y = y1 - y2;
|
||||||
|
|
||||||
|
[(x1 + diff_x, y1 + diff_y), (x2 - diff_x, y2 - diff_y)]
|
||||||
|
})
|
||||||
|
.filter(|(x, y)| bound_x.contains(x) && bound_y.contains(y))
|
||||||
|
.unique()
|
||||||
|
.count()
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part_b(&self, input: &str) -> Answer {
|
||||||
|
let bound_x = 0..(input.lines().count() as i64);
|
||||||
|
let bound_y = 0..(input.lines().next().unwrap().len() as i64);
|
||||||
|
|
||||||
|
let antennas = input
|
||||||
|
.lines()
|
||||||
|
.enumerate()
|
||||||
|
.flat_map(|(x, l)| {
|
||||||
|
l.chars()
|
||||||
|
.enumerate()
|
||||||
|
.filter(|(_, c)| *c != '.')
|
||||||
|
.map(move |(y, c)| (c, (x as i64, y as i64)))
|
||||||
|
})
|
||||||
|
.into_group_map();
|
||||||
|
|
||||||
|
antennas
|
||||||
|
.iter()
|
||||||
|
.flat_map(|(_, pos)| pos.iter().tuple_combinations::<(_, _)>())
|
||||||
|
.flat_map(|((x1, y1), (x2, y2))| {
|
||||||
|
let diff_x = x1 - x2;
|
||||||
|
let diff_y = y1 - y2;
|
||||||
|
|
||||||
|
// we go from 0 because antennas also count as antinodes here
|
||||||
|
let before = (0..)
|
||||||
|
.map(move |n| (x1 + diff_x * n, y1 + diff_y * n))
|
||||||
|
.take_while(|(x, y)| bound_x.contains(x) && bound_y.contains(y));
|
||||||
|
|
||||||
|
let after = (0..)
|
||||||
|
.map(move |n| (x2 - diff_x * n, y2 - diff_y * n))
|
||||||
|
.take_while(|(x, y)| bound_x.contains(x) && bound_y.contains(y));
|
||||||
|
|
||||||
|
before.chain(after)
|
||||||
|
})
|
||||||
|
.filter(|(x, y)| bound_x.contains(x) && bound_y.contains(y))
|
||||||
|
.unique()
|
||||||
|
.count()
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::Day08;
|
||||||
|
use crate::common::Solution;
|
||||||
|
|
||||||
|
use indoc::indoc;
|
||||||
|
|
||||||
|
const INPUT: &str = indoc! {"
|
||||||
|
............
|
||||||
|
........0...
|
||||||
|
.....0......
|
||||||
|
.......0....
|
||||||
|
....0.......
|
||||||
|
......A.....
|
||||||
|
............
|
||||||
|
............
|
||||||
|
........A...
|
||||||
|
.........A..
|
||||||
|
............
|
||||||
|
............
|
||||||
|
"};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part_a() {
|
||||||
|
assert_eq!(Day08.part_a(INPUT), 14.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part_b() {
|
||||||
|
assert_eq!(Day08.part_b(INPUT), 34.into());
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ mod day_04;
|
||||||
mod day_05;
|
mod day_05;
|
||||||
mod day_06;
|
mod day_06;
|
||||||
mod day_07;
|
mod day_07;
|
||||||
|
mod day_08;
|
||||||
|
|
||||||
pub const SOLUTIONS: &[&dyn Solution] = &[
|
pub const SOLUTIONS: &[&dyn Solution] = &[
|
||||||
&day_01::Day01,
|
&day_01::Day01,
|
||||||
|
@ -16,4 +17,5 @@ pub const SOLUTIONS: &[&dyn Solution] = &[
|
||||||
&day_05::Day05,
|
&day_05::Day05,
|
||||||
&day_06::Day06,
|
&day_06::Day06,
|
||||||
&day_07::Day07,
|
&day_07::Day07,
|
||||||
|
&day_08::Day08,
|
||||||
];
|
];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue