Skip to content

Commit b9f529c

Browse files
committed
Add day 23
1 parent 245daae commit b9f529c

File tree

6 files changed

+120
-0
lines changed

6 files changed

+120
-0
lines changed

Day23_input.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
916438275

day23a/Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "day23a"
3+
version = "0.1.0"
4+
authors = ["Linus Kardell <[email protected]>"]
5+
edition = "2018"
6+
7+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
9+
[dependencies]

day23a/src/main.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use std::io::Read;
2+
3+
fn main() {
4+
let mut input = String::new();
5+
std::io::stdin().read_to_string(&mut input).unwrap();
6+
7+
let mut cups = u64::from_str_radix(input.trim(), 16).unwrap();
8+
let cup_count = input.trim().len();
9+
let pick_up_mask = (0..cup_count - 4).fold(0, |acc, n| acc | (0xF << n * 4));
10+
let keep_masks: Vec<_> = (0..cup_count).map(|i| {
11+
(0..i).fold(0, |acc, j| acc | 0xF << j * 4)
12+
}).collect();
13+
14+
for _ in 0..100 {
15+
let current_cup = cups >> (cup_count - 1) * 4;
16+
let removed_cups = cups >> (cup_count - 4) * 4 & 0xFFF;
17+
cups = current_cup << (cup_count - 4) * 4 | cups & pick_up_mask;
18+
let destination = (current_cup as usize - 1..current_cup as usize + cup_count - 1).rev().find_map(|cup| {
19+
let cup = cup % cup_count + 1;
20+
if let Some(pos) = (0..cup_count).find(|pos| cups >> pos * 4 & 0xF == cup as u64) {
21+
Some(pos)
22+
} else {
23+
None
24+
}
25+
}).unwrap();
26+
cups = cups & keep_masks[destination] |
27+
cups >> destination * 4 << (destination + 3) * 4 |
28+
removed_cups << destination * 4;
29+
cups = (cups & keep_masks[cup_count - 1]) << 4 | cups >> (cup_count - 1) * 4;
30+
}
31+
32+
while cups & 0xF != 1 {
33+
cups = (cups & 0xF) << (cup_count - 1) * 4 | cups >> 4;
34+
}
35+
36+
println!("{:X}", cups >> 4);
37+
}

day23a/testinput

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
389125467

day23b/Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "day23b"
3+
version = "0.1.0"
4+
authors = ["Linus Kardell <[email protected]>"]
5+
edition = "2018"
6+
7+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
9+
[dependencies]

day23b/src/main.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
use std::io::Read;
2+
3+
fn main() {
4+
let mut input = String::new();
5+
std::io::stdin().read_to_string(&mut input).unwrap();
6+
// Changing this to usize works, but more than doubles the runtime
7+
type ItemType = u32;
8+
const FULL_CUP_COUNT: ItemType = 1000000;
9+
10+
let initial_cups: Vec<_> = input.trim().chars().map(|digit| digit.to_digit(10).unwrap() as ItemType).collect();
11+
// Lookup table for the next cup after each cup
12+
let mut cups: Vec<_> = (0..FULL_CUP_COUNT + 1).map(|x| x + 1).collect();
13+
let mut current_cup = initial_cups[0];
14+
*cups.last_mut().unwrap() = current_cup;
15+
for (i, &cup) in initial_cups.iter().enumerate() {
16+
cups[cup as usize] = if i == initial_cups.len() - 1 {
17+
if FULL_CUP_COUNT as usize > initial_cups.len() {
18+
(initial_cups.len() + 1) as ItemType
19+
} else {
20+
current_cup
21+
}
22+
} else {
23+
initial_cups[i + 1]
24+
}
25+
}
26+
27+
for _ in 0..10000000 {
28+
let first_removed = cups[current_cup as usize];
29+
let last_removed = (0..2).fold(first_removed, |acc, _| cups[acc as usize]);
30+
cups[current_cup as usize] = cups[last_removed as usize];
31+
32+
let destination = (current_cup - 1..current_cup + FULL_CUP_COUNT - 1).rev().find_map(|i| {
33+
let cup = i % FULL_CUP_COUNT + 1;
34+
if (0..3).try_fold(first_removed, |acc, _| {
35+
if cup == acc {
36+
Err(())
37+
} else {
38+
Ok(cups[acc as usize])
39+
}
40+
}).is_ok() {
41+
Some(cup)
42+
} else {
43+
None
44+
}
45+
}).unwrap();
46+
cups[last_removed as usize] = cups[destination as usize];
47+
cups[destination as usize] = first_removed;
48+
current_cup = cups[current_cup as usize];
49+
}
50+
51+
// For part 1
52+
// (0..FULL_CUP_COUNT - 1).fold(1, |acc, _| {
53+
// let next = cups[acc as usize];
54+
// print!("{}", next);
55+
// next
56+
// });
57+
// println!("");
58+
59+
println!("{}", (0..2).fold((1, 1), |(cup, product), _| {
60+
let next = cups[cup as usize];
61+
(next, product * next as u64)
62+
}).1);
63+
}

0 commit comments

Comments
 (0)