Rust Day 2

This commit is contained in:
Tobias Berger 2023-04-27 11:38:21 +02:00
parent 4f8cda8c29
commit 4a0a756323
Signed by: toby
GPG key ID: 2D05EFAB764D6A88
6 changed files with 1135 additions and 0 deletions

View file

@ -26,3 +26,7 @@ codegen-units = 1
[[bin]]
name = "day01"
path = "src/day01/main.rs"
[[bin]]
name = "day02"
path = "src/day02/main.rs"

1000
rust/src/day02/input.txt Normal file

File diff suppressed because it is too large Load diff

56
rust/src/day02/main.rs Normal file
View file

@ -0,0 +1,56 @@
const INPUT: &str = include_str!("input.txt");
mod part_1;
use part_1::part_1;
mod part_2;
use part_2::part_2;
use std::str::FromStr;
#[derive(Debug)]
pub struct ParseError(String);
#[derive(Debug)]
pub struct Password {
pub first_num: usize,
pub second_num: usize,
pub letter: char,
pub password: String,
}
impl FromStr for Password {
type Err = ParseError;
fn from_str(line: &str) -> Result<Self, Self::Err> {
let parts = line.split(" ").collect::<Vec<_>>();
if parts.len() != 3 {
return Err(ParseError(line.into()));
}
let mut nums_iter = parts[0].split('-').map(|s| s.parse().unwrap());
let first_num = nums_iter.next().unwrap();
let second_num = nums_iter.next().unwrap();
let letter = parts[1].chars().nth(0).unwrap();
let password = parts[2].into();
Ok(Password {
first_num,
second_num,
letter,
password,
})
}
}
pub fn parse_input(input: &'static str) -> Vec<Password> {
input
.lines()
.map(|line| Password::from_str(line).unwrap())
.collect()
}
pub fn main() {
let input = parse_input(INPUT);
part_1(&input);
part_2(&input);
}

30
rust/src/day02/part_1.rs Normal file
View file

@ -0,0 +1,30 @@
pub(crate) fn part_1(input: &[crate::Password]) -> usize {
input.iter().fold(0, |acc, password| {
let num_letters = password
.password
.chars()
.filter(|&char| char == password.letter)
.count();
dbg!(password, num_letters);
if num_letters >= password.first_num && num_letters <= password.second_num {
acc + 1
} else {
acc
}
})
}
#[cfg(test)]
mod tests {
const SAMPLE_INPUT: &str = include_str!("sample_input.txt");
#[test]
fn test_with_sample_solution() {
assert_eq!(super::part_1(&crate::parse_input(SAMPLE_INPUT)), 2);
}
#[test]
fn test_with_solution() {
assert_eq!(super::part_1(&crate::parse_input(crate::INPUT)), 620);
}
}

42
rust/src/day02/part_2.rs Normal file
View file

@ -0,0 +1,42 @@
pub(crate) fn part_2(input: &[crate::Password]) -> usize {
input.iter().fold(0, |acc, password| {
let first_char = password
.password
.chars()
.nth(password.first_num - 1) // 1-indexed
.unwrap_or_default();
let second_char = password
.password
.chars()
.nth(password.second_num - 1) // 1-indexed
.unwrap_or_default();
dbg!(
&password.password,
password.letter,
password.first_num,
first_char,
password.second_num,
second_char
);
if (password.letter == first_char) != (password.letter == second_char) {
acc + 1
} else {
acc
}
})
}
#[cfg(test)]
mod tests {
const SAMPLE_INPUT: &str = include_str!("sample_input.txt");
#[test]
fn test_with_sample_solution() {
assert_eq!(super::part_2(&crate::parse_input(SAMPLE_INPUT)), 1);
}
#[test]
fn test_with_solution() {
assert_eq!(super::part_2(&crate::parse_input(crate::INPUT)), 727);
}
}

View file

@ -0,0 +1,3 @@
1-3 a: abcde
1-3 b: cdefg
2-9 c: ccccccccc