day(20): add solution
Signed-off-by: Matej Focko <me@mfocko.xyz>
This commit is contained in:
parent
08246225fb
commit
4fe0d4d891
2 changed files with 117 additions and 0 deletions
7
samples/day20.txt
Normal file
7
samples/day20.txt
Normal file
|
@ -0,0 +1,7 @@
|
|||
1
|
||||
2
|
||||
-3
|
||||
3
|
||||
-2
|
||||
0
|
||||
4
|
110
src/bin/day20.rs
Normal file
110
src/bin/day20.rs
Normal file
|
@ -0,0 +1,110 @@
|
|||
use aoc_2022::*;
|
||||
|
||||
type Input = Vec<Coordinate>;
|
||||
type Output = i64;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
struct Coordinate {
|
||||
key: i64,
|
||||
index: usize,
|
||||
swapped: bool,
|
||||
}
|
||||
|
||||
impl Coordinate {
|
||||
fn new(key: i64, index: usize) -> Self {
|
||||
Self {
|
||||
key,
|
||||
index,
|
||||
swapped: key == 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn reset(&self) -> Self {
|
||||
Self {
|
||||
swapped: self.key == 0,
|
||||
..*self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn index_of<T: PartialEq>(vector: &[T], key: &T) -> Option<usize> {
|
||||
vector
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|&(_, val)| key == val)
|
||||
.map(|found| found.0)
|
||||
}
|
||||
|
||||
fn mix(order: &[Coordinate], mut coordinates: Input) -> Input {
|
||||
let length: i64 = coordinates.len().try_into().unwrap();
|
||||
|
||||
for coordinate in order {
|
||||
if coordinate.swapped {
|
||||
continue;
|
||||
}
|
||||
|
||||
let old_idx = index_of(&coordinates, coordinate).unwrap();
|
||||
|
||||
let mut new_idx = (old_idx as i64 + coordinate.key) % (length - 1);
|
||||
if new_idx < 0 {
|
||||
new_idx += length - 1;
|
||||
}
|
||||
|
||||
let mut c = coordinates.remove(old_idx);
|
||||
c.swapped = true;
|
||||
coordinates.insert(new_idx as usize, c);
|
||||
}
|
||||
|
||||
coordinates.iter().map(Coordinate::reset).collect_vec()
|
||||
}
|
||||
|
||||
fn find_sum(mixed: &[Coordinate]) -> Output {
|
||||
let mixed = mixed.iter().map(|c| c.key).collect_vec();
|
||||
let base_index = index_of(&mixed, &0).unwrap();
|
||||
|
||||
vec![1000, 2000, 3000]
|
||||
.iter()
|
||||
.map(|off| mixed[(base_index + off) % mixed.len()])
|
||||
.sum()
|
||||
}
|
||||
|
||||
struct Day20;
|
||||
impl Solution<Input, Output> for Day20 {
|
||||
fn parse_input<P: AsRef<Path>>(pathname: P) -> Input {
|
||||
let coordinates: Vec<i64> = file_to_structs(pathname);
|
||||
|
||||
coordinates
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, key)| Coordinate::new(*key, i))
|
||||
.collect_vec()
|
||||
}
|
||||
|
||||
fn part_1(input: &Input) -> Output {
|
||||
let order = input.clone();
|
||||
let mixed = mix(&order, input.clone());
|
||||
|
||||
find_sum(&mixed)
|
||||
}
|
||||
|
||||
fn part_2(input: &Input) -> Output {
|
||||
let decryption_key = 811589153;
|
||||
let with_decryption = input
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(|c| Coordinate::new(c.key * decryption_key, c.index))
|
||||
.collect_vec();
|
||||
|
||||
let order = with_decryption.clone();
|
||||
let mixed = (0..10).fold(with_decryption, |acc, _| mix(&order, acc));
|
||||
|
||||
find_sum(&mixed)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
// Day20::run("sample")
|
||||
Day20::main()
|
||||
}
|
||||
|
||||
test_sample!(day_20, Day20, 3, 1623178306);
|
Loading…
Reference in a new issue