Skip to content

Commit 3311e3d

Browse files
committed
Add day 22
1 parent 8d226e0 commit 3311e3d

File tree

5 files changed

+204
-4
lines changed

5 files changed

+204
-4
lines changed

benches/bench_days.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,4 @@ macro_rules! benches {
4848
};
4949
}
5050

51-
benches!(21);
51+
benches!(22);

build.rs

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,16 +194,16 @@ fn press_number2(from_pos: Pos, to_pos: Pos, cache: &mut HashMap<(Pos, Pos, u32)
194194
}
195195
}
196196

197+
#[allow(unused)]
197198
fn part2_inner(a: usize, b: usize, c: usize, cache: &mut HashMap<(Pos, Pos, u32), u64>) -> u64 {
198199
press_number2(keypad_pos(10), keypad_pos(a), cache)
199200
+ press_number2(keypad_pos(a), keypad_pos(b), cache)
200201
+ press_number2(keypad_pos(b), keypad_pos(c), cache)
201202
+ press_number2(keypad_pos(c), keypad_pos(10), cache)
202203
}
203204

204-
fn main() {
205-
println!("cargo::rerun-if-changed=build.rs");
206-
205+
#[allow(unused)]
206+
fn write_day21() {
207207
let mut lut = [0u64; 10usize.pow(3)];
208208

209209
let mut cache = HashMap::new();
@@ -224,3 +224,35 @@ fn main() {
224224

225225
file.write_all(&lut).unwrap();
226226
}
227+
228+
// fn write_day22() {
229+
// const MAX: u32 = 16777216;
230+
231+
// let mut lut = Vec::with_capacity(MAX as usize);
232+
233+
// for i in 0..MAX {
234+
// let mut sn = i as u32;
235+
// for _ in 0..2000 {
236+
// sn = ((i * 64) % MAX) ^ i;
237+
// sn = (sn / 32) ^ sn;
238+
// sn = ((sn * 2048) % MAX) ^ sn;
239+
// }
240+
241+
// lut[i as usize] = sn;
242+
// }
243+
244+
// let mut path = PathBuf::from(std::env::var("OUT_DIR").unwrap());
245+
// path.push("day22.bin");
246+
// let mut file = File::create(path).unwrap();
247+
248+
// let lut: [u8; 4 * MAX as usize] = unsafe { transmute(lut) };
249+
250+
// file.write_all(&lut).unwrap();
251+
// }
252+
253+
fn main() {
254+
println!("cargo::rerun-if-changed=build.rs");
255+
256+
// write_day21();
257+
// write_day22();
258+
}

src/day22.rs

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
use core::str;
2+
3+
use aoc_runner_derive::aoc;
4+
use bitvec::array::BitArray;
5+
6+
const MAX: u32 = 16777216;
7+
8+
// static LUT_P1: [u32; MAX as usize] =
9+
// unsafe { transmute(*include_bytes!(concat!(env!("OUT_DIR"), "/day22.bin"))) };
10+
11+
#[aoc(day22, part1)]
12+
pub fn part1(s: &str) -> u64 {
13+
let s = s.as_bytes();
14+
15+
let mut sum = 0;
16+
let mut i = 0;
17+
unsafe {
18+
while i < s.len() {
19+
#[cfg(not(test))]
20+
let mut sn = (*s.get_unchecked(i + 0) as u32) * 100000
21+
+ (*s.get_unchecked(i + 1) as u32) * 10000
22+
+ (*s.get_unchecked(i + 2) as u32) * 1000
23+
+ (*s.get_unchecked(i + 3) as u32) * 100
24+
+ (*s.get_unchecked(i + 4) as u32) * 10
25+
+ (*s.get_unchecked(i + 5) as u32) * 1
26+
- (b'0' as u32 * 111_111);
27+
#[cfg(not(test))]
28+
{
29+
i += 6;
30+
}
31+
32+
#[cfg(test)]
33+
let mut sn = 0;
34+
while *s.get_unchecked(i) != b'\n' {
35+
sn *= 10;
36+
sn += (s.get_unchecked(i) - b'0') as u32;
37+
i += 1;
38+
}
39+
i += 1;
40+
41+
for _ in 0..2000 {
42+
sn = ((sn as u64 * 64) % MAX as u64) as u32 ^ sn;
43+
sn = (sn / 32) ^ sn;
44+
sn = ((sn as u64 * 2048) % MAX as u64) as u32 ^ sn;
45+
}
46+
47+
sum += sn as u64;
48+
}
49+
}
50+
51+
sum
52+
}
53+
54+
const SEQUENCES: usize = 18 << 15 | 18 << 10 | 18 << 5 | 18;
55+
56+
#[aoc(day22, part2)]
57+
pub fn part2(s: &str) -> i16 {
58+
let s = s.as_bytes();
59+
60+
let mut sequences = [0; SEQUENCES];
61+
let mut done = BitArray::<[usize; SEQUENCES.div_ceil(usize::BITS as usize)]>::default();
62+
63+
let mut current_best = 0;
64+
65+
let mut i = 0;
66+
unsafe {
67+
while i < s.len() {
68+
#[cfg(not(test))]
69+
let mut sn = (*s.get_unchecked(i + 0) as u32) * 100000
70+
+ (*s.get_unchecked(i + 1) as u32) * 10000
71+
+ (*s.get_unchecked(i + 2) as u32) * 1000
72+
+ (*s.get_unchecked(i + 3) as u32) * 100
73+
+ (*s.get_unchecked(i + 4) as u32) * 10
74+
+ (*s.get_unchecked(i + 5) as u32) * 1
75+
- (b'0' as u32 * 111_111);
76+
#[cfg(not(test))]
77+
{
78+
i += 6;
79+
}
80+
81+
#[cfg(test)]
82+
let mut sn = 0;
83+
while *s.get_unchecked(i) != b'\n' {
84+
sn *= 10;
85+
sn += (s.get_unchecked(i) - b'0') as u32;
86+
i += 1;
87+
}
88+
i += 1;
89+
90+
let mut diffs = 0;
91+
let mut prev = sn % 10;
92+
for _ in 0..3 {
93+
sn = ((sn as u64 * 64) % MAX as u64) as u32 ^ sn;
94+
sn = (sn / 32) ^ sn;
95+
sn = ((sn as u64 * 2048) % MAX as u64) as u32 ^ sn;
96+
let price = sn % 10;
97+
let diff = price + 9 - prev;
98+
diffs = (diffs << 5) | diff;
99+
100+
prev = price;
101+
}
102+
103+
for _ in 4..2000 {
104+
sn = ((sn as u64 * 64) % MAX as u64) as u32 ^ sn;
105+
sn = (sn / 32) ^ sn;
106+
sn = ((sn as u64 * 2048) % MAX as u64) as u32 ^ sn;
107+
let price = sn % 10;
108+
let diff = price + 9 - prev;
109+
diffs = ((diffs << 5) | diff) & 0xFFFFF;
110+
111+
if !done[diffs as usize] {
112+
sequences[diffs as usize] += price as i16;
113+
if current_best < sequences[diffs as usize] {
114+
current_best = sequences[diffs as usize];
115+
}
116+
done.set(diffs as usize, true);
117+
}
118+
119+
prev = price;
120+
}
121+
done.fill(false);
122+
}
123+
// println!(
124+
// "{},{},{},{}",
125+
// (((current_best_i >> 15) & 0x1F) as i16) - 9,
126+
// (((current_best_i >> 10) & 0x1F) as i16) - 9,
127+
// (((current_best_i >> 05) & 0x1F) as i16) - 9,
128+
// (((current_best_i >> 00) & 0x1F) as i16) - 9,
129+
// );
130+
// println!("{}\n", sequences[current_best_i as usize]);
131+
132+
// println!(
133+
// "{}",
134+
// sequences[((-2 + 9) << 15 | (1 + 9) << 10 | (-1 + 9) << 05 | (3 + 9) << 00) as usize]
135+
// );
136+
}
137+
138+
current_best
139+
}
140+
141+
#[cfg(test)]
142+
mod test {
143+
use super::*;
144+
145+
#[test]
146+
fn example_part1() {
147+
let s = r"1
148+
10
149+
100
150+
2024
151+
";
152+
153+
assert_eq!(part1(s), 37327623);
154+
}
155+
156+
#[test]
157+
fn example_part2() {
158+
let s = r"1
159+
2
160+
3
161+
2024
162+
";
163+
164+
assert_eq!(part2(s), 23);
165+
}
166+
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ pub mod day19;
1616
pub mod day2;
1717
pub mod day20;
1818
pub mod day21;
19+
pub mod day22;
1920
pub mod day3;
2021
pub mod day4;
2122
pub mod day5;

tests/test_days.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,5 @@ benches!(
5656
19 => ("267", "796449099271652"),
5757
20 => ("1511", "1020507"),
5858
21 => ("188398", "230049027535970"),
59+
22 => ("20068964552", "2246"),
5960
);

0 commit comments

Comments
 (0)