Rust Day 2
This commit is contained in:
parent
4f8cda8c29
commit
4a0a756323
6 changed files with 1135 additions and 0 deletions
|
@ -26,3 +26,7 @@ codegen-units = 1
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "day01"
|
name = "day01"
|
||||||
path = "src/day01/main.rs"
|
path = "src/day01/main.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "day02"
|
||||||
|
path = "src/day02/main.rs"
|
||||||
|
|
1000
rust/src/day02/input.txt
Normal file
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
56
rust/src/day02/main.rs
Normal 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
30
rust/src/day02/part_1.rs
Normal 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
42
rust/src/day02/part_2.rs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
3
rust/src/day02/sample_input.txt
Normal file
3
rust/src/day02/sample_input.txt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
1-3 a: abcde
|
||||||
|
1-3 b: cdefg
|
||||||
|
2-9 c: ccccccccc
|
Loading…
Reference in a new issue