Skip to content

Commit

Permalink
2024-03 Rust
Browse files Browse the repository at this point in the history
  • Loading branch information
jurisk committed Dec 3, 2024
1 parent 6cf0073 commit f9bc617
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 7 deletions.
1 change: 1 addition & 0 deletions ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

| Year-Day | Task | Scala | Rust | Others |
|----------|:-------------------------------------------------------------------------------|:-----------------------------------------------------------------------:|:----------------------------------------------:|:----------------------------------------------------------------------:|
| 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) | |
| 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) | |
| 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) | |
| 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) | |
Expand Down
1 change: 1 addition & 0 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion rust/y2024/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ workspace = true

[dependencies]
advent-of-code-common = { path = "../common" }
itertools.workspace = true
itertools.workspace = true
regex.workspace = true
1 change: 1 addition & 0 deletions rust/y2024/resources/03-test-00.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))
1 change: 1 addition & 0 deletions rust/y2024/resources/03-test-01.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))
6 changes: 6 additions & 0 deletions rust/y2024/resources/03.txt

Large diffs are not rendered by default.

11 changes: 5 additions & 6 deletions rust/y2024/src/bin/solution_2024_02.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,11 @@ fn valid_diffs_1(row: &[N], range: &RangeInclusive<N>) -> bool {
#[allow(dead_code)]
fn valid_diffs_2_straightforward(row: &[N], range: &RangeInclusive<N>) -> bool {
valid_diffs_1(row, range)
|| (0 .. row.len())
.any(|idx| {
let mut row = row.to_vec();
row.remove(idx);
valid_diffs_1(row.as_slice(), range)
})
|| (0 .. row.len()).any(|idx| {
let mut row = row.to_vec();
row.remove(idx);
valid_diffs_1(row.as_slice(), range)
})
}

fn valid_diffs_2_dp(row: &[N], range: &RangeInclusive<N>) -> bool {
Expand Down
96 changes: 96 additions & 0 deletions rust/y2024/src/bin/solution_2024_03.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
const DATA: &str = include_str!("../../resources/03.txt");

type R = usize;
type Data = &'static str;

use regex::Regex;

const MUL: &str = r"mul\((\d+),(\d+)\)";
const DO: &str = r"do()";
const DONT: &str = r"don't()";

fn to_regex(s: &str) -> String {
s.replace('(', r"\(").replace(')', r"\)")
}

fn solve(data: &Data, regex: &str) -> Result<R, String> {
let regex = Regex::new(regex).map_err(|err| format!("Error compiling regex: {err}"))?;

let mul = Regex::new(MUL).map_err(|err| format!("Error compiling regex: {err}"))?;

let mut active = true;
let mut result = 0;

for s in regex.find_iter(data).map(|m| m.as_str()) {
if s == DO {
active = true;
} else if s == DONT {
active = false;
} else if let Some(captures) = mul.captures(s) {
if active {
let c_1 = captures.get(1).ok_or(format!("Invalid capture: {s}"))?;
let a = c_1
.as_str()
.parse::<usize>()
.map_err(|err| format!("Failed to parse: {err}"))?;
let c_2 = captures.get(2).ok_or(format!("Invalid capture: {s}"))?;
let b = c_2
.as_str()
.parse::<usize>()
.map_err(|err| format!("Failed to parse: {err}"))?;
result += a * b;
}
} else {
return Err(format!("Invalid operation: {s}"));
}
}

Ok(result)
}

fn solve_1(data: &Data) -> Result<R, String> {
solve(data, MUL)
}

fn solve_2(data: &Data) -> Result<R, String> {
let regex = [MUL.to_string(), to_regex(DO), to_regex(DONT)].join("|");
solve(data, regex.as_str())
}

fn main() -> Result<(), String> {
let result_1 = solve_1(&DATA)?;
println!("Part 1: {result_1}");

let result_2 = solve_2(&DATA)?;
println!("Part 2: {result_2}");

Ok(())
}

#[cfg(test)]
mod tests {
use super::*;

const TEST_DATA_0: &str = include_str!("../../resources/03-test-00.txt");
const TEST_DATA_1: &str = include_str!("../../resources/03-test-01.txt");

#[test]
fn test_solve_1_test() {
assert_eq!(solve_1(&TEST_DATA_0), Ok(2 * 4 + 5 * 5 + 11 * 8 + 8 * 5));
}

#[test]
fn test_solve_1_real() {
assert_eq!(solve_1(&DATA), Ok(187_825_547));
}

#[test]
fn test_solve_2_test() {
assert_eq!(solve_2(&TEST_DATA_1), Ok(2 * 4 + 8 * 5));
}

#[test]
fn test_solve_2_real() {
assert_eq!(solve_2(&DATA), Ok(85_508_223));
}
}

0 comments on commit f9bc617

Please sign in to comment.