mirror of
https://github.com/SebastianStork/advent-of-code.git
synced 2026-01-21 13:21:34 +01:00
Compare commits
2 commits
ff3c082979
...
5929ef6b97
| Author | SHA1 | Date | |
|---|---|---|---|
| 5929ef6b97 | |||
| 2786c75a97 |
4 changed files with 140 additions and 3 deletions
7
2025/rust/day-05/Cargo.lock
generated
Normal file
7
2025/rust/day-05/Cargo.lock
generated
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "day-05"
|
||||||
|
version = "0.1.0"
|
||||||
6
2025/rust/day-05/Cargo.toml
Normal file
6
2025/rust/day-05/Cargo.toml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
[package]
|
||||||
|
name = "day-05"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
124
2025/rust/day-05/src/main.rs
Normal file
124
2025/rust/day-05/src/main.rs
Normal file
|
|
@ -0,0 +1,124 @@
|
||||||
|
use std::fs;
|
||||||
|
|
||||||
|
struct Range {
|
||||||
|
start: u64,
|
||||||
|
end: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Range {
|
||||||
|
fn new(start: u64, end: u64) -> Self {
|
||||||
|
Range { start, end }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn contains(&self, num: u64) -> bool {
|
||||||
|
num >= self.start && num <= self.end
|
||||||
|
}
|
||||||
|
|
||||||
|
fn overlaps(&self, other: &Range) -> bool {
|
||||||
|
self.contains(other.start) || self.contains(other.end)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn merge_with(&mut self, overlap: &Range) {
|
||||||
|
if overlap.start < self.start {
|
||||||
|
self.start = overlap.start;
|
||||||
|
}
|
||||||
|
if overlap.end > self.end {
|
||||||
|
self.end = overlap.end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn length(&self) -> u64 {
|
||||||
|
self.end - self.start + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let (ranges, available_ids) = parse_input(&fs::read_to_string("../../inputs/05.txt").unwrap());
|
||||||
|
let ranges = merge_overlapping_ranges(ranges);
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"Number of available IDs in ranges: {}",
|
||||||
|
count_available_ids_in_ranges(available_ids, &ranges)
|
||||||
|
);
|
||||||
|
println!("Number of IDs in ranges: {}", count_ids_in_ranges(&ranges));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_input(contents: &str) -> (Vec<Range>, Vec<u64>) {
|
||||||
|
let (ranges, available_ids) = contents.trim().split_once("\n\n").unwrap();
|
||||||
|
|
||||||
|
let ranges: Vec<Range> = ranges
|
||||||
|
.lines()
|
||||||
|
.map(|line| line.split_once("-").unwrap())
|
||||||
|
.map(|(start, end)| Range::new(start.parse().unwrap(), end.parse().unwrap()))
|
||||||
|
.collect();
|
||||||
|
let available_ids: Vec<u64> = available_ids
|
||||||
|
.lines()
|
||||||
|
.map(|line| line.parse().unwrap())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
(ranges, available_ids)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn merge_overlapping_ranges(mut ranges: Vec<Range>) -> Vec<Range> {
|
||||||
|
ranges.sort_by_key(|range| range.start);
|
||||||
|
|
||||||
|
let mut compressed_ranges = vec![ranges.remove(0)];
|
||||||
|
|
||||||
|
for range in ranges {
|
||||||
|
let previous = compressed_ranges.last_mut().unwrap();
|
||||||
|
|
||||||
|
if previous.overlaps(&range) {
|
||||||
|
previous.merge_with(&range);
|
||||||
|
} else {
|
||||||
|
compressed_ranges.push(range);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
compressed_ranges
|
||||||
|
}
|
||||||
|
|
||||||
|
fn count_available_ids_in_ranges(available_ids: Vec<u64>, ranges: &[Range]) -> usize {
|
||||||
|
available_ids
|
||||||
|
.iter()
|
||||||
|
.filter(|id| ranges.iter().any(|range| range.contains(**id)))
|
||||||
|
.count()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn count_ids_in_ranges(ranges: &[Range]) -> u64 {
|
||||||
|
ranges.iter().map(|range| range.length()).sum()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
const TEST_INPUT: &str = "
|
||||||
|
3-5
|
||||||
|
10-14
|
||||||
|
16-20
|
||||||
|
12-18
|
||||||
|
|
||||||
|
1
|
||||||
|
5
|
||||||
|
8
|
||||||
|
11
|
||||||
|
17
|
||||||
|
32
|
||||||
|
";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part1() {
|
||||||
|
let (ranges, available_ids) = parse_input(TEST_INPUT);
|
||||||
|
let ranges = merge_overlapping_ranges(ranges);
|
||||||
|
|
||||||
|
assert_eq!(count_available_ids_in_ranges(available_ids, &ranges), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part2() {
|
||||||
|
let (ranges, _) = parse_input(TEST_INPUT);
|
||||||
|
let ranges = merge_overlapping_ranges(merge_overlapping_ranges(ranges));
|
||||||
|
|
||||||
|
assert_eq!(count_ids_in_ranges(&ranges), 14);
|
||||||
|
}
|
||||||
|
}
|
||||||
6
flake.lock
generated
6
flake.lock
generated
|
|
@ -3,10 +3,10 @@
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1764840758,
|
"lastModified": 1764926544,
|
||||||
"narHash": "sha256-GTN8SBnhvv6t2oDS1H85xcYAhafy8mpUQWSrCErhtgw=",
|
"narHash": "sha256-xIkgV9KrBel6Qwy673iMmmggFGZ9Zz93Hd/lGhRyHRM=",
|
||||||
"ref": "refs/heads/main",
|
"ref": "refs/heads/main",
|
||||||
"rev": "415a59297c64d0448d22975ca5ad3d8ef064c9f0",
|
"rev": "27de1eaccb499f25dca8f3505b4c4f42a8e35514",
|
||||||
"shallow": true,
|
"shallow": true,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "ssh://git@github.com/SebastianStork/advent-of-code-inputs.git"
|
"url": "ssh://git@github.com/SebastianStork/advent-of-code-inputs.git"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue