main
mat ess 2022-12-05 22:24:05 -05:00
parent b561e148e0
commit c96ffb03a8
3 changed files with 668 additions and 33 deletions

9
inputs/5.small.txt Normal file
View File

@ -0,0 +1,9 @@
[D]
[N] [C]
[Z] [M] [P]
1 2 3
move 1 from 2 to 1
move 3 from 1 to 3
move 2 from 2 to 1
move 1 from 1 to 2

512
inputs/5.txt Normal file
View File

@ -0,0 +1,512 @@
[M] [Z] [V]
[Z] [P] [L] [Z] [J]
[S] [D] [W] [W] [H] [Q]
[P] [V] [N] [D] [P] [C] [V]
[H] [B] [J] [V] [B] [M] [N] [P]
[V] [F] [L] [Z] [C] [S] [P] [S] [G]
[F] [J] [M] [G] [R] [R] [H] [R] [L]
[G] [G] [G] [N] [V] [V] [T] [Q] [F]
1 2 3 4 5 6 7 8 9
move 6 from 9 to 3
move 2 from 2 to 1
move 1 from 8 to 2
move 3 from 7 to 2
move 7 from 6 to 9
move 1 from 9 to 5
move 3 from 5 to 7
move 6 from 8 to 6
move 1 from 7 to 8
move 6 from 6 to 5
move 4 from 5 to 8
move 9 from 2 to 9
move 1 from 2 to 3
move 3 from 1 to 3
move 3 from 5 to 1
move 10 from 3 to 5
move 4 from 4 to 6
move 2 from 7 to 6
move 2 from 6 to 9
move 6 from 8 to 6
move 1 from 4 to 3
move 1 from 4 to 5
move 1 from 4 to 1
move 2 from 3 to 1
move 1 from 3 to 7
move 8 from 1 to 9
move 1 from 1 to 2
move 1 from 2 to 7
move 6 from 6 to 3
move 7 from 3 to 5
move 14 from 5 to 6
move 2 from 1 to 3
move 5 from 5 to 8
move 5 from 8 to 1
move 2 from 7 to 1
move 5 from 6 to 9
move 8 from 9 to 3
move 13 from 9 to 3
move 7 from 1 to 4
move 6 from 4 to 1
move 22 from 3 to 1
move 1 from 9 to 3
move 2 from 6 to 1
move 1 from 3 to 4
move 7 from 9 to 8
move 2 from 1 to 7
move 2 from 3 to 2
move 2 from 6 to 9
move 2 from 7 to 8
move 1 from 3 to 6
move 9 from 8 to 6
move 1 from 2 to 4
move 8 from 1 to 2
move 1 from 9 to 4
move 3 from 4 to 1
move 1 from 4 to 6
move 10 from 6 to 5
move 5 from 2 to 9
move 6 from 9 to 3
move 2 from 5 to 3
move 2 from 9 to 7
move 7 from 5 to 8
move 5 from 6 to 2
move 3 from 3 to 7
move 3 from 3 to 5
move 4 from 5 to 8
move 1 from 3 to 5
move 6 from 6 to 8
move 1 from 5 to 7
move 9 from 8 to 9
move 1 from 3 to 1
move 7 from 2 to 7
move 9 from 7 to 6
move 2 from 2 to 3
move 7 from 9 to 3
move 9 from 6 to 8
move 7 from 3 to 4
move 2 from 7 to 6
move 4 from 4 to 5
move 3 from 5 to 6
move 2 from 7 to 4
move 5 from 4 to 7
move 13 from 8 to 4
move 2 from 9 to 4
move 2 from 8 to 7
move 6 from 7 to 5
move 6 from 4 to 2
move 1 from 7 to 5
move 3 from 2 to 7
move 1 from 7 to 8
move 3 from 2 to 4
move 2 from 3 to 9
move 2 from 7 to 2
move 6 from 5 to 4
move 3 from 6 to 2
move 2 from 6 to 9
move 5 from 2 to 9
move 12 from 4 to 8
move 3 from 9 to 2
move 12 from 1 to 5
move 4 from 4 to 6
move 12 from 8 to 9
move 2 from 6 to 5
move 1 from 4 to 8
move 1 from 4 to 1
move 3 from 2 to 1
move 2 from 6 to 7
move 1 from 5 to 9
move 2 from 1 to 4
move 10 from 5 to 1
move 2 from 7 to 3
move 18 from 9 to 7
move 8 from 7 to 2
move 1 from 9 to 6
move 1 from 6 to 7
move 10 from 7 to 9
move 1 from 4 to 2
move 19 from 1 to 5
move 8 from 5 to 9
move 3 from 8 to 4
move 2 from 5 to 2
move 2 from 3 to 6
move 10 from 5 to 2
move 4 from 1 to 2
move 2 from 9 to 2
move 1 from 1 to 6
move 2 from 5 to 6
move 1 from 8 to 7
move 1 from 5 to 8
move 1 from 5 to 6
move 18 from 2 to 5
move 5 from 2 to 1
move 6 from 5 to 8
move 1 from 8 to 9
move 2 from 2 to 4
move 1 from 2 to 6
move 2 from 7 to 6
move 1 from 4 to 1
move 4 from 8 to 5
move 1 from 2 to 9
move 2 from 8 to 3
move 1 from 3 to 6
move 1 from 4 to 8
move 1 from 8 to 9
move 10 from 5 to 7
move 5 from 5 to 1
move 2 from 4 to 1
move 3 from 7 to 6
move 12 from 1 to 4
move 8 from 9 to 5
move 6 from 7 to 4
move 1 from 7 to 9
move 4 from 4 to 3
move 1 from 1 to 7
move 3 from 9 to 5
move 2 from 3 to 1
move 1 from 7 to 6
move 8 from 4 to 7
move 1 from 7 to 6
move 7 from 6 to 4
move 2 from 1 to 3
move 1 from 7 to 1
move 1 from 3 to 7
move 1 from 1 to 6
move 4 from 9 to 3
move 5 from 4 to 6
move 12 from 6 to 2
move 3 from 9 to 4
move 8 from 2 to 6
move 2 from 9 to 6
move 8 from 5 to 6
move 4 from 5 to 8
move 14 from 6 to 3
move 11 from 4 to 9
move 2 from 2 to 7
move 8 from 3 to 9
move 11 from 3 to 6
move 14 from 9 to 1
move 7 from 1 to 3
move 2 from 9 to 5
move 2 from 2 to 8
move 6 from 7 to 5
move 1 from 9 to 8
move 13 from 6 to 3
move 4 from 6 to 8
move 3 from 1 to 6
move 5 from 5 to 8
move 7 from 8 to 7
move 2 from 1 to 8
move 1 from 4 to 1
move 4 from 8 to 9
move 8 from 7 to 5
move 1 from 8 to 1
move 4 from 9 to 3
move 1 from 4 to 5
move 5 from 5 to 2
move 1 from 8 to 9
move 1 from 8 to 6
move 2 from 6 to 2
move 4 from 8 to 6
move 4 from 1 to 8
move 4 from 8 to 5
move 1 from 9 to 8
move 1 from 2 to 3
move 4 from 6 to 1
move 1 from 8 to 2
move 3 from 5 to 4
move 4 from 2 to 5
move 1 from 7 to 9
move 1 from 2 to 6
move 3 from 1 to 8
move 2 from 4 to 5
move 2 from 6 to 1
move 3 from 8 to 9
move 4 from 9 to 2
move 1 from 7 to 1
move 1 from 6 to 7
move 4 from 1 to 6
move 1 from 7 to 4
move 6 from 2 to 8
move 2 from 4 to 8
move 1 from 9 to 5
move 3 from 6 to 2
move 1 from 6 to 4
move 7 from 3 to 5
move 2 from 8 to 1
move 3 from 2 to 8
move 6 from 8 to 5
move 17 from 5 to 3
move 2 from 1 to 6
move 3 from 8 to 3
move 1 from 9 to 5
move 11 from 5 to 2
move 40 from 3 to 5
move 11 from 2 to 7
move 4 from 7 to 8
move 1 from 8 to 9
move 1 from 3 to 5
move 1 from 4 to 8
move 19 from 5 to 8
move 7 from 7 to 8
move 16 from 5 to 2
move 6 from 5 to 8
move 1 from 5 to 8
move 1 from 9 to 4
move 1 from 6 to 1
move 1 from 4 to 7
move 1 from 6 to 9
move 1 from 1 to 7
move 1 from 7 to 3
move 1 from 7 to 2
move 1 from 9 to 8
move 1 from 3 to 4
move 1 from 4 to 6
move 14 from 2 to 9
move 24 from 8 to 4
move 8 from 8 to 3
move 1 from 6 to 3
move 16 from 4 to 1
move 3 from 8 to 4
move 3 from 3 to 8
move 4 from 3 to 4
move 1 from 3 to 9
move 13 from 9 to 4
move 16 from 1 to 8
move 8 from 8 to 1
move 3 from 1 to 7
move 1 from 8 to 6
move 1 from 3 to 8
move 10 from 8 to 5
move 5 from 5 to 2
move 3 from 8 to 9
move 1 from 8 to 9
move 1 from 4 to 5
move 5 from 2 to 6
move 3 from 5 to 2
move 1 from 6 to 1
move 5 from 1 to 5
move 1 from 1 to 5
move 2 from 7 to 3
move 2 from 3 to 2
move 1 from 5 to 7
move 7 from 5 to 3
move 5 from 9 to 5
move 2 from 7 to 9
move 4 from 5 to 6
move 2 from 9 to 8
move 2 from 2 to 4
move 5 from 3 to 5
move 1 from 3 to 2
move 7 from 4 to 9
move 1 from 8 to 1
move 1 from 2 to 1
move 9 from 4 to 6
move 2 from 1 to 8
move 1 from 3 to 9
move 2 from 8 to 6
move 13 from 4 to 6
move 1 from 8 to 7
move 2 from 9 to 6
move 3 from 5 to 7
move 3 from 2 to 5
move 3 from 2 to 6
move 5 from 6 to 2
move 4 from 2 to 5
move 4 from 5 to 7
move 5 from 5 to 7
move 7 from 9 to 6
move 6 from 7 to 2
move 22 from 6 to 5
move 10 from 5 to 8
move 7 from 5 to 4
move 8 from 8 to 5
move 18 from 6 to 2
move 5 from 7 to 5
move 1 from 8 to 2
move 6 from 5 to 1
move 7 from 4 to 2
move 4 from 1 to 5
move 1 from 7 to 9
move 1 from 8 to 6
move 1 from 7 to 8
move 10 from 5 to 9
move 12 from 2 to 1
move 8 from 5 to 2
move 19 from 2 to 9
move 1 from 6 to 8
move 13 from 9 to 3
move 8 from 1 to 2
move 5 from 1 to 3
move 10 from 2 to 1
move 7 from 2 to 5
move 3 from 5 to 7
move 4 from 1 to 3
move 1 from 2 to 3
move 3 from 1 to 2
move 1 from 8 to 6
move 2 from 7 to 5
move 4 from 1 to 3
move 6 from 5 to 4
move 2 from 2 to 1
move 1 from 2 to 9
move 6 from 4 to 5
move 5 from 5 to 9
move 1 from 6 to 8
move 1 from 5 to 1
move 6 from 9 to 2
move 5 from 2 to 4
move 3 from 1 to 6
move 2 from 4 to 7
move 22 from 3 to 9
move 1 from 8 to 4
move 2 from 4 to 3
move 2 from 6 to 1
move 2 from 1 to 5
move 1 from 6 to 7
move 1 from 7 to 4
move 6 from 3 to 7
move 1 from 2 to 4
move 8 from 7 to 3
move 1 from 4 to 5
move 1 from 7 to 9
move 5 from 3 to 6
move 1 from 8 to 4
move 4 from 3 to 2
move 32 from 9 to 3
move 3 from 6 to 7
move 5 from 9 to 3
move 1 from 9 to 7
move 2 from 9 to 2
move 2 from 4 to 3
move 2 from 5 to 4
move 5 from 3 to 2
move 3 from 7 to 8
move 1 from 7 to 2
move 1 from 8 to 5
move 1 from 3 to 4
move 5 from 4 to 5
move 4 from 5 to 2
move 3 from 5 to 7
move 1 from 7 to 5
move 1 from 6 to 5
move 2 from 8 to 5
move 15 from 2 to 4
move 3 from 5 to 6
move 4 from 6 to 5
move 2 from 5 to 2
move 1 from 2 to 4
move 25 from 3 to 9
move 2 from 5 to 2
move 11 from 9 to 2
move 13 from 2 to 1
move 4 from 4 to 7
move 12 from 9 to 8
move 6 from 7 to 8
move 7 from 4 to 7
move 7 from 7 to 8
move 1 from 5 to 1
move 5 from 4 to 3
move 2 from 2 to 1
move 2 from 9 to 5
move 7 from 1 to 7
move 1 from 1 to 4
move 12 from 3 to 2
move 1 from 3 to 9
move 1 from 1 to 3
move 1 from 9 to 1
move 7 from 7 to 2
move 1 from 4 to 7
move 2 from 8 to 7
move 7 from 1 to 2
move 1 from 3 to 4
move 26 from 2 to 1
move 4 from 8 to 1
move 3 from 1 to 6
move 1 from 6 to 3
move 1 from 6 to 9
move 1 from 3 to 8
move 20 from 1 to 3
move 1 from 9 to 7
move 4 from 7 to 1
move 1 from 5 to 3
move 4 from 3 to 5
move 1 from 6 to 2
move 6 from 3 to 2
move 8 from 1 to 4
move 1 from 1 to 5
move 3 from 1 to 4
move 7 from 2 to 4
move 10 from 3 to 8
move 4 from 4 to 3
move 12 from 4 to 7
move 3 from 3 to 1
move 2 from 4 to 3
move 2 from 8 to 1
move 6 from 8 to 9
move 5 from 9 to 6
move 1 from 9 to 3
move 3 from 8 to 7
move 10 from 8 to 5
move 4 from 8 to 7
move 9 from 7 to 9
move 4 from 8 to 4
move 2 from 4 to 3
move 3 from 1 to 7
move 11 from 7 to 4
move 6 from 4 to 8
move 1 from 7 to 3
move 4 from 5 to 1
move 5 from 3 to 6
move 5 from 9 to 4
move 1 from 9 to 8
move 10 from 4 to 8
move 5 from 1 to 2
move 1 from 7 to 6
move 9 from 6 to 3
move 7 from 8 to 7
move 3 from 4 to 1
move 2 from 2 to 1
move 9 from 8 to 3
move 10 from 5 to 8
move 18 from 3 to 9
move 1 from 7 to 8
move 1 from 5 to 3
move 4 from 8 to 3
move 2 from 6 to 3
move 6 from 7 to 2
move 1 from 5 to 3
move 1 from 1 to 9
move 10 from 3 to 9
move 4 from 1 to 8
move 13 from 8 to 1
move 3 from 1 to 8
move 3 from 2 to 4
move 5 from 2 to 6
move 5 from 6 to 4
move 28 from 9 to 2
move 2 from 9 to 5
move 2 from 5 to 2
move 1 from 3 to 7
move 2 from 1 to 4
move 3 from 8 to 3
move 1 from 9 to 4
move 3 from 4 to 6
move 2 from 3 to 7
move 8 from 1 to 5
move 3 from 7 to 6
move 14 from 2 to 8
move 1 from 9 to 1
move 6 from 5 to 6
move 4 from 2 to 5
move 9 from 8 to 2
move 4 from 8 to 4
move 7 from 2 to 4
move 12 from 4 to 3
move 5 from 4 to 7
move 5 from 7 to 4
move 1 from 8 to 7
move 1 from 4 to 5
move 2 from 5 to 4
move 1 from 5 to 8
move 1 from 5 to 9

View File

@ -1,13 +1,30 @@
use std::collections::HashSet; use std::collections::HashSet;
use std::fs; use std::fs;
use std::{cmp::Ordering, ops::RangeInclusive as Range}; use std::ops::RangeInclusive as Range;
use std::{cmp::Ordering, fmt::Display};
use anyhow::Error; use anyhow::Error;
use chrono::{Datelike, Local}; use chrono::{Datelike, Local};
use pico_args::Arguments; use pico_args::Arguments;
fn main() -> Result<(), Error> {
let mut args = Arguments::from_env();
let small = args.contains("--small");
let part = args.opt_free_from_str()?.unwrap_or(1);
let day = args
.opt_free_from_str()?
.unwrap_or_else(|| Local::now().day());
let small = if small { ".small" } else { "" };
let path = format!("inputs/{day}{small}.txt");
let input = fs::read_to_string(path)?;
println!("running day {day} part {part}");
let result = SOLUTIONS[day as usize - 1][part as usize - 1](input);
println!("{result}");
Ok(())
}
macro_rules! solutions { macro_rules! solutions {
($($all:tt),*) => { ($($all:expr),*) => {
const DAYS: usize = 0 $( + solutions!(@expand $all 1) )*; const DAYS: usize = 0 $( + solutions!(@expand $all 1) )*;
const SOLUTIONS: [Day; DAYS] = [ const SOLUTIONS: [Day; DAYS] = [
$($all),* $($all),*
@ -16,7 +33,33 @@ macro_rules! solutions {
(@expand $ignore:tt $e:expr) => {$e}; (@expand $ignore:tt $e:expr) => {$e};
} }
type Part = fn(String) -> u64; enum Output {
Num(u64),
Str(String),
}
impl Display for Output {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Output::Num(n) => write!(f, "{n}"),
Output::Str(s) => write!(f, "{s}"),
}
}
}
impl From<u64> for Output {
fn from(n: u64) -> Self {
Self::Num(n)
}
}
impl From<String> for Output {
fn from(s: String) -> Self {
Self::Str(s)
}
}
type Part = fn(String) -> Output;
type Day = [Part; 2]; type Day = [Part; 2];
solutions! { solutions! {
[ [
@ -31,7 +74,7 @@ solutions! {
(max, sum + cal) (max, sum + cal)
} }
}); });
max max.into()
}, },
// day 1 part 2 // day 1 part 2
|input| { |input| {
@ -52,7 +95,7 @@ solutions! {
(a, b, c, sum + cal) (a, b, c, sum + cal)
} }
}); });
a + b + c (a + b + c).into()
}, },
], ],
[ [
@ -65,7 +108,7 @@ solutions! {
let (you, me) = (RPS::from_str(you), RPS::from_str(me)); let (you, me) = (RPS::from_str(you), RPS::from_str(me));
RPS::score(you, me) RPS::score(you, me)
}) })
.sum() .sum::<u64>().into()
}, },
// day 2 part 2 // day 2 part 2
|input| { |input| {
@ -77,7 +120,7 @@ solutions! {
let me = out.requires(you); let me = out.requires(you);
RPS::score(you, me) RPS::score(you, me)
}) })
.sum() .sum::<u64>().into()
}, },
], ],
[ [
@ -90,7 +133,7 @@ solutions! {
let rs = Rucksack::new(line); let rs = Rucksack::new(line);
rs.score() rs.score()
}) })
.sum() .sum::<u64>().into()
}, },
// day 3 part 2 // day 3 part 2
|input| { |input| {
@ -105,47 +148,118 @@ solutions! {
} }
_ => unreachable!("fooey"), _ => unreachable!("fooey"),
}) })
.sum() .sum::<u64>().into()
}, },
], ],
[ [
// day 4 part 1 // day 4 part 1
|input| { |input| {
make_ranges(input) (make_ranges(input)
.iter() .iter()
.map(|(first, second)| { .filter(|(first, second)| {
range_contains(first, second) || range_contains(second, first) range_contains(first, second) || range_contains(second, first)
}) })
.map(|b| if b { 1 } else { 0 }) .count() as u64).into()
.sum()
}, },
// day 4 part 2 // day 4 part 2
|input| { |input| {
make_ranges(input) (make_ranges(input)
.iter() .iter()
.map(|(first, second)| { .filter(|(first, second)| range_overlaps(first, second) || range_overlaps(second, first))
range_overlaps(first, second) || range_overlaps(second, first) .count() as u64).into()
}) },
.map(|b| if b { 1 } else { 0 }) ],
.sum() [
// day 5 part 1
|input| {
let midpt = input.find("\n\n").unwrap();
let stacks = make_stacks(&input[..=midpt]);
let rules = make_rules(&input[midpt + 2..]);
run_rules(stacks, rules).into()
},
// day 5 part 2
|input| {
let midpt = input.find("\n\n").unwrap();
let stacks = make_stacks(&input[..=midpt]);
let rules = make_rules(&input[midpt + 2..]);
run_rules_9001(stacks, rules).into()
}, },
] ]
} }
fn main() -> Result<(), Error> { fn run_rules_9001(mut stacks: Vec<Vec<char>>, rules: Vec<Rule>) -> String {
let mut args = Arguments::from_env(); for rule in rules {
let small = args.contains("--small"); let total = stacks[rule.from - 1].len();
let part = args.opt_free_from_str()?.unwrap_or(1); let mut moved = stacks[rule.from - 1].drain((total - rule.n)..).collect();
let day = args stacks[rule.to - 1].append(&mut moved);
.opt_free_from_str()? }
.unwrap_or_else(|| Local::now().day()); let mut s = String::new();
let small = if small { ".small" } else { "" }; for stack in stacks {
let path = format!("inputs/{day}{small}.txt"); s.push(*stack.last().unwrap())
let input = fs::read_to_string(path)?; }
println!("running day {day} part {part}"); s
let result = SOLUTIONS[day as usize - 1][part as usize - 1](input); }
println!("{result}");
Ok(()) fn run_rules(mut stacks: Vec<Vec<char>>, rules: Vec<Rule>) -> String {
for rule in rules {
for _ in 0..rule.n {
let c = stacks[rule.from - 1].pop().unwrap();
stacks[rule.to - 1].push(c);
}
}
let mut s = String::new();
for stack in stacks {
s.push(*stack.last().unwrap())
}
s
}
fn make_stacks(input: &str) -> Vec<Vec<char>> {
let n = (input.find('\n').unwrap()) / 4 + 1;
let mut stacks = vec![vec![]; n];
input
.lines()
.rev()
.filter(|line| line.trim().starts_with('['))
.for_each(|line| {
for (idx, cr8) in line.chars().skip(1).step_by(4).enumerate() {
if cr8 != ' ' {
stacks[idx].push(cr8);
}
}
});
stacks
}
#[derive(Debug)]
struct Rule {
n: usize,
from: usize,
to: usize,
}
impl Rule {
fn new(raw: Vec<usize>) -> Self {
Self {
n: raw[0],
from: raw[1],
to: raw[2],
}
}
}
fn make_rules(input: &str) -> Vec<Rule> {
input
.lines()
.map(|line| {
line.split_whitespace()
.skip(1)
.step_by(2)
.map(|num| num.parse::<usize>().unwrap())
.collect()
})
.map(Rule::new)
.collect()
} }
fn make_ranges(input: String) -> Vec<(Range<u64>, Range<u64>)> { fn make_ranges(input: String) -> Vec<(Range<u64>, Range<u64>)> {