Add solution for day 4

This commit is contained in:
Savanni D'Gerinel 2022-12-04 23:36:21 -05:00
parent 27e5979042
commit 3e3fbd802d
5 changed files with 1179 additions and 0 deletions

25
2022/Cargo.lock generated
View File

@ -2,6 +2,31 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "nom"
version = "7.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]] [[package]]
name = "problems" name = "problems"
version = "0.1.0" version = "0.1.0"
dependencies = [
"nom",
]

View File

@ -6,3 +6,4 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
nom = { version = "7" }

1000
2022/data/day4.txt Normal file

File diff suppressed because it is too large Load Diff

150
2022/src/day4.rs Normal file
View File

@ -0,0 +1,150 @@
use nom::{self, bytes::complete::tag, character::complete, sequence::separated_pair, IResult};
use std::collections::HashSet;
const INPUT: &str = include_str!("../data/day4.txt");
pub fn part1() -> String {
format!("{}", count_full_containments(input(INPUT)))
}
pub fn part2() -> String {
format!("{}", count_overlaps(input(INPUT)))
}
fn count_full_containments(pairings: Vec<ElfPairing>) -> u32 {
pairings.into_iter().fold(0, |cur, pairing| {
if pairing.has_full_containment() {
cur + 1
} else {
cur
}
})
}
fn count_overlaps(pairings: Vec<ElfPairing>) -> u32 {
pairings.into_iter().fold(
0,
|cur, pairing| {
if pairing.has_overlap() {
cur + 1
} else {
cur
}
},
)
}
struct ElfPairing {
elf1: Vec<u32>,
elf2: Vec<u32>,
}
impl ElfPairing {
fn has_full_containment(&self) -> bool {
let elf1 = self.elf1.iter().cloned().collect::<HashSet<u32>>();
let elf2 = self.elf2.iter().cloned().collect::<HashSet<u32>>();
elf1.is_subset(&elf2) || elf2.is_subset(&elf1)
}
fn has_overlap(&self) -> bool {
let element_count = self.elf1.len() + self.elf2.len();
let combined_set = self
.elf1
.iter()
.chain(self.elf2.iter())
.cloned()
.collect::<HashSet<u32>>();
combined_set.len() < element_count
}
}
fn input(data: &str) -> Vec<ElfPairing> {
data.lines()
.map(|line| {
let (_, pairing) = elf_pair(line).unwrap();
pairing
})
.collect::<Vec<ElfPairing>>()
}
fn elf_pair(input: &str) -> IResult<&str, ElfPairing> {
let (input, elf1) = elf_range(input)?;
let (input, _) = tag(",")(input)?;
let (input, elf2) = elf_range(input)?;
Ok((input, ElfPairing { elf1, elf2 }))
}
fn elf_range(input: &str) -> IResult<&str, Vec<u32>> {
let (input, start) = complete::u32(input)?;
let (input, _) = tag("-")(input)?;
let (input, end) = complete::u32(input)?;
Ok((input, (start..end + 1).collect::<Vec<u32>>()))
}
#[cfg(test)]
mod test {
use super::*;
const TEST_DATA: &str = "2-4,6-8
2-3,4-5
5-7,7-9
2-8,3-7
6-6,4-6
2-6,4-8";
#[test]
fn it_gets_a_hashset_from_a_range() {
assert_eq!(vec![2, 3, 4], (2..5).collect::<Vec<u32>>());
}
fn with_input<F>(test: F)
where
F: Fn(Vec<ElfPairing>) -> () + std::panic::UnwindSafe,
{
test(input(TEST_DATA));
}
#[test]
fn it_parses_input_correctly() {
with_input(|pairings| {
assert_eq!(vec![2, 3, 4], pairings[0].elf1);
assert_eq!(vec![6, 7, 8], pairings[0].elf2);
assert_eq!(vec![6], pairings[4].elf1);
assert_eq!(vec![4, 5, 6], pairings[4].elf2);
});
}
#[test]
fn it_checks_full_containment() {
with_input(|pairings| {
assert!(!pairings[0].has_full_containment());
assert!(!pairings[1].has_full_containment());
assert!(!pairings[2].has_full_containment());
assert!(pairings[3].has_full_containment());
assert!(pairings[4].has_full_containment());
assert!(!pairings[5].has_full_containment());
});
}
#[test]
fn it_counts_full_containments() {
with_input(|pairings| {
assert_eq!(2, count_full_containments(pairings));
});
}
#[test]
fn it_checks_overlap() {
with_input(|pairings| {
assert!(!pairings[0].has_overlap());
assert!(!pairings[1].has_overlap());
assert!(pairings[2].has_overlap());
assert!(pairings[3].has_overlap());
assert!(pairings[4].has_overlap());
assert!(pairings[5].has_overlap());
});
}
}

View File

@ -1,6 +1,7 @@
mod day1; mod day1;
mod day2; mod day2;
mod day3; mod day3;
mod day4;
fn main() { fn main() {
let day = std::env::args().skip(1).next(); let day = std::env::args().skip(1).next();
@ -12,6 +13,8 @@ fn main() {
Some("2b") => day2::part2(), Some("2b") => day2::part2(),
Some("3a") => day3::part1(), Some("3a") => day3::part1(),
Some("3b") => day3::part2(), Some("3b") => day3::part2(),
Some("4a") => day4::part1(),
Some("4b") => day4::part2(),
_ => panic!("unrecognized day"), _ => panic!("unrecognized day"),
}; };