- commit
- 791c7e1cb91b5745f234173dfb46eff7edb7d703
- parent
- 4014abd9f483824f746823514973eb85f3072fef
- Author
- Tobias Bengfort <tobias.bengfort@posteo.de>
- Date
- 2021-12-21 09:26
day 21
Diffstat
A | 2021/21/input.txt | 2 | ++ |
A | 2021/21/part1.rs | 57 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | 2021/21/part2.rs | 111 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | 2021/21/test.txt | 2 | ++ |
4 files changed, 172 insertions, 0 deletions
diff --git a/2021/21/input.txt b/2021/21/input.txt
@@ -0,0 +1,2 @@ -1 1 Player 1 starting position: 9 -1 2 Player 2 starting position: 3
diff --git a/2021/21/part1.rs b/2021/21/part1.rs
@@ -0,0 +1,57 @@ -1 1 use std::env::args; -1 2 use std::fs::File; -1 3 use std::io::BufRead; -1 4 use std::io::BufReader; -1 5 -1 6 fn get_data() -> (u64, u64) { -1 7 let path = args().nth(1).unwrap(); -1 8 let file = File::open(path).unwrap(); -1 9 -1 10 let mut state = 0; -1 11 let mut player1 = 0; -1 12 let mut player2 = 0; -1 13 -1 14 for line in BufReader::new(file).lines() { -1 15 match state { -1 16 0 => { -1 17 player1 = line.unwrap()[28..].parse::<u64>().unwrap(); -1 18 state = 1; -1 19 }, -1 20 1 => { -1 21 player2 = line.unwrap()[28..].parse::<u64>().unwrap(); -1 22 state = 2; -1 23 }, -1 24 _ => unreachable!(), -1 25 } -1 26 } -1 27 -1 28 return (player1, player2); -1 29 } -1 30 -1 31 fn main() { -1 32 let (mut player1, mut player2) = get_data(); -1 33 -1 34 let mut die: u64 = 0; -1 35 let mut score1: u64 = 0; -1 36 let mut score2: u64 = 0; -1 37 -1 38 loop { -1 39 let d1 = 3 * (die % 100) + 6; -1 40 player1 = (player1 + d1 - 1) % 10 + 1; -1 41 score1 += player1; -1 42 die += 3; -1 43 if score1 >= 1000 { -1 44 println!("{}", score2 * die); -1 45 break; -1 46 } -1 47 -1 48 let d2 = 3 * (die % 100) + 6; -1 49 player2 = (player2 + d2 - 1) % 10 + 1; -1 50 score2 += player2; -1 51 die += 3; -1 52 if score2 >= 1000 { -1 53 println!("{}", score1 * die); -1 54 break; -1 55 } -1 56 } -1 57 }
diff --git a/2021/21/part2.rs b/2021/21/part2.rs
@@ -0,0 +1,111 @@ -1 1 use std::env::args; -1 2 use std::fs::File; -1 3 use std::io::BufRead; -1 4 use std::io::BufReader; -1 5 -1 6 const TURNS: usize = 11; -1 7 -1 8 fn get_data() -> (usize, usize) { -1 9 let path = args().nth(1).unwrap(); -1 10 let file = File::open(path).unwrap(); -1 11 -1 12 let mut state = 0; -1 13 let mut player1 = 0; -1 14 let mut player2 = 0; -1 15 -1 16 for line in BufReader::new(file).lines() { -1 17 match state { -1 18 0 => { -1 19 player1 = line.unwrap()[28..].parse::<usize>().unwrap(); -1 20 state = 1; -1 21 }, -1 22 1 => { -1 23 player2 = line.unwrap()[28..].parse::<usize>().unwrap(); -1 24 state = 2; -1 25 }, -1 26 _ => unreachable!(), -1 27 } -1 28 } -1 29 -1 30 return (player1 - 1, player2 - 1); -1 31 } -1 32 -1 33 fn index(turn: usize, score: usize, position: usize) -> usize { -1 34 assert!(turn < TURNS); -1 35 assert!(score < 21); -1 36 assert!(position < 10); -1 37 -1 38 return turn + score * TURNS + position * TURNS * 21; -1 39 } -1 40 -1 41 fn main() { -1 42 let (player1, player2) = get_data(); -1 43 -1 44 let mut counts1 = [0u64; TURNS * 21 * 10]; -1 45 let mut counts2 = [0u64; TURNS * 21 * 10]; -1 46 let mut finishes1 = [0u64; TURNS]; -1 47 let mut finishes2 = [0u64; TURNS]; -1 48 -1 49 counts1[index(0, 0, player1)] += 1; -1 50 counts2[index(0, 0, player2)] += 1; -1 51 -1 52 for turn in 1..TURNS { -1 53 for score in 0..21 { -1 54 for position in 0..10 { -1 55 if score > position { -1 56 let i = index(turn, score, position); -1 57 let old_score = score - (position + 1); -1 58 for a in [1, 2, 3].iter() { -1 59 for b in [1, 2, 3].iter() { -1 60 for c in [1, 2, 3].iter() { -1 61 let old_position = (position + 10 - (a + b + c)) % 10; -1 62 let j = index(turn - 1, old_score, old_position); -1 63 counts1[i] += counts1[j]; -1 64 counts2[i] += counts2[j]; -1 65 } -1 66 } -1 67 } -1 68 } -1 69 } -1 70 } -1 71 -1 72 for position in 0..10 { -1 73 for old_score in (21 - (position + 1))..21 { -1 74 for a in [1, 2, 3].iter() { -1 75 for b in [1, 2, 3].iter() { -1 76 for c in [1, 2, 3].iter() { -1 77 let old_position = (position + 10 - (a + b + c)) % 10; -1 78 let j = index(turn - 1, old_score, old_position); -1 79 finishes1[turn] += counts1[j]; -1 80 finishes2[turn] += counts2[j]; -1 81 } -1 82 } -1 83 } -1 84 } -1 85 } -1 86 } -1 87 -1 88 // the two players can play their games independently and just -1 89 // multiply their universes in the end -1 90 let mut open1: u64 = 1; -1 91 let mut wins1: u64 = 0; -1 92 -1 93 let mut open2: u64 = 1; -1 94 let mut wins2: u64 = 0; -1 95 -1 96 for turn in 1..TURNS { -1 97 open1 *= 27; -1 98 open1 -= finishes1[turn]; -1 99 wins1 += finishes1[turn] * open2; -1 100 -1 101 open2 *= 27; -1 102 open2 -= finishes2[turn]; -1 103 wins2 += finishes2[turn] * open1; -1 104 } -1 105 -1 106 if wins1 > wins2 { -1 107 println!("{}", wins1); -1 108 } else { -1 109 println!("{}", wins2); -1 110 } -1 111 }
diff --git a/2021/21/test.txt b/2021/21/test.txt
@@ -0,0 +1,2 @@ -1 1 Player 1 starting position: 4 -1 2 Player 2 starting position: 8