Solutions for 2022, as well as 2015-2018 and 2019 up to day 11
This commit is contained in:
commit
1895197c49
722 changed files with 375457 additions and 0 deletions
9
2018/day11_chronal_charge/Cargo.toml
Normal file
9
2018/day11_chronal_charge/Cargo.toml
Normal file
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "day11_chronal_charge"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
rayon = "1.6.1"
|
65
2018/day11_chronal_charge/challenge.txt
Normal file
65
2018/day11_chronal_charge/challenge.txt
Normal file
|
@ -0,0 +1,65 @@
|
|||
You watch the Elves and their sleigh fade into the distance as they head toward the North Pole.
|
||||
|
||||
Actually, you're the one fading. The falling sensation returns.
|
||||
|
||||
The low fuel warning light is illuminated on your wrist-mounted device. Tapping it once causes it to project a hologram of the situation: a *300x300* grid of fuel cells and their current power levels, some negative. You're not sure what negative power means in the context of time travel, but it can't be good.
|
||||
|
||||
Each fuel cell has a coordinate ranging *from 1 to 300* in both the X (horizontal) and Y (vertical) direction. In `X,Y` notation, the top-left cell is `1,1`, and the top-right cell is `300,1`.
|
||||
|
||||
The interface lets you select *any 3x3 square* of fuel cells. To increase your chances of getting to your destination, you decide to choose the 3x3 square with the *largest total power*.
|
||||
|
||||
The power level in a given fuel cell can be found through the following process:
|
||||
|
||||
* Find the fuel cell's *rack ID*, which is its *X coordinate plus 10*.
|
||||
* Begin with a power level of the *rack ID* times the *Y coordinate*.
|
||||
* Increase the power level by the value of the *grid serial number* (your puzzle input).
|
||||
* Set the power level to itself multiplied by the *rack ID*.
|
||||
* Keep only the *hundreds digit* of the power level (so `12*3*45` becomes `3`; numbers with no hundreds digit become `0`).
|
||||
* *Subtract 5* from the power level.
|
||||
|
||||
For example, to find the power level of the fuel cell at `3,5` in a grid with serial number `8`:
|
||||
|
||||
* The rack ID is `3 + 10 = *13*`.
|
||||
* The power level starts at `13 * 5 = *65*`.
|
||||
* Adding the serial number produces `65 + 8 = *73*`.
|
||||
* Multiplying by the rack ID produces `73 * 13 = *949*`.
|
||||
* The hundreds digit of `*9*49` is `*9*`.
|
||||
* Subtracting 5 produces `9 - 5 = *4*`.
|
||||
|
||||
So, the power level of this fuel cell is `*4*`.
|
||||
|
||||
Here are some more example power levels:
|
||||
|
||||
* Fuel cell at `122,79`, grid serial number `57`: power level `-5`.
|
||||
* Fuel cell at `217,196`, grid serial number `39`: power level `0`.
|
||||
* Fuel cell at `101,153`, grid serial number `71`: power level `4`.
|
||||
|
||||
Your goal is to find the 3x3 square which has the largest total power. The square must be entirely within the 300x300 grid. Identify this square using the `X,Y` coordinate of its *top-left fuel cell*. For example:
|
||||
|
||||
For grid serial number `18`, the largest total 3x3 square has a top-left corner of `*33,45*` (with a total power of `29`); these fuel cells appear in the middle of this 5x5 region:
|
||||
|
||||
```
|
||||
-2 -4 4 4 4
|
||||
-4 4 4 4 -5
|
||||
4 3 3 4 -4
|
||||
1 1 2 4 -3
|
||||
-1 0 2 -5 -2
|
||||
|
||||
```
|
||||
|
||||
For grid serial number `42`, the largest 3x3 square's top-left is `*21,61*` (with a total power of `30`); they are in the middle of this region:
|
||||
|
||||
```
|
||||
-3 4 2 2 2
|
||||
-4 4 3 3 4
|
||||
-5 3 3 4 -4
|
||||
4 3 3 4 -3
|
||||
3 3 3 -5 -1
|
||||
|
||||
```
|
||||
|
||||
*What is the `X,Y` coordinate of the top-left fuel cell of the 3x3 square with the largest total power?*
|
||||
|
||||
Your puzzle input is `2187`.
|
||||
|
||||
Answer:
|
72
2018/day11_chronal_charge/src/lib.rs
Normal file
72
2018/day11_chronal_charge/src/lib.rs
Normal file
|
@ -0,0 +1,72 @@
|
|||
use rayon::prelude::*;
|
||||
|
||||
pub fn run(input: &str) -> ((usize, usize), (usize, usize, usize)) {
|
||||
let grid_serial = input.parse::<i32>().unwrap();
|
||||
let grid: Vec<Vec<i32>> = (1..=300).map(|y|
|
||||
(1..=300).map(|x| cell_charge(x, y, grid_serial))
|
||||
.collect()
|
||||
).collect();
|
||||
let first = get_max_charge(&grid, 3).0;
|
||||
let second = get_total_max_charge(&grid);
|
||||
((first.0 + 1, first.1 + 1), (second.0.0 + 1, second.0.1 + 1, second.1))
|
||||
}
|
||||
|
||||
fn get_total_max_charge(grid: &[Vec<i32>]) -> ((usize, usize), usize) {
|
||||
let mut best = ((0, 0), 1);
|
||||
let mut best_val = i32::MIN;
|
||||
let mut side_length = 1;
|
||||
loop {
|
||||
let this = get_max_charge(grid, side_length);
|
||||
if this.1 > best_val {
|
||||
best_val = this.1;
|
||||
best = (this.0, side_length);
|
||||
side_length += 1;
|
||||
} else if this.1 > 0 {
|
||||
side_length += 1;
|
||||
} else {
|
||||
return best;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_max_charge(grid: &[Vec<i32>], side_length: usize) -> ((usize, usize), i32) {
|
||||
(0..=300-side_length).into_par_iter()
|
||||
.map(|y|
|
||||
(0..=300-side_length).map(|x| ((x, y), grid_charge(grid, (x, y), side_length)))
|
||||
.max_by_key(|charge| charge.1).unwrap())
|
||||
.max_by_key(|charge| charge.1)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn grid_charge(grid: &[Vec<i32>], top_left: (usize, usize), side_length: usize) -> i32 {
|
||||
(0..side_length).map(|y_offset|
|
||||
(0..side_length).map(|x_offset| grid[top_left.1 + y_offset][top_left.0 + x_offset])
|
||||
.sum::<i32>()
|
||||
).sum()
|
||||
}
|
||||
|
||||
fn cell_charge(x: i32, y: i32, grid_serial: i32) -> i32 {
|
||||
((((x + 10) * y + grid_serial) * (x + 10) ) % 1000 ) / 100 - 5
|
||||
}
|
||||
|
||||
#[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_input = read_file("tests/sample_input");
|
||||
assert_eq!(run(&sample_input), ((33, 45), (90, 269, 16)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_challenge() {
|
||||
let challenge_input = read_file("tests/challenge_input");
|
||||
assert_eq!(run(&challenge_input), ((235, 85), (233, 40, 13)));
|
||||
}
|
||||
}
|
1
2018/day11_chronal_charge/tests/challenge_input
Normal file
1
2018/day11_chronal_charge/tests/challenge_input
Normal file
|
@ -0,0 +1 @@
|
|||
2187
|
1
2018/day11_chronal_charge/tests/sample_input
Normal file
1
2018/day11_chronal_charge/tests/sample_input
Normal file
|
@ -0,0 +1 @@
|
|||
18
|
Loading…
Add table
Add a link
Reference in a new issue