1
0
Fork 0

day(20): add solution

Signed-off-by: Matej Focko <me@mfocko.xyz>
This commit is contained in:
Matej Focko 2023-01-07 12:30:28 +01:00
parent 08246225fb
commit 4fe0d4d891
Signed by: mfocko
GPG key ID: 7C47D46246790496
2 changed files with 117 additions and 0 deletions

7
samples/day20.txt Normal file
View file

@ -0,0 +1,7 @@
1
2
-3
3
-2
0
4

110
src/bin/day20.rs Normal file
View 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);