Day 22 part 2.
This commit is contained in:
10
Cargo.lock
generated
10
Cargo.lock
generated
@@ -16,6 +16,7 @@ name = "aoc_2019"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itertools",
|
"itertools",
|
||||||
|
"modinverse",
|
||||||
"num-integer",
|
"num-integer",
|
||||||
"regex",
|
"regex",
|
||||||
]
|
]
|
||||||
@@ -47,6 +48,15 @@ version = "2.4.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "modinverse"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2f62f577f148cc1a9466e7065a22e59466a7d537cceba5e77e57181d0f706633"
|
||||||
|
dependencies = [
|
||||||
|
"num-integer",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-integer"
|
name = "num-integer"
|
||||||
version = "0.1.44"
|
version = "0.1.44"
|
||||||
|
|||||||
@@ -9,4 +9,5 @@ edition = "2021"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
itertools = "0.10.3"
|
itertools = "0.10.3"
|
||||||
regex = "1.5.5"
|
regex = "1.5.5"
|
||||||
num-integer = "0.1.44"
|
num-integer = "0.1.44"
|
||||||
|
modinverse = "0.1.1"
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
|
use modinverse::modinverse;
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
let input = std::fs::read_to_string("input/day22.txt").unwrap();
|
let input = std::fs::read_to_string("input/day22.txt").unwrap();
|
||||||
task1(input);
|
println!("{}", task2(input, 119315717514047, 2020, 101741582076661));
|
||||||
}
|
}
|
||||||
|
|
||||||
type Deck = VecDeque<u16>;
|
type Deck = VecDeque<u16>;
|
||||||
|
type Size = i128;
|
||||||
|
|
||||||
fn task1(input: String) {
|
fn task1(input: String) -> usize {
|
||||||
let deck_size = 10_007;
|
let deck_size = 10_007;
|
||||||
let mut deck: Deck = (0..deck_size).collect();
|
let mut deck: Deck = (0..deck_size).collect();
|
||||||
for line in input.lines() {
|
for line in input.lines() {
|
||||||
@@ -31,6 +33,7 @@ fn task1(input: String) {
|
|||||||
.find_map(|(i, card)| if *card == 2019 { Some(i) } else { None });
|
.find_map(|(i, card)| if *card == 2019 { Some(i) } else { None });
|
||||||
|
|
||||||
println!("Result: {:?}", pos_2019);
|
println!("Result: {:?}", pos_2019);
|
||||||
|
pos_2019.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn into_new_stack(deck: Deck) -> Deck {
|
fn into_new_stack(deck: Deck) -> Deck {
|
||||||
@@ -55,3 +58,80 @@ fn deal_with_increment(deck: Deck, n: usize) -> Deck {
|
|||||||
}
|
}
|
||||||
new.into_iter().collect()
|
new.into_iter().collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn task2(input: String, deck_size: Size, field_after: Size, num_iterations: usize) -> Size {
|
||||||
|
let shuffles: Vec<String> = input.trim().lines().rev().map(|it| it.into()).collect();
|
||||||
|
let mut results: HashMap<Size, usize> = HashMap::new();
|
||||||
|
|
||||||
|
let mut result = field_after;
|
||||||
|
results.insert(result, 0);
|
||||||
|
|
||||||
|
let mut iteration = 1;
|
||||||
|
while iteration <= num_iterations {
|
||||||
|
result = revert_iteration_find_start(&shuffles, deck_size, result);
|
||||||
|
if let Some(last_iteration) = results.get(&result) {
|
||||||
|
println!("check after {} iterations", iteration);
|
||||||
|
let iterations = iteration - last_iteration;
|
||||||
|
let full_cycles_remaining = (num_iterations - iteration) / iterations;
|
||||||
|
iteration += full_cycles_remaining * iterations;
|
||||||
|
} else {
|
||||||
|
results.insert(result, iteration);
|
||||||
|
}
|
||||||
|
iteration += 1;
|
||||||
|
if iteration % 1000 == 0 {
|
||||||
|
println!("iteration {}", iteration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn revert_iteration_find_start(shuffles: &Vec<String>, deck_size: Size, field_after: Size) -> Size {
|
||||||
|
let mut current: Size = field_after;
|
||||||
|
for line in shuffles {
|
||||||
|
if line.starts_with("deal into new stack") {
|
||||||
|
current = deck_size - 1 - current;
|
||||||
|
} else if line.starts_with("cut") {
|
||||||
|
let s = line.split("cut ").collect::<Vec<_>>();
|
||||||
|
let n = s[1].parse::<Size>().unwrap();
|
||||||
|
current += n;
|
||||||
|
current += deck_size;
|
||||||
|
current %= deck_size;
|
||||||
|
} else if line.starts_with("deal with increment") {
|
||||||
|
let s = line.split("deal with increment ").collect::<Vec<_>>();
|
||||||
|
let n = s[1].parse::<Size>().unwrap();
|
||||||
|
current = revert_finite_field_multiplikation(deck_size, n, current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
current
|
||||||
|
}
|
||||||
|
|
||||||
|
fn revert_finite_field_multiplikation(
|
||||||
|
field_length: Size,
|
||||||
|
multiplicator: Size,
|
||||||
|
result: Size,
|
||||||
|
) -> Size {
|
||||||
|
let multiplicator_inverse =
|
||||||
|
modinverse(multiplicator, field_length).expect("no modular inverse found");
|
||||||
|
(result * multiplicator_inverse) % field_length
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use crate::tasks::day22::task1;
|
||||||
|
use crate::tasks::day22::task2;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
|
||||||
|
fn part1() {
|
||||||
|
let input = std::fs::read_to_string("input/day22.txt").unwrap();
|
||||||
|
assert_eq!(7545, task1(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2() {
|
||||||
|
let input = std::fs::read_to_string("input/day22.txt").unwrap();
|
||||||
|
assert_eq!(2019, task2(input, 10007, 7545, 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,5 +16,6 @@ pub mod day16;
|
|||||||
pub mod day17;
|
pub mod day17;
|
||||||
pub mod day18;
|
pub mod day18;
|
||||||
pub mod day21;
|
pub mod day21;
|
||||||
|
#[allow(dead_code)]
|
||||||
pub mod day22;
|
pub mod day22;
|
||||||
pub mod day24;
|
pub mod day24;
|
||||||
|
|||||||
Reference in New Issue
Block a user