diff --git a/inputs/day23.txt b/inputs/day23.txt new file mode 100644 index 0000000..f69e63f --- /dev/null +++ b/inputs/day23.txt @@ -0,0 +1 @@ +963275481 diff --git a/inputs/test.txt b/inputs/test.txt index 391cd24..f69e63f 100644 --- a/inputs/test.txt +++ b/inputs/test.txt @@ -1,13 +1 @@ -Player 1: -9 -2 -6 -3 -1 - -Player 2: -5 -8 -4 -7 -10 +963275481 diff --git a/src/bin/day23.rs b/src/bin/day23.rs new file mode 100644 index 0000000..227610b --- /dev/null +++ b/src/bin/day23.rs @@ -0,0 +1,77 @@ +use std::error::Error; +use std::fs::File; +use std::io::{self, BufRead}; +use std::vec::Vec; + +fn main() -> Result<(), Box> { + let file = File::open("inputs/day23.txt")?; + let mut lines = io::BufReader::new(file).lines().map(|l| l.unwrap()); + let line = lines.nth(0).expect("No line in file."); + + let mut cups: Vec = line + .chars() + .map(|c| c.to_string().parse().expect("Can't parse number")) + .collect(); + + let mut cur_pos = 0; + for m in 1..101 { + println!("Move: {}", m); + println!("Cups: {:?}", cups); + + let cur_cup = cups[cur_pos]; + println!("Current: {}", cur_cup); + + let mut taken = Vec::new(); + + for i in 0..3 { + let cup = cups[(cur_pos + 1 + i) % cups.len()]; + taken.push(cup); + } + println!("Taken: {:?}", taken); + cups = cups + .iter() + .cloned() + .filter(|c| !taken.iter().any(|oc| c == oc)) + .collect(); + + let min = cups.iter().fold(cups[0], |a, b| usize::min(a, *b)); + let max = cups.iter().fold(cups[0], |a, b| usize::max(a, *b)); + + let mut dest_cup = cur_cup; + loop { + dest_cup = if dest_cup < min { max } else { dest_cup - 1 }; + if let Some(pos) = cups.iter().position(|c| *c == dest_cup) { + println!("Dest: {}", dest_cup); + for taken_cup in taken.iter().rev() { + cups.insert(pos + 1, *taken_cup); + } + break; + } + } + + // Rotate cups to keep the current cup at the same index + while cups[cur_pos] != cur_cup { + let cup = cups.remove(0); + cups.push(cup); + } + + cur_pos = (cur_pos + 1) % cups.len(); + println!("=============================") + } + + // Rotate cups make 1 the first + while cups[0] != 1 { + let cup = cups.remove(0); + cups.push(cup); + } + + let answer = cups.iter().skip(1).fold(0, |a, c| a * 10 + c); + println!("Answer: {}", answer); + + Ok(()) +} + +#[cfg(test)] +mod tests { + use crate::*; +} diff --git a/src/bin/day23_part2.rs b/src/bin/day23_part2.rs new file mode 100644 index 0000000..91017f5 --- /dev/null +++ b/src/bin/day23_part2.rs @@ -0,0 +1,75 @@ +use std::error::Error; +use std::fs::File; +use std::io::{self, BufRead}; +use std::vec::Vec; + +fn main() -> Result<(), Box> { + let file = File::open("inputs/day23.txt")?; + let mut lines = io::BufReader::new(file).lines().map(|l| l.unwrap()); + let line = lines.nth(0).expect("No line in file."); + + let input: Vec = line + .chars() + .map(|c| c.to_string().parse().expect("Can't parse number")) + .collect(); + + let cup_count = 1_000_000; + + // Initilize the linked list with cup_count ordered cups + let mut cups = Vec::with_capacity(cup_count + 1); + for v in 0..cup_count + 1 { + cups.push(v + 1) + } + + // Order the first ten according to the input + for i in 0..input.len() - 1 { + let cup = input[i]; + let next_cup = input[i + 1]; + + cups[cup] = next_cup; + } + + // Initialize cup zero, used as the 'current cup' later + cups[0] = input[0]; + + // Connect the ends + // The last from the input, points to the first autogenerated cup + cups[input[input.len() - 1]] = input.len() + 1; + + let idx = cups.len() - 1; + cups[idx] = input[0]; + + for _ in 1..10_000_001 { + let cur_cup = cups[0]; + + let taken1 = cups[cur_cup]; + let taken2 = cups[taken1]; + let taken3 = cups[taken2]; + cups[cur_cup] = cups[taken3]; + cups[0] = cups[taken3]; + + let mut dest = cur_cup; + while dest == taken1 || dest == taken2 || dest == taken3 || dest == cur_cup { + dest = if dest - 1 == 0 { cup_count } else { dest - 1 } + } + + let cut = cups[dest]; + cups[dest] = taken1; + cups[taken3] = cut; + } + + let a = cups[1]; + let b = cups[a]; + + println!("Cups: {} {}", a, b); + + let answer = a * b; + println!("Answer: {}", answer); + + Ok(()) +} + +#[cfg(test)] +mod tests { + use crate::*; +}