Skip to content

Commit f9bc617

Browse files
committed
2024-03 Rust
1 parent 6cf0073 commit f9bc617

File tree

8 files changed

+113
-7
lines changed

8 files changed

+113
-7
lines changed

ReadMe.md

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
| Year-Day | Task | Scala | Rust | Others |
88
|----------|:-------------------------------------------------------------------------------|:-----------------------------------------------------------------------:|:----------------------------------------------:|:----------------------------------------------------------------------:|
9+
| 2024-03 | [Mull It Over](https://adventofcode.com/2024/day/3) | [Scala](scala2/src/main/scala/jurisk/adventofcode/y2024/Advent03.scala) | [Rust](rust/y2024/src/bin/solution_2024_03.rs) | |
910
| 2024-02 | [Red-Nosed Reports](https://adventofcode.com/2024/day/2) | [Scala](scala2/src/main/scala/jurisk/adventofcode/y2024/Advent02.scala) | [Rust](rust/y2024/src/bin/solution_2024_02.rs) | |
1011
| 2024-01 | [Historian Hysteria](https://adventofcode.com/2024/day/1) | [Scala](scala2/src/main/scala/jurisk/adventofcode/y2024/Advent01.scala) | [Rust](rust/y2024/src/bin/solution_2024_01.rs) | |
1112
| 2023-01 | [Trebuchet?!](https://adventofcode.com/2023/day/1) | [Scala](scala2/src/main/scala/jurisk/adventofcode/y2023/Advent01.scala) | [Rust](rust/y2023/src/bin/solution_2023_01.rs) | |

rust/Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/y2024/Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ workspace = true
1111

1212
[dependencies]
1313
advent-of-code-common = { path = "../common" }
14-
itertools.workspace = true
14+
itertools.workspace = true
15+
regex.workspace = true

rust/y2024/resources/03-test-00.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))

rust/y2024/resources/03-test-01.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))

rust/y2024/resources/03.txt

+6
Large diffs are not rendered by default.

rust/y2024/src/bin/solution_2024_02.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,11 @@ fn valid_diffs_1(row: &[N], range: &RangeInclusive<N>) -> bool {
3030
#[allow(dead_code)]
3131
fn valid_diffs_2_straightforward(row: &[N], range: &RangeInclusive<N>) -> bool {
3232
valid_diffs_1(row, range)
33-
|| (0 .. row.len())
34-
.any(|idx| {
35-
let mut row = row.to_vec();
36-
row.remove(idx);
37-
valid_diffs_1(row.as_slice(), range)
38-
})
33+
|| (0 .. row.len()).any(|idx| {
34+
let mut row = row.to_vec();
35+
row.remove(idx);
36+
valid_diffs_1(row.as_slice(), range)
37+
})
3938
}
4039

4140
fn valid_diffs_2_dp(row: &[N], range: &RangeInclusive<N>) -> bool {
+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
const DATA: &str = include_str!("../../resources/03.txt");
2+
3+
type R = usize;
4+
type Data = &'static str;
5+
6+
use regex::Regex;
7+
8+
const MUL: &str = r"mul\((\d+),(\d+)\)";
9+
const DO: &str = r"do()";
10+
const DONT: &str = r"don't()";
11+
12+
fn to_regex(s: &str) -> String {
13+
s.replace('(', r"\(").replace(')', r"\)")
14+
}
15+
16+
fn solve(data: &Data, regex: &str) -> Result<R, String> {
17+
let regex = Regex::new(regex).map_err(|err| format!("Error compiling regex: {err}"))?;
18+
19+
let mul = Regex::new(MUL).map_err(|err| format!("Error compiling regex: {err}"))?;
20+
21+
let mut active = true;
22+
let mut result = 0;
23+
24+
for s in regex.find_iter(data).map(|m| m.as_str()) {
25+
if s == DO {
26+
active = true;
27+
} else if s == DONT {
28+
active = false;
29+
} else if let Some(captures) = mul.captures(s) {
30+
if active {
31+
let c_1 = captures.get(1).ok_or(format!("Invalid capture: {s}"))?;
32+
let a = c_1
33+
.as_str()
34+
.parse::<usize>()
35+
.map_err(|err| format!("Failed to parse: {err}"))?;
36+
let c_2 = captures.get(2).ok_or(format!("Invalid capture: {s}"))?;
37+
let b = c_2
38+
.as_str()
39+
.parse::<usize>()
40+
.map_err(|err| format!("Failed to parse: {err}"))?;
41+
result += a * b;
42+
}
43+
} else {
44+
return Err(format!("Invalid operation: {s}"));
45+
}
46+
}
47+
48+
Ok(result)
49+
}
50+
51+
fn solve_1(data: &Data) -> Result<R, String> {
52+
solve(data, MUL)
53+
}
54+
55+
fn solve_2(data: &Data) -> Result<R, String> {
56+
let regex = [MUL.to_string(), to_regex(DO), to_regex(DONT)].join("|");
57+
solve(data, regex.as_str())
58+
}
59+
60+
fn main() -> Result<(), String> {
61+
let result_1 = solve_1(&DATA)?;
62+
println!("Part 1: {result_1}");
63+
64+
let result_2 = solve_2(&DATA)?;
65+
println!("Part 2: {result_2}");
66+
67+
Ok(())
68+
}
69+
70+
#[cfg(test)]
71+
mod tests {
72+
use super::*;
73+
74+
const TEST_DATA_0: &str = include_str!("../../resources/03-test-00.txt");
75+
const TEST_DATA_1: &str = include_str!("../../resources/03-test-01.txt");
76+
77+
#[test]
78+
fn test_solve_1_test() {
79+
assert_eq!(solve_1(&TEST_DATA_0), Ok(2 * 4 + 5 * 5 + 11 * 8 + 8 * 5));
80+
}
81+
82+
#[test]
83+
fn test_solve_1_real() {
84+
assert_eq!(solve_1(&DATA), Ok(187_825_547));
85+
}
86+
87+
#[test]
88+
fn test_solve_2_test() {
89+
assert_eq!(solve_2(&TEST_DATA_1), Ok(2 * 4 + 8 * 5));
90+
}
91+
92+
#[test]
93+
fn test_solve_2_real() {
94+
assert_eq!(solve_2(&DATA), Ok(85_508_223));
95+
}
96+
}

0 commit comments

Comments
 (0)