+79
-1
2025/src/days/one/mod.rs
+79
-1
2025/src/days/one/mod.rs
···
1
-
pub mod secret_entrance;
1
+
use atoi_simd::parse as parse_i32;
2
+
3
+
pub fn main() -> anyhow::Result<()> {
4
+
crate::run("Secret Entrance", "inputs/day1.txt", parse, part_a, part_b)
5
+
}
6
+
7
+
fn parse(input: &[u8]) -> Vec<i32> {
8
+
let mut out = Vec::with_capacity(input.iter().filter(|&b| *b == b'\n').count());
9
+
let mut start = 0;
10
+
11
+
while start < input.len() {
12
+
let end = match memchr::memchr(b'\n', &input[start..]) {
13
+
Some(index) => start + index,
14
+
None => input.len(),
15
+
};
16
+
let line = &input[start..end];
17
+
18
+
if !line.is_empty() {
19
+
let mut buf = [0u8; 4];
20
+
let mut len = 0usize;
21
+
let mut seen_digit = false;
22
+
23
+
for &b in line {
24
+
match b {
25
+
b'L' => {
26
+
if len == 0 {
27
+
buf[len] = b'-';
28
+
len += 1;
29
+
}
30
+
}
31
+
b'0'..=b'9' => {
32
+
seen_digit = true;
33
+
buf[len] = b;
34
+
len += 1;
35
+
}
36
+
_ => {
37
+
len = 0;
38
+
break;
39
+
}
40
+
}
41
+
}
42
+
if seen_digit && len > 0 {
43
+
if let Ok(num) = parse_i32(&buf[..len]) {
44
+
out.push(num);
45
+
}
46
+
}
47
+
}
48
+
49
+
start = end + 1;
50
+
}
51
+
52
+
out
53
+
}
54
+
55
+
fn part_a(input: Vec<i32>) -> usize {
56
+
input
57
+
.iter()
58
+
.scan(50, |state, &rotation| {
59
+
*state += rotation;
60
+
Some(*state)
61
+
})
62
+
.filter(|&state| state % 100 == 0)
63
+
.count()
64
+
}
65
+
66
+
fn part_b(input: Vec<i32>) -> usize {
67
+
input
68
+
.iter()
69
+
.scan(50, |state, &rotation| {
70
+
let mut passes = (rotation / 100).abs() as usize;
71
+
let turn = rotation % 100;
72
+
if *state + turn <= 0 && *state != 0 || 99 < *state + turn {
73
+
passes += 1;
74
+
}
75
+
*state = (*state + turn).rem_euclid(100);
76
+
Some(passes)
77
+
})
78
+
.sum()
79
+
}
-79
2025/src/days/one/secret_entrance.rs
-79
2025/src/days/one/secret_entrance.rs
···
1
-
use atoi_simd::parse as parse_i32;
2
-
3
-
pub fn main() -> anyhow::Result<()> {
4
-
crate::run("Secret Entrance", "inputs/day1.txt", parse, part_a, part_b)
5
-
}
6
-
7
-
fn parse(input: &[u8]) -> Vec<i32> {
8
-
let mut out = Vec::with_capacity(4503);
9
-
let mut start = 0;
10
-
11
-
while start < input.len() {
12
-
let end = match memchr::memchr(b'\n', &input[start..]) {
13
-
Some(index) => start + index,
14
-
None => input.len(),
15
-
};
16
-
let line = &input[start..end];
17
-
18
-
if !line.is_empty() {
19
-
let mut buf = [0u8; 4];
20
-
let mut len = 0usize;
21
-
let mut seen_digit = false;
22
-
23
-
for &b in line {
24
-
match b {
25
-
b'L' => {
26
-
if len == 0 {
27
-
buf[len] = b'-';
28
-
len += 1;
29
-
}
30
-
}
31
-
b'0'..=b'9' => {
32
-
seen_digit = true;
33
-
buf[len] = b;
34
-
len += 1;
35
-
}
36
-
_ => {
37
-
len = 0;
38
-
break;
39
-
}
40
-
}
41
-
}
42
-
if seen_digit && len > 0 {
43
-
if let Ok(num) = parse_i32(&buf[..len]) {
44
-
out.push(num);
45
-
}
46
-
}
47
-
}
48
-
49
-
start = end + 1;
50
-
}
51
-
52
-
out
53
-
}
54
-
55
-
fn part_a(input: Vec<i32>) -> usize {
56
-
input
57
-
.iter()
58
-
.scan(50, |state, &rotation| {
59
-
*state += rotation;
60
-
Some(*state)
61
-
})
62
-
.filter(|&state| state % 100 == 0)
63
-
.count()
64
-
}
65
-
66
-
fn part_b(input: Vec<i32>) -> usize {
67
-
input
68
-
.iter()
69
-
.scan(50, |state, &rotation| {
70
-
let mut passes = (rotation / 100).abs() as usize;
71
-
let turn = rotation % 100;
72
-
if *state + turn <= 0 && *state != 0 || 99 < *state + turn {
73
-
passes += 1;
74
-
}
75
-
*state = (*state + turn).rem_euclid(100);
76
-
Some(passes)
77
-
})
78
-
.sum()
79
-
}
+92
2025/src/days/two/mod.rs
+92
2025/src/days/two/mod.rs
···
1
+
use atoi_simd::parse as parse_u64;
2
+
3
+
pub fn main() -> anyhow::Result<()> {
4
+
crate::run("Gift Shop", "inputs/day2.txt", parse, part_a, part_b)
5
+
}
6
+
7
+
fn parse(input: &[u8]) -> Vec<u64> {
8
+
let mut out = Vec::new();
9
+
let mut start = 0;
10
+
11
+
while start < input.len() {
12
+
let end = match memchr::memchr2(b',', b'\n', &input[start..]) {
13
+
Some(index) => start + index,
14
+
None => input.len(),
15
+
};
16
+
let range = &input[start..end];
17
+
18
+
let [min, max, ..] = range
19
+
.split(|&b| b == b'-')
20
+
.map(|s| parse_u64::<u64>(s).unwrap())
21
+
.collect::<Vec<_>>()[..]
22
+
else {
23
+
panic!("invalid input")
24
+
};
25
+
26
+
for i in min.clone()..=max.clone() {
27
+
out.push(i);
28
+
}
29
+
start += range.len() + 1;
30
+
}
31
+
32
+
out
33
+
}
34
+
35
+
fn part_a(input: Vec<u64>) -> usize {
36
+
println!("{}", input.len());
37
+
input.iter().fold(0, |acc, x| {
38
+
acc + if is_valid_id_a(x.clone()) {
39
+
0usize
40
+
} else {
41
+
*x as usize
42
+
}
43
+
})
44
+
}
45
+
46
+
fn is_valid_id_a(id: u64) -> bool {
47
+
// invalid ID's are identifiable due to them being made up from some sequences being repeated
48
+
// eg: 11 -> [1, 1] invalid
49
+
// eg: 123123 -> [123, 123] invalid
50
+
// eg: 123456 -> [123456] valid
51
+
let id_str = id.to_string();
52
+
let id_len = id_str.len();
53
+
54
+
let (left, right) = id_str.split_at(id_len / 2);
55
+
left != right
56
+
}
57
+
58
+
fn is_valid_id_b(id: &u64) -> bool {
59
+
// invalid ID's are identifiable due to them being made up from some sequences being repeated
60
+
// eg: 11 -> [1, 1] invalid
61
+
// eg: 123123 -> [123, 123] invalid
62
+
// eg: 121212 -> [12, 12, 12] invalid
63
+
// eg: 111 -> [1, 1, 1] invalid
64
+
// eg: 123456 -> [123456] valid
65
+
let id_str = id.to_string();
66
+
let id_len = id_str.len();
67
+
let mut needle = id_str.chars().next().unwrap().to_string();
68
+
69
+
while needle.len() != id_str.len() {
70
+
if id_len % needle.len() != 0 {
71
+
needle.push(id_str.chars().nth(needle.len()).unwrap());
72
+
continue;
73
+
};
74
+
let count = id_str.matches(&needle).count();
75
+
if count * needle.len() == id_len {
76
+
return false;
77
+
};
78
+
needle.push(id_str.chars().nth(needle.len()).unwrap());
79
+
}
80
+
81
+
true
82
+
}
83
+
84
+
fn part_b(input: Vec<u64>) -> usize {
85
+
input.iter().fold(0, |acc, x| {
86
+
acc + if is_valid_id_b(x) {
87
+
0usize
88
+
} else {
89
+
*x as usize
90
+
}
91
+
})
92
+
}
+7
-2
2025/src/main.rs
+7
-2
2025/src/main.rs
···
2
2
extern crate test;
3
3
4
4
fn main() -> anyhow::Result<()> {
5
-
aoc2025::days::one::secret_entrance::main()?;
5
+
aoc2025::days::two::main()?;
6
6
Ok(())
7
7
}
8
8
···
13
13
14
14
#[bench]
15
15
fn day1(b: &mut Bencher) {
16
-
b.iter(|| days::one::secret_entrance::main())
16
+
b.iter(|| days::one::main())
17
+
}
18
+
19
+
#[bench]
20
+
fn day2(b: &mut Bencher) {
21
+
b.iter(|| days::two::main())
17
22
}
18
23
}