Solutions for 2022, as well as 2015-2018 and 2019 up to day 11

This commit is contained in:
Chris Alge 2023-03-12 15:20:02 +01:00
commit 1895197c49
722 changed files with 375457 additions and 0 deletions

View file

@ -0,0 +1,8 @@
[package]
name = "day11-hex_ed"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

View file

@ -0,0 +1,45 @@
\--- Day 11: Hex Ed ---
----------
Crossing the bridge, you've barely reached the other side of the stream when a program comes up to you, clearly in distress. "It's my child process," she says, "he's gotten lost in an infinite grid!"
Fortunately for her, you have plenty of experience with infinite grids.
Unfortunately for you, it's a [hex grid](https://en.wikipedia.org/wiki/Hexagonal_tiling).
The hexagons ("hexes") in this grid are aligned such that adjacent hexes can be found to the north, northeast, southeast, south, southwest, and northwest:
```
\ n /
nw +--+ ne
/ \
-+ +-
\ /
sw +--+ se
/ s \
```
You have the path the child process took. Starting where he started, you need to determine the fewest number of steps required to reach him. (A "step" means to move from the hex you are in to any adjacent hex.)
For example:
* `ne,ne,ne` is `3` steps away.
* `ne,ne,sw,sw` is `0` steps away (back where you started).
* `ne,ne,s,s` is `2` steps away (`se,se`).
* `se,sw,se,sw,sw` is `3` steps away (`s,s,sw`).
Your puzzle answer was `796`.
\--- Part Two ---
----------
*How many steps away* is the *furthest* he ever got from his starting position?
Your puzzle answer was `1585`.
Both parts of this puzzle are complete! They provide two gold stars: \*\*
At this point, all that is left is for you to [admire your Advent calendar](/2017).
If you still want to see it, you can [get your puzzle input](11/input).

View file

@ -0,0 +1,77 @@
enum Direction { North, NorthEast, SouthEast, South, SouthWest, NorthWest }
impl Direction {
fn parse(string_repr: &str) -> Self {
match string_repr {
"n" => Self::North,
"ne" => Self::NorthEast,
"se" => Self::SouthEast,
"s" => Self::South,
"sw" => Self::SouthWest,
"nw" => Self::NorthWest,
_ => panic!("Unknown Direction: {string_repr}"),
}
}
fn movement_components(&self) -> (isize, isize) {
match self {
Self::North => (2, 0),
Self::NorthEast => (1, 1),
Self::SouthEast => (-1, 1),
Self::South => (-2, 0),
Self::SouthWest => (-1, -1),
Self::NorthWest => (1, -1),
}
}
}
pub fn run(input: &str) -> (usize, usize) {
let (last, max) = input.split(',')
.map(Direction::parse)
.fold(((0, 0), 0), |(current, max_distance), direction| {
let new = go_direction(current, &direction);
(new, max_distance.max(distance_from_origin(new)))
});
(distance_from_origin(last), max)
}
fn go_direction(current: (isize, isize), direction: &Direction) -> (isize, isize) {
let movement = direction.movement_components();
(current.0 + movement.0, current.1 + movement.1)
}
fn distance_from_origin(position: (isize, isize)) -> usize {
let ew_distance = position.1.unsigned_abs();
let ns_distance = position.0.unsigned_abs();
ew_distance + ns_distance.saturating_sub(ew_distance)/2
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs::read_to_string;
fn read_file(name: &str) -> String {
read_to_string(name).expect(&format!("Unable to read file: {name}")[..]).trim().to_string()
}
#[test]
fn test_sample() {
let sample_inputs = read_file("tests/sample_input");
let sample_results = [
(3, 3),
(0, 2),
(2, 2),
(3, 3),
];
for (idx, line) in sample_inputs.lines().enumerate() {
assert_eq!(run(line.trim()), sample_results[idx]);
}
}
#[test]
fn test_challenge() {
let challenge_input = read_file("tests/challenge_input");
assert_eq!(run(&challenge_input), (796, 1585));
}
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,4 @@
ne,ne,ne
ne,ne,sw,sw
ne,ne,s,s
se,sw,se,sw,sw