Skip to content

Commit

Permalink
add day3
Browse files Browse the repository at this point in the history
  • Loading branch information
mirsella committed Dec 3, 2024
1 parent ae0b249 commit b428a21
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 1 deletion.
2 changes: 1 addition & 1 deletion 2024/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ resolver = "2"
members = [
"day1",
"day2",
# "day3",
"day3",
# "day4",
# "day5",
# "day6",
Expand Down
19 changes: 19 additions & 0 deletions 2024/day3/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
input.txt
flamegraph.svg
perf.data*
### Rust
# Generated by Cargo
# will have compiled files and executables
debug/
target/

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk

# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb

12 changes: 12 additions & 0 deletions 2024/day3/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "day3"
authors = ["mirsella <[email protected]>"]
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
itertools = "0.13.0"
regex = "1.11.1"

28 changes: 28 additions & 0 deletions 2024/day3/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use std::fs::File;
use std::io::{self, Read};
use std::path::PathBuf;
use std::{env, fs};

fn replace_in_file(file_path: &PathBuf, old: &str, new: &str) -> io::Result<()> {
let mut contents = String::new();
File::open(file_path)?.read_to_string(&mut contents)?;
let new_contents = contents.replace(old, new);
if contents != new_contents {
println!("Updating {}", file_path.display());
fs::write(file_path, new_contents)?;
}
Ok(())
}

fn main() -> io::Result<()> {
let pkg_name = env::var("CARGO_PKG_NAME").unwrap();
replace_in_file(
&"../Cargo.toml".into(),
&format!("# \"{pkg_name}\""),
&format!("\"{pkg_name}\""),
)?;

replace_in_file(&"./Cargo.toml".into(), "\n[workspace]", "")?;

Ok(())
}
57 changes: 57 additions & 0 deletions 2024/day3/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use itertools::Itertools;
use regex::Regex;

fn part1(input: &str) -> usize {
let regex = Regex::new(r"mul\((\d+),(\d+)\)").unwrap();
regex
.captures_iter(input)
.map(|c| {
c.extract::<2>()
.1
.into_iter()
.map(|s| s.parse::<usize>().unwrap())
.fold(0, |acc, v| if acc == 0 { v } else { acc * v })
})
.sum()
}
fn part2(input: &str) -> usize {
let regex = Regex::new(r"(mul\((\d+),(\d+)\)|don't\(\)|do\(\))").unwrap();
let mut acc = 0usize;
let mut enabled = true;
for capture in regex.captures_iter(input) {
let full = capture.get(0).unwrap().as_str();
if full == "don't()" {
enabled = false
} else if full == "do()" {
enabled = true
} else if full.starts_with("mul") {
if enabled {
acc += capture.get(2).unwrap().as_str().parse::<usize>().unwrap()
* capture.get(3).unwrap().as_str().parse::<usize>().unwrap()
}
} else {
unreachable!();
}
}
acc
}
fn main() {
let input = include_str!("../input.txt");
println!("Part 1: {}", part1(input));
println!("Part 2: {}", part2(input));
}

#[cfg(test)]
mod tests {
const INPUT: &str = "xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))";
#[test]
fn part1() {
assert_eq!(super::part1(INPUT), 161);
}
const INPUT2: &str =
"xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))";
#[test]
fn part2() {
assert_eq!(super::part2(INPUT2), 48);
}
}

0 comments on commit b428a21

Please sign in to comment.