From cd901b2fc5b3ca615675fee434521a15ccbfb6f2 Mon Sep 17 00:00:00 2001 From: Sijmen Schoon Date: Fri, 25 Dec 2020 02:15:25 +0100 Subject: [PATCH] rust(day23): Rust too --- .gitignore | 2 ++ rust/src/day23.rs | 91 +++++++++++++++++++++++++++++++++++++++++++++++ rust/src/main.rs | 10 ++++++ 3 files changed, 103 insertions(+) create mode 100644 rust/src/day23.rs diff --git a/.gitignore b/.gitignore index 35cb943..0c0ef96 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ rust/target +callgrind.* +*.prof c64/*.vs c64/*.prg diff --git a/rust/src/day23.rs b/rust/src/day23.rs new file mode 100644 index 0000000..74dfa80 --- /dev/null +++ b/rust/src/day23.rs @@ -0,0 +1,91 @@ +use std::{time::Duration, time::Instant}; + +fn step(cups: &mut [u32], current_label: u32, min: u32, max: u32) -> u32 { + let a = cups[current_label as usize]; + let b = cups[a as usize]; + let c = cups[b as usize]; + + let picked_up = &[a, b, c]; + cups[current_label as usize] = cups[c as usize]; + + let mut destination = current_label - 1; + if destination < min { + destination = max; + } + + while picked_up.contains(&destination) { + destination -= 1; + if destination < min { + destination = max; + } + } + + cups[c as usize] = cups[destination as usize]; + cups[destination as usize] = a; + cups[current_label as usize] +} + +fn part1(labels: &[u32]) -> Option { + let mut cups = vec![0; labels.len() + 1]; + for i in 0..labels.len() { + cups[labels[i] as usize] = labels[(i + 1) % labels.len()]; + } + + let mut current = labels[0]; + let min = labels.iter().min()?; + let max = labels.iter().max()?; + for _ in 0..100 { + current = step(&mut cups, current, *min, *max); + } + + let mut result = 0; + let mut label = 1; + for _ in 0..8 { + label = cups[label as usize]; + result = result * 10 + label; + } + + Some(result) +} + +fn part2(old_labels: &[u32]) -> Option { + let mut labels = Vec::from(old_labels); + labels.reserve(1_000_000); + labels.extend((*old_labels.iter().max()? + 1)..=1_000_000); + + let cups = &mut [0; 1_000_001]; + for i in 0..labels.len() { + cups[labels[i] as usize] = labels[(i + 1) % labels.len()]; + } + + let mut current = labels[0]; + let min = labels.iter().min()?; + let max = labels.iter().max()?; + for _ in 0..10_000_000 { + current = step(cups, current, *min, *max); + } + + let a = cups[1] as usize; + let b = cups[a as usize] as usize; + Some(a * b) +} + +pub fn run(print: bool) -> Duration { + let file_string = std::fs::read_to_string("../inputs/23").unwrap(); + let instant = Instant::now(); + + let labels: Vec = file_string + .trim() + .chars() + .map(|c| (c as u32 - '0' as u32)) + .collect(); + + let part1 = part1(&labels).unwrap(); + let part2 = part2(&labels).unwrap(); + + if print { + dbg!(part1, part2); + } + + instant.elapsed() +} diff --git a/rust/src/main.rs b/rust/src/main.rs index 0eabf38..bce626f 100644 --- a/rust/src/main.rs +++ b/rust/src/main.rs @@ -22,6 +22,11 @@ mod day17; use nop as day18; mod day19; use nop as day20; +use nop as day21; +use nop as day22; +mod day23; +use nop as day24; +use nop as day25; fn main() { let days = [ @@ -45,6 +50,11 @@ fn main() { day18::run, day19::run, day20::run, + day21::run, + day22::run, + day23::run, + day24::run, + day25::run, ]; if let Some(day) = std::env::args().nth(1) {