diff --git a/Cargo.toml b/Cargo.toml index 7161516..2fb75e2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,5 @@ [workspace] members = [ "day_1", + "day_2", ] diff --git a/day_2/Cargo.toml b/day_2/Cargo.toml new file mode 100644 index 0000000..30ea542 --- /dev/null +++ b/day_2/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "day_2" +version = "0.1.0" +authors = ["Smaug123 "] +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +[dev-dependencies] +criterion = "0.3" + +[[bench]] +name = "day_2" +harness = false diff --git a/day_2/benches/day_2.rs b/day_2/benches/day_2.rs new file mode 100644 index 0000000..22f58bf --- /dev/null +++ b/day_2/benches/day_2.rs @@ -0,0 +1,19 @@ +use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use day_2::day_2::{input, part_1, part_2}; + +fn criterion_benchmark(c: &mut Criterion) { + let input = input(); + c.bench_function("day 2 part 1", |b| { + b.iter(|| { + black_box(part_1(&input)); + }) + }); + c.bench_function("day 2 part 2", |b| { + b.iter(|| { + black_box(part_2(&input)); + }) + }); +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/day_2/day_1.m b/day_2/day_1.m new file mode 100644 index 0000000..a88ce04 --- /dev/null +++ b/day_2/day_1.m @@ -0,0 +1,5 @@ +ints = ReadList[StringJoin[NotebookDirectory[], "/input.txt"], "Number"]; + +part1 = Tr@Clip[Differences@#, {0, 1}] &; + +part2 = Tr@Boole[Less @@@ Partition[#, 4, 1][[All, {1, 4}]]] &; diff --git a/day_2/input.txt b/day_2/input.txt new file mode 100644 index 0000000..b3a0ece --- /dev/null +++ b/day_2/input.txt @@ -0,0 +1,1000 @@ +forward 9 +down 3 +down 8 +forward 2 +up 3 +forward 5 +up 8 +down 2 +down 5 +up 7 +down 9 +forward 4 +up 5 +down 9 +forward 2 +forward 2 +forward 8 +down 6 +forward 2 +up 9 +up 5 +down 2 +forward 5 +down 8 +forward 3 +up 4 +forward 5 +forward 7 +down 8 +down 6 +up 7 +down 3 +forward 4 +up 8 +down 5 +down 3 +down 6 +down 8 +forward 1 +forward 9 +forward 4 +up 7 +down 4 +forward 7 +forward 3 +forward 9 +down 1 +down 3 +up 9 +down 3 +forward 9 +up 6 +up 9 +down 8 +up 3 +down 1 +up 8 +down 8 +down 2 +down 4 +down 4 +up 3 +down 6 +down 1 +down 3 +forward 1 +up 5 +forward 5 +forward 8 +down 2 +forward 6 +forward 2 +up 7 +forward 6 +down 8 +forward 6 +forward 5 +up 9 +forward 5 +up 5 +forward 9 +down 2 +down 4 +down 3 +down 8 +forward 9 +forward 6 +forward 2 +up 7 +down 7 +up 3 +forward 4 +forward 5 +down 7 +forward 5 +up 9 +forward 6 +forward 6 +forward 1 +down 6 +forward 9 +up 2 +down 7 +down 8 +down 6 +up 5 +down 8 +down 8 +forward 7 +down 6 +up 5 +down 9 +down 3 +forward 2 +down 4 +forward 8 +down 5 +up 5 +forward 7 +up 2 +up 2 +down 4 +forward 4 +down 5 +up 8 +down 2 +forward 4 +down 9 +forward 8 +down 5 +down 6 +down 7 +up 7 +up 5 +up 7 +forward 7 +forward 8 +down 2 +forward 3 +down 2 +down 7 +down 4 +down 2 +forward 3 +forward 5 +down 3 +down 7 +up 7 +down 7 +up 5 +forward 1 +down 8 +down 2 +up 4 +up 5 +down 8 +forward 9 +down 3 +down 9 +forward 8 +forward 1 +forward 1 +down 2 +up 9 +down 2 +up 8 +down 6 +up 8 +forward 7 +down 5 +forward 7 +down 8 +forward 8 +down 7 +up 9 +up 2 +up 6 +down 5 +down 9 +forward 2 +up 3 +down 4 +up 5 +up 4 +down 9 +forward 7 +forward 7 +down 3 +forward 4 +forward 9 +up 8 +forward 3 +down 1 +forward 2 +down 7 +down 3 +down 7 +down 7 +forward 8 +forward 4 +forward 7 +up 1 +down 4 +up 9 +down 2 +down 1 +forward 6 +down 3 +forward 7 +forward 8 +up 9 +up 2 +up 2 +forward 7 +up 2 +up 5 +forward 5 +down 3 +forward 8 +forward 1 +up 4 +down 6 +down 5 +forward 4 +up 9 +forward 8 +up 4 +down 8 +down 3 +down 3 +down 7 +forward 2 +forward 4 +down 9 +down 7 +down 2 +up 3 +up 3 +forward 8 +forward 7 +forward 8 +down 5 +up 5 +forward 3 +forward 6 +up 7 +up 1 +forward 2 +forward 5 +down 5 +forward 8 +down 2 +down 4 +forward 2 +down 7 +down 3 +down 5 +forward 9 +down 7 +down 8 +up 1 +up 2 +down 8 +forward 7 +forward 8 +down 8 +forward 5 +up 7 +forward 3 +up 2 +down 7 +forward 1 +down 2 +up 7 +up 4 +down 2 +forward 1 +up 5 +forward 2 +up 2 +forward 3 +forward 9 +forward 2 +forward 8 +forward 2 +up 7 +down 8 +down 7 +forward 2 +forward 7 +down 1 +forward 2 +up 1 +up 6 +down 3 +down 6 +forward 7 +down 4 +forward 5 +forward 6 +up 3 +forward 3 +down 6 +forward 8 +up 8 +forward 4 +down 3 +forward 3 +down 4 +down 7 +forward 9 +forward 2 +up 2 +forward 8 +down 6 +forward 6 +down 9 +down 9 +forward 8 +down 1 +forward 9 +down 1 +down 6 +down 8 +down 5 +down 5 +forward 3 +forward 3 +down 2 +down 5 +forward 9 +down 2 +down 8 +down 3 +forward 9 +up 2 +down 4 +down 9 +forward 9 +forward 1 +forward 5 +up 9 +down 1 +down 6 +forward 6 +forward 5 +forward 8 +down 2 +forward 8 +down 4 +down 2 +down 6 +down 6 +up 3 +up 8 +forward 1 +down 1 +up 8 +down 3 +down 4 +up 9 +up 1 +down 7 +down 7 +up 1 +up 2 +forward 5 +up 8 +forward 2 +down 3 +forward 1 +up 5 +forward 6 +forward 2 +down 6 +up 2 +forward 2 +forward 1 +down 3 +forward 4 +up 8 +forward 5 +down 4 +forward 2 +down 8 +down 7 +up 7 +down 8 +forward 1 +down 4 +up 9 +down 6 +up 6 +up 6 +down 2 +forward 1 +forward 8 +down 6 +up 3 +down 7 +forward 9 +up 1 +up 4 +forward 7 +down 7 +forward 1 +down 6 +down 4 +down 7 +down 8 +down 8 +forward 4 +down 6 +down 6 +down 5 +forward 6 +up 9 +up 3 +down 4 +forward 8 +down 7 +forward 6 +up 3 +forward 1 +forward 1 +down 8 +forward 7 +forward 4 +forward 6 +up 1 +forward 7 +up 8 +forward 2 +forward 6 +forward 8 +down 9 +down 8 +up 9 +up 4 +up 2 +forward 2 +forward 8 +up 2 +forward 3 +forward 2 +up 2 +up 5 +up 8 +forward 4 +forward 8 +forward 3 +up 5 +down 1 +forward 2 +down 7 +down 8 +forward 3 +up 1 +forward 5 +forward 7 +forward 9 +up 7 +forward 4 +down 4 +up 2 +forward 4 +forward 5 +forward 3 +up 9 +forward 6 +forward 8 +down 9 +down 1 +forward 1 +down 5 +down 2 +forward 9 +down 2 +up 9 +down 1 +forward 5 +forward 8 +up 2 +forward 6 +down 4 +down 9 +forward 4 +forward 1 +down 3 +down 3 +up 5 +forward 5 +down 6 +forward 3 +down 2 +forward 8 +down 7 +down 2 +down 1 +forward 2 +up 5 +forward 9 +forward 3 +forward 5 +down 4 +up 7 +forward 6 +down 3 +forward 1 +forward 7 +forward 1 +up 4 +down 2 +down 7 +up 9 +forward 9 +down 8 +down 1 +up 2 +down 3 +forward 7 +down 8 +down 5 +down 5 +up 8 +forward 1 +down 5 +forward 8 +up 7 +down 1 +forward 9 +down 4 +forward 8 +forward 5 +forward 7 +forward 8 +forward 3 +up 9 +forward 3 +down 7 +down 5 +up 8 +forward 3 +up 6 +forward 8 +up 3 +down 5 +forward 5 +forward 6 +forward 4 +forward 3 +forward 8 +up 9 +forward 2 +down 6 +down 4 +down 5 +forward 7 +down 2 +up 5 +forward 2 +forward 5 +down 9 +forward 8 +down 8 +forward 6 +down 9 +down 7 +up 9 +forward 3 +forward 3 +up 5 +down 2 +forward 5 +down 6 +down 6 +down 2 +down 3 +down 4 +forward 7 +up 1 +down 7 +forward 7 +up 1 +forward 3 +up 6 +down 7 +down 5 +forward 9 +forward 2 +down 5 +forward 9 +down 5 +forward 9 +forward 1 +down 4 +forward 9 +down 5 +forward 8 +down 6 +down 4 +down 5 +forward 9 +down 1 +forward 6 +forward 9 +down 1 +down 1 +up 2 +forward 5 +forward 3 +down 4 +up 8 +forward 8 +down 2 +forward 3 +forward 1 +down 7 +forward 6 +forward 5 +up 7 +up 8 +down 5 +up 3 +down 8 +forward 6 +forward 5 +forward 6 +up 1 +up 8 +up 7 +down 5 +forward 3 +forward 9 +up 9 +up 4 +up 7 +up 8 +forward 7 +forward 3 +forward 9 +down 7 +forward 3 +down 6 +forward 9 +down 1 +forward 3 +down 1 +forward 8 +forward 7 +down 2 +forward 1 +forward 6 +forward 7 +down 3 +down 2 +down 1 +forward 7 +forward 4 +down 6 +up 4 +forward 4 +forward 9 +forward 3 +down 1 +up 2 +down 3 +down 5 +forward 7 +forward 5 +up 1 +down 2 +down 3 +down 8 +forward 1 +down 4 +forward 5 +down 5 +up 6 +down 6 +down 8 +forward 1 +forward 9 +up 5 +forward 2 +down 9 +down 5 +down 1 +down 4 +down 9 +down 8 +forward 2 +forward 4 +up 2 +forward 3 +down 8 +down 5 +up 5 +forward 8 +up 2 +down 8 +up 3 +forward 7 +down 7 +forward 8 +down 7 +down 3 +up 6 +forward 5 +up 4 +up 5 +forward 9 +forward 6 +down 9 +forward 5 +down 5 +down 3 +forward 2 +down 1 +up 9 +up 8 +down 6 +down 1 +forward 9 +forward 4 +forward 2 +up 1 +forward 5 +forward 9 +up 5 +forward 8 +forward 4 +down 4 +down 4 +down 2 +forward 1 +forward 7 +down 9 +forward 4 +down 5 +down 4 +down 7 +down 2 +forward 9 +down 3 +forward 6 +forward 3 +down 9 +down 3 +down 4 +down 9 +down 9 +up 6 +down 5 +up 4 +down 1 +down 1 +forward 9 +forward 7 +down 9 +forward 4 +down 8 +down 7 +forward 7 +forward 4 +up 2 +up 5 +forward 2 +forward 7 +down 1 +forward 6 +forward 6 +forward 3 +forward 8 +down 2 +up 2 +forward 7 +up 5 +down 1 +down 5 +forward 8 +down 6 +forward 8 +down 5 +down 4 +down 6 +forward 5 +down 1 +forward 9 +forward 8 +up 5 +down 6 +forward 5 +up 5 +down 4 +forward 1 +down 2 +down 5 +down 3 +forward 2 +down 9 +forward 1 +forward 1 +forward 1 +forward 8 +forward 2 +down 8 +down 6 +up 1 +forward 6 +down 3 +down 4 +up 9 +down 3 +down 3 +up 7 +down 4 +forward 4 +forward 9 +down 3 +down 8 +forward 5 +down 3 +down 6 +down 7 +forward 1 +up 2 +forward 8 +down 1 +down 4 +up 9 +forward 9 +up 4 +up 2 +forward 3 +forward 4 +down 2 +down 2 +down 6 +forward 6 +forward 8 +down 6 +up 6 +down 5 +forward 1 +down 4 +up 9 +forward 1 +forward 3 +down 1 +down 4 +up 6 +forward 5 +forward 6 +up 9 +up 9 +down 2 +up 6 +forward 1 +forward 2 +forward 3 +forward 3 +forward 6 +up 2 +down 8 +down 9 +forward 7 +up 1 +up 3 +down 2 +forward 3 +down 8 +forward 9 +down 3 +forward 6 +up 2 +forward 7 +down 2 +forward 5 +down 4 +down 2 +up 8 +forward 3 +forward 5 +forward 9 +forward 5 +forward 3 +up 9 +down 7 +forward 4 +forward 2 +forward 7 +down 5 +up 6 +up 6 +forward 8 +down 2 +forward 1 +up 1 +up 9 +up 8 +up 3 +up 4 +down 2 +up 7 +down 4 +up 5 +down 1 +up 9 +down 5 +down 9 +down 4 +up 2 +down 8 +up 2 +up 7 +up 9 +forward 4 +forward 2 +forward 1 +forward 6 +forward 8 +up 5 +forward 5 +forward 5 +down 4 +up 6 +forward 3 +down 9 +down 7 +forward 4 +down 3 +up 1 +forward 4 +down 2 +down 6 +up 3 +up 1 +down 9 +down 7 +down 9 +forward 3 +forward 8 +down 8 +up 7 +up 6 +down 2 +down 9 +down 1 +down 9 +forward 6 +up 4 +down 3 +forward 5 +up 3 +up 9 +up 8 +forward 6 +down 8 +forward 6 +forward 6 +forward 5 +up 4 +down 4 +up 6 +up 4 +forward 2 +down 5 +forward 9 +up 7 +up 6 +down 4 +forward 7 +forward 6 +up 2 +down 8 +down 6 +forward 5 +up 2 +forward 5 +forward 1 +up 9 +down 8 +forward 7 +up 4 +forward 8 +down 4 +forward 3 +forward 3 +down 9 +forward 4 +forward 9 +up 8 +forward 7 +forward 3 +forward 9 +forward 4 +up 3 +forward 2 +forward 7 diff --git a/day_2/src/lib.rs b/day_2/src/lib.rs new file mode 100644 index 0000000..10ae21e --- /dev/null +++ b/day_2/src/lib.rs @@ -0,0 +1,180 @@ +pub mod day_2 { + + pub enum Direction { + Forward, + Down, + Up, + } + + pub struct Movement { + direction: Direction, + distance: u32, + } + + fn chomp(input: &mut I, s: &str) + where + I: Iterator, + { + for expected in s.chars() { + if input.next() != Some(expected) { + panic!("Unexpected character"); + } + } + } + + fn parse_int(input: &mut I) -> u32 + where + I: Iterator, + { + let mut answer = 0; + for c in input { + answer = answer * 10 + char::to_digit(c, 10).unwrap(); + } + answer + } + + pub fn parse_movement(s: &str) -> Movement { + let mut iter = s.chars(); + let direction = match iter.next() { + None => { + panic!("Expected a nonempty string"); + } + Some('f') => { + chomp(&mut iter, "orward "); + Direction::Forward + } + Some('u') => { + chomp(&mut iter, "p "); + Direction::Up + } + Some('d') => { + chomp(&mut iter, "own "); + Direction::Down + } + Some(c) => { + panic!("Unknown character: {}", c); + } + }; + Movement { + direction, + distance: parse_int(&mut iter), + } + } + + pub fn input() -> Vec { + let input = include_str!("../input.txt"); + input + .trim() + .split('\n') + .map(parse_movement) + .collect::>() + } + + pub struct Position { + x: u32, + y: u32, + } + + fn step(position: Position, movement: &Movement) -> Position { + match movement.direction { + Direction::Forward => Position { + x: position.x + movement.distance, + y: position.y, + }, + Direction::Up => Position { + x: position.x, + y: position.y - movement.distance, + }, + Direction::Down => Position { + x: position.x, + y: position.y + movement.distance, + }, + } + } + + pub fn part_1(movements: &[Movement]) -> u32 { + let start_pos = Position { x: 0, y: 0 }; + let final_pos = movements.iter().fold(start_pos, |pos, dir| step(pos, dir)); + final_pos.x * final_pos.y + } + + pub struct Position2 { + x: u32, + depth: u32, + aim: u32, + } + + fn step_2(position: Position2, movement: &Movement) -> Position2 { + match movement.direction { + Direction::Forward => Position2 { + aim: position.aim, + x: position.x + movement.distance, + depth: position.depth + movement.distance * position.aim, + }, + Direction::Up => Position2 { + x: position.x, + depth: position.depth, + aim: position.aim - movement.distance, + }, + Direction::Down => Position2 { + x: position.x, + depth: position.depth, + aim: position.aim + movement.distance, + }, + } + } + + pub fn part_2(movements: &[Movement]) -> u32 { + let start_pos = Position2 { + x: 0, + depth: 0, + aim: 0, + }; + let final_pos = movements + .iter() + .fold(start_pos, |pos, dir| step_2(pos, dir)); + final_pos.x * final_pos.depth + } +} + +#[cfg(test)] +mod tests { + use super::day_2::*; + + #[test] + fn part1_known() { + let input = [ + "forward 5", + "down 5", + "forward 8", + "up 3", + "down 8", + "forward 2", + ] + .map(parse_movement); + + assert_eq!(part_1(&input), 150); + } + + #[test] + fn part2_known() { + let input = [ + "forward 5", + "down 5", + "forward 8", + "up 3", + "down 8", + "forward 2", + ] + .map(parse_movement); + println!("{}", part_2(&input)); + assert_eq!(part_2(&input), 900); + } + + #[test] + fn test_day_2() { + let input = input(); + assert_eq!(part_1(&input), 1451208); + assert_eq!(part_2(&input), 1620141160); + } +} diff --git a/day_2/src/main.rs b/day_2/src/main.rs new file mode 100644 index 0000000..56335b0 --- /dev/null +++ b/day_2/src/main.rs @@ -0,0 +1,7 @@ +use day_2::day_2; + +fn main() { + let input = day_2::input(); + println!("part 1 => {}", day_2::part_1(&input)); + println!("part 2 => {}", day_2::part_2(&input)); +}