rust(day23): Rust too
This commit is contained in:
parent
050cd4e1be
commit
cd901b2fc5
3 changed files with 103 additions and 0 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,4 +1,6 @@
|
|||
rust/target
|
||||
callgrind.*
|
||||
*.prof
|
||||
|
||||
c64/*.vs
|
||||
c64/*.prg
|
||||
|
|
91
rust/src/day23.rs
Normal file
91
rust/src/day23.rs
Normal file
|
@ -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<u32> {
|
||||
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<usize> {
|
||||
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<u32> = 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()
|
||||
}
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue