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