Skip to content

Commit

Permalink
feat: updates
Browse files Browse the repository at this point in the history
  • Loading branch information
tatupesonen committed Dec 4, 2024
1 parent cb8d28a commit 278fba0
Show file tree
Hide file tree
Showing 8 changed files with 425 additions and 93 deletions.
307 changes: 300 additions & 7 deletions aoc2024/Cargo.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions aoc2024/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ edition = "2021"
[dependencies]
clap = { version = "4.0.29", features = ["derive"] }
criterion = "0.3.6"
miette = { version = "7.4.0", features = ["fancy"] }
nom = "7.1.3"
owo-colors = { version = "3.5.0", features = ["supports-colors"] }
rstest = "0.16.0"
toml = "0.8.19"
45 changes: 23 additions & 22 deletions aoc2024/src/days/day01.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,33 @@ use std::collections::HashMap;

use crate::Solution;

fn parse_day1(input: &str) -> (Vec<i32>, Vec<i32>) {
let mut first = input
fn parse_day1(input: &str) -> miette::Result<(Vec<i32>, Vec<i32>)> {
let mut first: Vec<i32> = input
.lines()
.map(|line| {
line.split_whitespace()
.next()
.unwrap()
.ok_or_else(|| miette::miette!("Missing first value in line"))?
.parse::<i32>()
.unwrap()
.map_err(|e| miette::miette!("Failed to parse first value as i32: {}", e))
})
.collect::<Vec<i32>>();
.collect::<Result<Vec<_>, _>>()?;

let mut second = input
let mut second: Vec<i32> = input
.lines()
.map(|line| {
line.split_whitespace()
.nth(1)
.unwrap()
.ok_or_else(|| miette::miette!("Missing second value in line"))?
.parse::<i32>()
.unwrap()
.map_err(|e| miette::miette!("Failed to parse second value as i32: {}", e))
})
.collect::<Vec<i32>>();
.collect::<Result<Vec<_>, _>>()?;

first.sort();
second.sort();

(first, second)
Ok((first, second))
}

fn distance(it: (i32, i32)) -> i32 {
Expand All @@ -36,26 +37,26 @@ fn distance(it: (i32, i32)) -> i32 {

pub struct Problem;
impl Solution for Problem {
fn part_one(&self, input: &str) -> String {
let (first, second) = parse_day1(input);
Iterator::zip(first.into_iter(), second)
fn part_one(&self, input: &str) -> miette::Result<String> {
let (first, second) = parse_day1(input)?;
Ok(Iterator::zip(first.into_iter(), second)
.map(distance)
.sum::<i32>()
.to_string()
.to_string())
}

fn part_two(&self, input: &str) -> String {
let (first, second) = parse_day1(input);
fn part_two(&self, input: &str) -> miette::Result<String> {
let (first, second) = parse_day1(input)?;
let mut m: HashMap<i32, usize> = HashMap::new();
for x in second {
*m.entry(x).or_default() += 1;
}

first
Ok(first
.iter()
.map(|v| (*v as usize) * m.get(v).unwrap_or(&0))
.sum::<usize>()
.to_string()
.to_string())
}
}

Expand All @@ -68,21 +69,21 @@ mod tests {

#[test]
fn part1_test() {
assert_eq!(Problem.part_one(TEST_INPUT), "11");
assert_eq!(Problem.part_one(TEST_INPUT).unwrap(), "11");
}

#[test]
fn part2_test() {
assert_eq!(Problem.part_two(TEST_INPUT), "31");
assert_eq!(Problem.part_two(TEST_INPUT).unwrap(), "31");
}

#[test]
fn part1() {
assert_eq!(Problem.part_one(INPUT), "2066446");
assert_eq!(Problem.part_one(INPUT).unwrap(), "2066446");
}

#[test]
fn part2() {
assert_eq!(Problem.part_two(INPUT), "24931009");
assert_eq!(Problem.part_two(INPUT).unwrap(), "24931009");
}
}
20 changes: 10 additions & 10 deletions aoc2024/src/days/day02.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,26 +38,26 @@ fn is_safe(sequence: &[i32], mut dampener_levels: usize) -> bool {

pub struct Problem;
impl Solution for Problem {
fn part_one(&self, input: &str) -> String {
fn part_one(&self, input: &str) -> miette::Result<String> {
let reports = parse(input);

reports
Ok(reports
.iter()
.map(|levels| is_safe(levels, 0))
.filter(|&e| e)
.count()
.to_string()
.to_string())
}

fn part_two(&self, input: &str) -> String {
fn part_two(&self, input: &str) -> miette::Result<String> {
let reports = parse(input);

reports
Ok(reports
.iter()
.map(|levels| is_safe(levels, 1))
.filter(|&e| e)
.count()
.to_string()
.to_string())
}
}

Expand All @@ -70,21 +70,21 @@ mod tests {

#[test]
fn part1_test() {
assert_eq!(Problem.part_one(TEST_INPUT), "2");
assert_eq!(Problem.part_one(TEST_INPUT).unwrap(), "2");
}

#[test]
fn part2_test() {
assert_eq!(Problem.part_two(TEST_INPUT), "5");
assert_eq!(Problem.part_two(TEST_INPUT).unwrap(), "5");
}

#[test]
fn part1() {
assert_eq!(Problem.part_one(INPUT), "326");
assert_eq!(Problem.part_one(INPUT).unwrap(), "326");
}

#[test]
fn part2() {
assert_eq!(Problem.part_two(INPUT), "381");
assert_eq!(Problem.part_two(INPUT).unwrap(), "381");
}
}
28 changes: 16 additions & 12 deletions aoc2024/src/days/day03.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,25 @@ enum Process {

pub struct Problem;
impl Solution for Problem {
fn part_one(&self, input: &str) -> String {
let (_, instrs) = parse(input).unwrap();
fn part_one(&self, input: &str) -> miette::Result<String> {
let (_, instrs) = parse(input).map_err(|err| miette::miette!("Parsing failed: {:?}", err))?;

instrs
let res = instrs
.iter()
.map(|instr| match instr {
Instruction::Mul(x, y) => x * y,
_ => 0,
})
.sum::<u32>()
.to_string()
.to_string();

Ok(res)
}

fn part_two(&self, input: &str) -> String {
let (_input, instructions) = parse(input).unwrap();
fn part_two(&self, input: &str) -> miette::Result<String> {
let (_, instructions) = parse(input).map_err(|err| miette::miette!("Parsing failed: {:?}", err))?;

instructions
let res = instructions
.iter()
.fold((Process::DoProcess, 0), |(process, acc), ins| match ins {
Instruction::Mul(a, b) => {
Expand All @@ -77,7 +79,9 @@ impl Solution for Problem {
Instruction::Dont => (Process::DontProcess, acc),
})
.1
.to_string()
.to_string();

Ok(res)
}
}

Expand All @@ -91,21 +95,21 @@ mod tests {

#[test]
fn part1_test() {
assert_eq!(Problem.part_one(TEST_INPUT), "161");
assert_eq!(Problem.part_one(TEST_INPUT).unwrap(), "161");
}

#[test]
fn part2_test() {
assert_eq!(Problem.part_two(TEST_INPUT_2), "48");
assert_eq!(Problem.part_two(TEST_INPUT_2).unwrap(), "48");
}

#[test]
fn part1() {
assert_eq!(Problem.part_one(INPUT), "178886550");
assert_eq!(Problem.part_one(INPUT).unwrap(), "178886550");
}

#[test]
fn part2() {
assert_eq!(Problem.part_two(INPUT), "87163705");
assert_eq!(Problem.part_two(INPUT).unwrap(), "87163705");
}
}
16 changes: 8 additions & 8 deletions aoc2024/src/days/day04.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const SUB: &str = "XMAS";

pub struct Problem;
impl Solution for Problem {
fn part_one(&self, input: &str) -> String {
fn part_one(&self, input: &str) -> miette::Result<String> {
let mtx: Vec<Vec<char>> = input.lines().map(|line| line.chars().collect()).collect();
let mut permutations: Vec<String> = vec![];

Expand Down Expand Up @@ -64,10 +64,10 @@ impl Solution for Problem {
.count();
}

count.to_string()
Ok(count.to_string())
}

fn part_two(&self, input: &str) -> String {
fn part_two(&self, input: &str) -> miette::Result<String> {
// thank god part 2 is WAY easier.
let mtx: Vec<Vec<char>> = input.lines().map(|line| line.chars().collect()).collect();

Expand Down Expand Up @@ -103,7 +103,7 @@ impl Solution for Problem {
}
}

count.to_string()
Ok(count.to_string())
}
}

Expand All @@ -116,21 +116,21 @@ mod tests {

#[test]
fn part1_test() {
assert_eq!(Problem.part_one(TEST_INPUT), "18");
assert_eq!(Problem.part_one(TEST_INPUT).unwrap(), "18");
}

#[test]
fn part2_test() {
assert_eq!(Problem.part_two(TEST_INPUT), "9");
assert_eq!(Problem.part_two(TEST_INPUT).unwrap(), "9");
}

#[test]
fn part1() {
assert_eq!(Problem.part_one(INPUT), "2547");
assert_eq!(Problem.part_one(INPUT).unwrap(), "2547");
}

#[test]
fn part2() {
assert_eq!(Problem.part_two(INPUT), "1939");
assert_eq!(Problem.part_two(INPUT).unwrap(), "1939");
}
}
4 changes: 2 additions & 2 deletions aoc2024/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
#![feature(iter_intersperse)]

pub trait Solution {
fn part_one(&self, input: &str) -> String;
fn part_two(&self, input: &str) -> String;
fn part_one(&self, input: &str) -> miette::Result<String>;
fn part_two(&self, input: &str) -> miette::Result<String>;
}

pub fn get_input(day_num: usize, test: bool) -> String {
Expand Down
Loading

0 comments on commit 278fba0

Please sign in to comment.