Skip to content

Commit e419b85

Browse files
committed
Add horible first implementation
1 parent ab9602e commit e419b85

File tree

4 files changed

+160
-2
lines changed

4 files changed

+160
-2
lines changed

benches/bench_days.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,4 @@ macro_rules! benches {
3838
};
3939
}
4040

41-
benches!(8);
41+
benches!(9);

src/day9.rs

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
use aoc_runner_derive::aoc;
2+
3+
#[cfg(not(test))]
4+
const INPUT_SIZE: usize = 19999;
5+
#[cfg(test)]
6+
const INPUT_SIZE: usize = 19;
7+
8+
// Assume a avrage of 5
9+
const MAX_BLOCKS_SIZE: usize = INPUT_SIZE * 5;
10+
11+
#[aoc(day9, part1)]
12+
pub fn part1(s: &str) -> u64 {
13+
#[expect(unused_unsafe)]
14+
unsafe {
15+
part1_inner(s)
16+
}
17+
}
18+
19+
fn part1_inner(s: &str) -> u64 {
20+
let input_map = s
21+
.as_bytes()
22+
.strip_suffix(&[b'\n'])
23+
.unwrap_or_else(|| s.as_bytes());
24+
25+
// All blocks with their id, and empty space
26+
let mut full_input_blocks: [u32; MAX_BLOCKS_SIZE] = [0; MAX_BLOCKS_SIZE];
27+
// Like full but without empty space
28+
let mut input_blocks: [u32; MAX_BLOCKS_SIZE / 2] = [0; MAX_BLOCKS_SIZE / 2];
29+
30+
let mut block_id = 0;
31+
let mut full_input_blocks_i: usize = 0;
32+
let mut input_blocks_i: usize = 0;
33+
34+
for c in input_map.chunks(2) {
35+
let block_size = (c[0] - b'0') as usize;
36+
37+
full_input_blocks[full_input_blocks_i..full_input_blocks_i + block_size].fill(block_id);
38+
input_blocks[input_blocks_i..input_blocks_i + block_size].fill(block_id);
39+
40+
full_input_blocks_i += block_size;
41+
input_blocks_i += block_size;
42+
43+
if c.len() == 2 {
44+
let empty_size = (c[1] - b'0') as usize;
45+
full_input_blocks_i += empty_size;
46+
}
47+
48+
block_id += 1;
49+
}
50+
51+
let full_size = full_input_blocks_i;
52+
let empty_space = full_size - input_blocks_i;
53+
let mut full_input_blocks_i: usize = (input_map[0] - b'0') as usize;
54+
55+
for i in (input_blocks_i - empty_space - 1..input_blocks_i).rev() {
56+
full_input_blocks[full_input_blocks_i] = input_blocks[i];
57+
while full_input_blocks[full_input_blocks_i] != 0 {
58+
full_input_blocks_i += 1;
59+
}
60+
}
61+
62+
full_input_blocks[..full_size - empty_space]
63+
.iter()
64+
.enumerate()
65+
.map(|(i, id)| i as u64 * *id as u64)
66+
.sum()
67+
}
68+
69+
#[aoc(day9, part2)]
70+
pub fn part2(s: &str) -> u64 {
71+
#[expect(unused_unsafe)]
72+
unsafe {
73+
part2_inner(s)
74+
}
75+
}
76+
77+
fn part2_inner(s: &str) -> u64 {
78+
let input_map = s
79+
.as_bytes()
80+
.strip_suffix(&[b'\n'])
81+
.unwrap_or_else(|| s.as_bytes());
82+
83+
// All blocks with their id, and empty space
84+
let mut full_input_blocks: [u32; MAX_BLOCKS_SIZE] = [0; MAX_BLOCKS_SIZE];
85+
// Like full but without empty space
86+
let mut input_blocks: [(usize, u32); INPUT_SIZE / 2 + 1] = [(0, 0); INPUT_SIZE / 2 + 1];
87+
88+
let mut block_id = 0;
89+
let mut full_input_blocks_i: usize = 0;
90+
let mut input_blocks_i: usize = 0;
91+
92+
for c in input_map.chunks(2) {
93+
let block_size = (c[0] - b'0') as usize;
94+
95+
full_input_blocks[full_input_blocks_i..full_input_blocks_i + block_size].fill(block_id);
96+
97+
input_blocks[input_blocks_i] = (full_input_blocks_i, block_size as u32);
98+
99+
full_input_blocks_i += block_size;
100+
input_blocks_i += 1;
101+
102+
if c.len() == 2 {
103+
let empty_size = (c[1] - b'0') as usize;
104+
full_input_blocks_i += empty_size;
105+
}
106+
107+
block_id += 1;
108+
}
109+
110+
let full_input_blocks_start: usize = (input_map[0] - b'0') as usize;
111+
112+
for block_id in (1..input_blocks_i).rev() {
113+
let (position, size) = input_blocks[block_id];
114+
115+
let mut i = full_input_blocks_start;
116+
let mut search_size = 0;
117+
while i < position {
118+
if full_input_blocks[i as usize] == 0 {
119+
search_size += 1;
120+
if search_size == size {
121+
full_input_blocks[position..position + size as usize].fill(0);
122+
full_input_blocks[i - size as usize + 1..i + 1].fill(block_id as u32);
123+
break;
124+
}
125+
} else {
126+
search_size = 0;
127+
}
128+
i += 1;
129+
}
130+
}
131+
132+
full_input_blocks
133+
.iter()
134+
.enumerate()
135+
.map(|(i, id)| i as u64 * *id as u64)
136+
.sum()
137+
}
138+
139+
#[cfg(test)]
140+
mod tests {
141+
use super::*;
142+
143+
const EXAMPLE: &str = "2333133121414131402\n";
144+
// const EXAMPLE: &str = "12345\n";
145+
146+
#[test]
147+
fn example_part1() {
148+
assert_eq!(part1(EXAMPLE), 1928);
149+
}
150+
151+
#[test]
152+
fn example_part2() {
153+
assert_eq!(part2(EXAMPLE), 2858);
154+
}
155+
}

src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use aoc_runner_derive::aoc_lib;
22

3+
mod memchr_inv;
4+
35
pub mod day1;
46
pub mod day2;
57
pub mod day3;
@@ -8,6 +10,6 @@ pub mod day5;
810
pub mod day6;
911
pub mod day7;
1012
pub mod day8;
11-
mod memchr_inv;
13+
pub mod day9;
1214

1315
aoc_lib! { year = 2024 }

tests/test_days.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,5 @@ benches!(
4141
6 => ("4988", "1697"),
4242
7 => ("538191549061", "34612812972206"),
4343
8 => ("394", "1277"),
44+
9 => ("6283170117911", "6307653242596"),
4445
);

0 commit comments

Comments
 (0)