refactor: use generated boilerplate from lib
Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
parent
f53be47327
commit
cb82cbb433
8 changed files with 204 additions and 399 deletions
|
@ -1,8 +1,4 @@
|
|||
use aoc_2022::file_to_lines;
|
||||
|
||||
use color_eyre::eyre::Result;
|
||||
use tracing::*;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
use aoc_2022::*;
|
||||
|
||||
type Input = Vec<i32>;
|
||||
type Output = i32;
|
||||
|
@ -24,53 +20,26 @@ fn n_biggest(n: usize, input: &Input) -> Output {
|
|||
calories.iter().rev().take(n).sum()
|
||||
}
|
||||
|
||||
fn part_1(input: &Input) -> Output {
|
||||
n_biggest(1_usize, input)
|
||||
}
|
||||
struct Day01;
|
||||
impl Solution<Input, Output> for Day01 {
|
||||
fn parse_input<P: AsRef<Path>>(pathname: P) -> Input {
|
||||
file_to_lines(pathname)
|
||||
.iter()
|
||||
.map(|s| if s.is_empty() { -1 } else { s.parse().unwrap() })
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn part_2(input: &Input) -> Output {
|
||||
n_biggest(3_usize, input)
|
||||
}
|
||||
fn part_1(input: &Input) -> Output {
|
||||
n_biggest(1_usize, input)
|
||||
}
|
||||
|
||||
fn parse_input(pathname: &str) -> Input {
|
||||
file_to_lines(pathname)
|
||||
.iter()
|
||||
.map(|s| if s.is_empty() { -1 } else { s.parse().unwrap() })
|
||||
.collect()
|
||||
fn part_2(input: &Input) -> Output {
|
||||
n_biggest(3_usize, input)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
tracing_subscriber::fmt()
|
||||
.with_env_filter(EnvFilter::from_default_env())
|
||||
.with_target(false)
|
||||
.with_file(true)
|
||||
.with_line_number(true)
|
||||
.without_time()
|
||||
.compact()
|
||||
.init();
|
||||
color_eyre::install()?;
|
||||
|
||||
let input = parse_input("inputs/day01.txt");
|
||||
|
||||
info!("Part 1: {}", part_1(&input));
|
||||
info!("Part 2: {}", part_2(&input));
|
||||
|
||||
Ok(())
|
||||
Day01::main()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod day_01 {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part_1() {
|
||||
let sample = parse_input("samples/day01.txt");
|
||||
assert_eq!(part_1(&sample), 24000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_part_2() {
|
||||
let sample = parse_input("samples/day01.txt");
|
||||
assert_eq!(part_2(&sample), 45000);
|
||||
}
|
||||
}
|
||||
test_sample!(day_01, Day01, 24000, 45000);
|
||||
|
|
|
@ -2,10 +2,14 @@ use std::str::FromStr;
|
|||
|
||||
use aoc_2022::*;
|
||||
|
||||
use color_eyre::{eyre::{eyre, Result}, Report};
|
||||
use color_eyre::{
|
||||
eyre::eyre,
|
||||
Report,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use tracing::*;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
type Input = Vec<Round>;
|
||||
type Output = i32;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum Shape {
|
||||
|
@ -133,53 +137,23 @@ impl Round {
|
|||
}
|
||||
}
|
||||
|
||||
type Input = Vec<Round>;
|
||||
type Output = i32;
|
||||
struct Day02;
|
||||
impl Solution<Input, Output> for Day02 {
|
||||
fn parse_input<P: AsRef<Path>>(pathname: P) -> Input {
|
||||
file_to_structs(pathname)
|
||||
}
|
||||
|
||||
fn part_1(input: &Input) -> Output {
|
||||
input.iter().map(Round::score).sum()
|
||||
}
|
||||
fn part_1(input: &Input) -> Output {
|
||||
input.iter().map(Round::score).sum()
|
||||
}
|
||||
|
||||
fn part_2(input: &Input) -> Output {
|
||||
input.iter().map(Round::expected_score).sum()
|
||||
}
|
||||
|
||||
fn parse_input(pathname: &str) -> Input {
|
||||
file_to_structs(pathname)
|
||||
fn part_2(input: &Input) -> Output {
|
||||
input.iter().map(Round::expected_score).sum()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
tracing_subscriber::fmt()
|
||||
.with_env_filter(EnvFilter::from_default_env())
|
||||
.with_target(false)
|
||||
.with_file(true)
|
||||
.with_line_number(true)
|
||||
.without_time()
|
||||
.compact()
|
||||
.init();
|
||||
color_eyre::install()?;
|
||||
|
||||
let input = parse_input("inputs/day02.txt");
|
||||
|
||||
info!("Part 1: {}", part_1(&input));
|
||||
info!("Part 2: {}", part_2(&input));
|
||||
|
||||
Ok(())
|
||||
Day02::main()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod day_02 {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part_1() {
|
||||
let sample = parse_input("samples/day02.txt");
|
||||
assert_eq!(part_1(&sample), 15);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_part_2() {
|
||||
let sample = parse_input("samples/day02.txt");
|
||||
assert_eq!(part_2(&sample), 12);
|
||||
}
|
||||
}
|
||||
test_sample!(day_02, Day02, 15, 12);
|
||||
|
|
|
@ -3,15 +3,13 @@ use std::str::FromStr;
|
|||
|
||||
use aoc_2022::*;
|
||||
|
||||
use color_eyre::eyre::{Report, Result};
|
||||
use tracing::*;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
struct Backpack(HashSet<i32>, HashSet<i32>);
|
||||
use color_eyre::eyre::Report;
|
||||
|
||||
type Input = Vec<Backpack>;
|
||||
type Output = i32;
|
||||
|
||||
struct Backpack(HashSet<i32>, HashSet<i32>);
|
||||
|
||||
impl FromStr for Backpack {
|
||||
type Err = Report;
|
||||
|
||||
|
@ -49,13 +47,6 @@ impl Backpack {
|
|||
}
|
||||
}
|
||||
|
||||
fn part_1(input: &Input) -> Output {
|
||||
input
|
||||
.iter()
|
||||
.map(|b| b.common_items().iter().sum::<i32>())
|
||||
.sum()
|
||||
}
|
||||
|
||||
fn common_items(backpacks: &[Backpack]) -> HashSet<i32> {
|
||||
backpacks
|
||||
.iter()
|
||||
|
@ -65,49 +56,29 @@ fn common_items(backpacks: &[Backpack]) -> HashSet<i32> {
|
|||
})
|
||||
}
|
||||
|
||||
fn part_2(input: &Input) -> Output {
|
||||
input
|
||||
.chunks(3)
|
||||
.map(|backpacks| common_items(backpacks).iter().sum::<i32>())
|
||||
.sum()
|
||||
}
|
||||
struct Day03;
|
||||
impl Solution<Input, Output> for Day03 {
|
||||
fn parse_input<P: AsRef<Path>>(pathname: P) -> Input {
|
||||
file_to_structs(pathname)
|
||||
}
|
||||
|
||||
fn parse_input(pathname: &str) -> Input {
|
||||
file_to_structs(pathname)
|
||||
fn part_1(input: &Input) -> Output {
|
||||
input
|
||||
.iter()
|
||||
.map(|b| b.common_items().iter().sum::<i32>())
|
||||
.sum()
|
||||
}
|
||||
|
||||
fn part_2(input: &Input) -> Output {
|
||||
input
|
||||
.chunks(3)
|
||||
.map(|backpacks| common_items(backpacks).iter().sum::<i32>())
|
||||
.sum()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
tracing_subscriber::fmt()
|
||||
.with_env_filter(EnvFilter::from_default_env())
|
||||
.with_target(false)
|
||||
.with_file(true)
|
||||
.with_line_number(true)
|
||||
.without_time()
|
||||
.compact()
|
||||
.init();
|
||||
color_eyre::install()?;
|
||||
|
||||
let input = parse_input("inputs/day03.txt");
|
||||
|
||||
info!("Part 1: {}", part_1(&input));
|
||||
info!("Part 2: {}", part_2(&input));
|
||||
|
||||
Ok(())
|
||||
Day03::main()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod day_03 {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part_1() {
|
||||
let sample = parse_input("samples/day03.txt");
|
||||
assert_eq!(part_1(&sample), 157);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_part_2() {
|
||||
let sample = parse_input("samples/day03.txt");
|
||||
assert_eq!(part_2(&sample), 70);
|
||||
}
|
||||
}
|
||||
test_sample!(day_03, Day03, 157, 70);
|
||||
|
|
|
@ -3,9 +3,10 @@ use std::str::FromStr;
|
|||
|
||||
use aoc_2022::*;
|
||||
|
||||
use color_eyre::eyre::{Report, Result};
|
||||
use tracing::*;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
use color_eyre::eyre::Report;
|
||||
|
||||
type Input = Vec<Assignment>;
|
||||
type Output = usize;
|
||||
|
||||
struct Assignment(RangeInclusive<i32>, RangeInclusive<i32>);
|
||||
|
||||
|
@ -48,53 +49,23 @@ impl Assignment {
|
|||
}
|
||||
}
|
||||
|
||||
type Input = Vec<Assignment>;
|
||||
type Output = usize;
|
||||
struct Day04;
|
||||
impl Solution<Input, Output> for Day04 {
|
||||
fn parse_input<P: AsRef<Path>>(pathname: P) -> Input {
|
||||
file_to_structs(pathname)
|
||||
}
|
||||
|
||||
fn part_1(input: &Input) -> Output {
|
||||
input.iter().filter(|a| a.fully_overlap()).count()
|
||||
}
|
||||
fn part_1(input: &Input) -> Output {
|
||||
input.iter().filter(|a| a.fully_overlap()).count()
|
||||
}
|
||||
|
||||
fn part_2(input: &Input) -> Output {
|
||||
input.iter().filter(|a| a.overlap()).count()
|
||||
}
|
||||
|
||||
fn parse_input(pathname: &str) -> Input {
|
||||
file_to_structs(pathname)
|
||||
fn part_2(input: &Input) -> Output {
|
||||
input.iter().filter(|a| a.overlap()).count()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
tracing_subscriber::fmt()
|
||||
.with_env_filter(EnvFilter::from_default_env())
|
||||
.with_target(false)
|
||||
.with_file(true)
|
||||
.with_line_number(true)
|
||||
.without_time()
|
||||
.compact()
|
||||
.init();
|
||||
color_eyre::install()?;
|
||||
|
||||
let input = parse_input("inputs/day04.txt");
|
||||
|
||||
info!("Part 1: {}", part_1(&input));
|
||||
info!("Part 2: {}", part_2(&input));
|
||||
|
||||
Ok(())
|
||||
Day04::main()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod day_04 {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part_1() {
|
||||
let sample = parse_input("samples/day04.txt");
|
||||
assert_eq!(part_1(&sample), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_part_2() {
|
||||
let sample = parse_input("samples/day04.txt");
|
||||
assert_eq!(part_2(&sample), 4);
|
||||
}
|
||||
}
|
||||
test_sample!(day_04, Day04, 2, 4);
|
||||
|
|
|
@ -3,10 +3,11 @@ use std::str::FromStr;
|
|||
|
||||
use aoc_2022::*;
|
||||
|
||||
use color_eyre::eyre::{Report, Result};
|
||||
use color_eyre::eyre::Report;
|
||||
use itertools::Itertools;
|
||||
use tracing::*;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
type Input = Ship;
|
||||
type Output = String;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Move {
|
||||
|
@ -65,9 +66,6 @@ impl FromStr for Ship {
|
|||
}
|
||||
}
|
||||
|
||||
type Input = Ship;
|
||||
type Output = String;
|
||||
|
||||
fn stacks_to_string(stacks: &[Vec<char>]) -> String {
|
||||
stacks.iter().fold(String::new(), |acc, stack| {
|
||||
if let Some(c) = stack.last() {
|
||||
|
@ -96,50 +94,23 @@ fn move_crates(input: &Input, one_by_one: bool) -> Output {
|
|||
stacks_to_string(&stacks)
|
||||
}
|
||||
|
||||
fn part_1(input: &Input) -> Output {
|
||||
move_crates(input, true)
|
||||
}
|
||||
struct Day05;
|
||||
impl Solution<Input, Output> for Day05 {
|
||||
fn parse_input<P: AsRef<Path>>(pathname: P) -> Input {
|
||||
file_to_string(pathname).parse().unwrap()
|
||||
}
|
||||
|
||||
fn part_2(input: &Input) -> Output {
|
||||
move_crates(input, false)
|
||||
}
|
||||
fn part_1(input: &Input) -> Output {
|
||||
move_crates(input, true)
|
||||
}
|
||||
|
||||
fn parse_input(pathname: &str) -> Input {
|
||||
file_to_string(pathname).parse::<Input>().unwrap()
|
||||
fn part_2(input: &Input) -> Output {
|
||||
move_crates(input, false)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
tracing_subscriber::fmt()
|
||||
.with_env_filter(EnvFilter::from_default_env())
|
||||
.with_target(false)
|
||||
.with_file(true)
|
||||
.with_line_number(true)
|
||||
.without_time()
|
||||
.compact()
|
||||
.init();
|
||||
color_eyre::install()?;
|
||||
|
||||
let input = parse_input("inputs/day05.txt");
|
||||
|
||||
info!("Part 1: {}", part_1(&input));
|
||||
info!("Part 2: {}", part_2(&input));
|
||||
|
||||
Ok(())
|
||||
Day05::main()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod day_05 {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part_1() {
|
||||
let sample = parse_input("samples/day05.txt");
|
||||
assert_eq!(part_1(&sample), "CMZ".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_part_2() {
|
||||
let sample = parse_input("samples/day05.txt");
|
||||
assert_eq!(part_2(&sample), "MCD".to_string());
|
||||
}
|
||||
}
|
||||
test_sample!(day_05, Day05, "CMZ".to_string(), "MCD".to_string());
|
||||
|
|
|
@ -2,10 +2,7 @@ use std::collections::HashSet;
|
|||
|
||||
use aoc_2022::*;
|
||||
|
||||
use color_eyre::eyre::Result;
|
||||
use itertools::Itertools;
|
||||
use tracing::*;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
type Input = String;
|
||||
type Output = usize;
|
||||
|
@ -23,90 +20,92 @@ fn unique_marker_index(buffer: &Input, n: usize) -> Output {
|
|||
+ n
|
||||
}
|
||||
|
||||
fn part_1(input: &Input) -> Output {
|
||||
unique_marker_index(input, 4)
|
||||
}
|
||||
struct Day06;
|
||||
impl Solution<Input, Output> for Day06 {
|
||||
fn parse_input<P: AsRef<Path>>(pathname: P) -> Input {
|
||||
file_to_string(pathname)
|
||||
}
|
||||
|
||||
fn part_2(input: &Input) -> Output {
|
||||
unique_marker_index(input, 14)
|
||||
}
|
||||
fn part_1(input: &Input) -> Output {
|
||||
unique_marker_index(input, 4)
|
||||
}
|
||||
|
||||
fn parse_input(pathname: &str) -> Input {
|
||||
file_to_string(pathname)
|
||||
fn part_2(input: &Input) -> Output {
|
||||
unique_marker_index(input, 14)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
tracing_subscriber::fmt()
|
||||
.with_env_filter(EnvFilter::from_default_env())
|
||||
.with_target(false)
|
||||
.with_file(true)
|
||||
.with_line_number(true)
|
||||
.without_time()
|
||||
.compact()
|
||||
.init();
|
||||
color_eyre::install()?;
|
||||
|
||||
let input = parse_input("inputs/day06.txt");
|
||||
|
||||
info!("Part 1: {}", part_1(&input));
|
||||
info!("Part 2: {}", part_2(&input));
|
||||
|
||||
Ok(())
|
||||
Day06::main()
|
||||
}
|
||||
|
||||
test_sample!(day_06, Day06, 7, 19);
|
||||
|
||||
#[cfg(test)]
|
||||
mod day_06 {
|
||||
mod day_06_extended {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part_1() {
|
||||
let sample = parse_input("samples/day06.txt");
|
||||
assert_eq!(part_1(&sample), 7);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_part_1_example_1() {
|
||||
assert_eq!(part_1(&"bvwbjplbgvbhsrlpgdmjqwftvncz".to_string()), 5);
|
||||
assert_eq!(
|
||||
Day06::part_1(&"bvwbjplbgvbhsrlpgdmjqwftvncz".to_string()),
|
||||
5
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_part_1_example_2() {
|
||||
assert_eq!(part_1(&"nppdvjthqldpwncqszvftbrmjlhg".to_string()), 6);
|
||||
assert_eq!(
|
||||
Day06::part_1(&"nppdvjthqldpwncqszvftbrmjlhg".to_string()),
|
||||
6
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_part_1_example_3() {
|
||||
assert_eq!(part_1(&"nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg".to_string()), 10);
|
||||
assert_eq!(
|
||||
Day06::part_1(&"nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg".to_string()),
|
||||
10
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_part_1_example_4() {
|
||||
assert_eq!(part_1(&"zcfzfwzzqfrljwzlrfnpqdbhtmscgvjw".to_string()), 11);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_part_2() {
|
||||
let sample = parse_input("samples/day06.txt");
|
||||
assert_eq!(part_2(&sample), 19);
|
||||
assert_eq!(
|
||||
Day06::part_1(&"zcfzfwzzqfrljwzlrfnpqdbhtmscgvjw".to_string()),
|
||||
11
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_part_2_example_1() {
|
||||
assert_eq!(part_2(&"bvwbjplbgvbhsrlpgdmjqwftvncz".to_string()), 23);
|
||||
assert_eq!(
|
||||
Day06::part_2(&"bvwbjplbgvbhsrlpgdmjqwftvncz".to_string()),
|
||||
23
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_part_2_example_2() {
|
||||
assert_eq!(part_2(&"nppdvjthqldpwncqszvftbrmjlhg".to_string()), 23);
|
||||
assert_eq!(
|
||||
Day06::part_2(&"nppdvjthqldpwncqszvftbrmjlhg".to_string()),
|
||||
23
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_part_2_example_3() {
|
||||
assert_eq!(part_2(&"nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg".to_string()), 29);
|
||||
assert_eq!(
|
||||
Day06::part_2(&"nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg".to_string()),
|
||||
29
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_part_2_example_4() {
|
||||
assert_eq!(part_2(&"zcfzfwzzqfrljwzlrfnpqdbhtmscgvjw".to_string()), 26);
|
||||
assert_eq!(
|
||||
Day06::part_2(&"zcfzfwzzqfrljwzlrfnpqdbhtmscgvjw".to_string()),
|
||||
26
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,10 +2,11 @@ use std::{cell::RefCell, cmp::min, collections::BTreeMap, rc::Rc, str::FromStr};
|
|||
|
||||
use aoc_2022::*;
|
||||
|
||||
use color_eyre::{eyre::Result, Report};
|
||||
use color_eyre::Report;
|
||||
use itertools::Itertools;
|
||||
use tracing::*;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
type Input = Filesystem;
|
||||
type Output = usize;
|
||||
|
||||
type FileHandle = Rc<RefCell<AocFile>>;
|
||||
|
||||
|
@ -47,15 +48,15 @@ impl AocFile {
|
|||
panic!("cannot cd in file")
|
||||
}
|
||||
|
||||
fn size_under_100000(&self) -> (bool, usize, usize) {
|
||||
fn size_under(&self, max_size: usize) -> (bool, usize, usize) {
|
||||
match self {
|
||||
AocFile::File(s) => (false, 0, *s),
|
||||
AocFile::Directory(files) => {
|
||||
let (running_total, size) = files
|
||||
.values()
|
||||
.map(|f| f.borrow().size_under_100000())
|
||||
.map(|f| f.borrow().size_under(max_size))
|
||||
.fold((0_usize, 0_usize), |(mut running, size), (dir, r, s)| {
|
||||
if dir && s <= 100000 {
|
||||
if dir && s <= max_size {
|
||||
running += s;
|
||||
}
|
||||
|
||||
|
@ -112,6 +113,8 @@ impl Filesystem {
|
|||
}
|
||||
}
|
||||
|
||||
// [MARK] Helper functions for ‹FromStr› trait
|
||||
|
||||
fn cd(&mut self, dir: &str) {
|
||||
match dir {
|
||||
".." => {
|
||||
|
@ -143,15 +146,28 @@ impl Filesystem {
|
|||
|
||||
for file in command.lines().skip(1) {
|
||||
let parts = file.split_ascii_whitespace().collect_vec();
|
||||
if parts[0] == "dir" {
|
||||
/* no-op */
|
||||
} else {
|
||||
if parts[0] != "dir" {
|
||||
let name = parts[1];
|
||||
let size: usize = parts[0].parse().unwrap();
|
||||
self.touch(name, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// [MARK] Helper functions for ‹FromStr› trait
|
||||
|
||||
fn size_under(&self, max_size: usize) -> usize {
|
||||
self.root.borrow().size_under(max_size).1
|
||||
}
|
||||
|
||||
fn purge(&self, total: usize, needed: usize) -> usize {
|
||||
let used = self.root.borrow().size_under(0).2;
|
||||
|
||||
// to_be_freed >= needed - (total - used)
|
||||
let to_be_freed = needed - (total - used);
|
||||
|
||||
self.root.borrow().smallest_bigger(to_be_freed).1
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Filesystem {
|
||||
|
@ -168,59 +184,23 @@ impl FromStr for Filesystem {
|
|||
}
|
||||
}
|
||||
|
||||
type Input = Filesystem;
|
||||
type Output = usize;
|
||||
struct Day07;
|
||||
impl Solution<Input, Output> for Day07 {
|
||||
fn parse_input<P: AsRef<Path>>(pathname: P) -> Input {
|
||||
file_to_string(pathname).parse().unwrap()
|
||||
}
|
||||
|
||||
fn part_1(input: &Input) -> Output {
|
||||
input.root.borrow().size_under_100000().1
|
||||
}
|
||||
fn part_1(input: &Input) -> Output {
|
||||
input.size_under(100000)
|
||||
}
|
||||
|
||||
fn part_2(input: &Input) -> Output {
|
||||
let (total, needed) = (70000000, 30000000);
|
||||
let used = input.root.borrow().size_under_100000().2;
|
||||
|
||||
// to_be_freed >= needed - (total - used)
|
||||
let to_be_freed = needed - (total - used);
|
||||
|
||||
input.root.borrow().smallest_bigger(to_be_freed).1
|
||||
}
|
||||
|
||||
fn parse_input(pathname: &str) -> Input {
|
||||
file_to_string(pathname).parse().unwrap()
|
||||
fn part_2(input: &Input) -> Output {
|
||||
input.purge(70000000, 30000000)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
tracing_subscriber::fmt()
|
||||
.with_env_filter(EnvFilter::from_default_env())
|
||||
.with_target(false)
|
||||
.with_file(true)
|
||||
.with_line_number(true)
|
||||
.without_time()
|
||||
.compact()
|
||||
.init();
|
||||
color_eyre::install()?;
|
||||
|
||||
let input = parse_input("inputs/day07.txt");
|
||||
|
||||
info!("Part 1: {}", part_1(&input));
|
||||
info!("Part 2: {}", part_2(&input));
|
||||
|
||||
Ok(())
|
||||
Day07::main()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod day_07 {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part_1() {
|
||||
let sample = parse_input("samples/day07.txt");
|
||||
assert_eq!(part_1(&sample), 95437);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_part_2() {
|
||||
let sample = parse_input("samples/day07.txt");
|
||||
assert_eq!(part_2(&sample), 24933642);
|
||||
}
|
||||
}
|
||||
test_sample!(day_07, Day07, 95437, 24933642);
|
||||
|
|
|
@ -2,10 +2,7 @@ use std::{cmp::max, collections::BTreeSet};
|
|||
|
||||
use aoc_2022::*;
|
||||
|
||||
use color_eyre::eyre::Result;
|
||||
use itertools::Itertools;
|
||||
use tracing::*;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
type Input = Vec<Vec<i8>>;
|
||||
type Output = usize;
|
||||
|
@ -51,15 +48,6 @@ fn count_in_columns(trees: &Input, counted: &mut Visited) {
|
|||
count_in(trees, counted, true)
|
||||
}
|
||||
|
||||
fn part_1(input: &Input) -> Output {
|
||||
let mut counted = Visited::new();
|
||||
|
||||
count_in_rows(input, &mut counted);
|
||||
count_in_columns(input, &mut counted);
|
||||
|
||||
counted.len()
|
||||
}
|
||||
|
||||
fn count_visible(trees: &Input, position: SignedPosition, diff: SignedPosition) -> usize {
|
||||
let max_height = *index(trees, &position);
|
||||
let mut visible = 0;
|
||||
|
@ -91,17 +79,10 @@ fn compute_scenic_score(trees: &Input, x: isize, y: isize) -> usize {
|
|||
.product()
|
||||
}
|
||||
|
||||
fn part_2(input: &Input) -> Output {
|
||||
(0..input.len())
|
||||
.flat_map(|y| {
|
||||
(0..input[y].len()).map(move |x| compute_scenic_score(input, x as isize, y as isize))
|
||||
})
|
||||
.max()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn parse_input(pathname: &str) -> Input {
|
||||
file_to_string(pathname)
|
||||
struct Day08;
|
||||
impl Solution<Input, Output> for Day08 {
|
||||
fn parse_input<P: AsRef<Path>>(pathname: P) -> Input {
|
||||
file_to_string(pathname)
|
||||
.lines()
|
||||
.map(|line| {
|
||||
line.chars()
|
||||
|
@ -109,40 +90,29 @@ fn parse_input(pathname: &str) -> Input {
|
|||
.collect_vec()
|
||||
})
|
||||
.collect_vec()
|
||||
}
|
||||
|
||||
fn part_1(input: &Input) -> Output {
|
||||
let mut counted = Visited::new();
|
||||
|
||||
count_in_rows(input, &mut counted);
|
||||
count_in_columns(input, &mut counted);
|
||||
|
||||
counted.len()
|
||||
}
|
||||
|
||||
fn part_2(input: &Input) -> Output {
|
||||
(0..input.len())
|
||||
.flat_map(|y| {
|
||||
(0..input[y].len()).map(move |x| compute_scenic_score(input, x as isize, y as isize))
|
||||
})
|
||||
.max()
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
tracing_subscriber::fmt()
|
||||
.with_env_filter(EnvFilter::from_default_env())
|
||||
.with_target(false)
|
||||
.with_file(true)
|
||||
.with_line_number(true)
|
||||
.without_time()
|
||||
.compact()
|
||||
.init();
|
||||
color_eyre::install()?;
|
||||
|
||||
let input = parse_input("inputs/day08.txt");
|
||||
|
||||
info!("Part 1: {}", part_1(&input));
|
||||
info!("Part 2: {}", part_2(&input));
|
||||
|
||||
Ok(())
|
||||
Day08::main()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod day_08 {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part_1() {
|
||||
let sample = parse_input("samples/day08.txt");
|
||||
assert_eq!(part_1(&sample), 21);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_part_2() {
|
||||
let sample = parse_input("samples/day08.txt");
|
||||
assert_eq!(part_2(&sample), 8);
|
||||
}
|
||||
}
|
||||
test_sample!(day_08, Day08, 21, 8);
|
||||
|
|
Loading…
Reference in a new issue