summaryrefslogtreecommitdiff
path: root/2023/Rust/src/day5.rs
diff options
context:
space:
mode:
Diffstat (limited to '2023/Rust/src/day5.rs')
-rw-r--r--2023/Rust/src/day5.rs107
1 files changed, 107 insertions, 0 deletions
diff --git a/2023/Rust/src/day5.rs b/2023/Rust/src/day5.rs
new file mode 100644
index 0000000..bd57e90
--- /dev/null
+++ b/2023/Rust/src/day5.rs
@@ -0,0 +1,107 @@
+use std::collections::HashSet;
+
+fn solve_part_one(data: &str) -> u32 {
+ let mut almanac = Almanac::from(data);
+ let mut seeds = almanac.seeds.clone();
+ let mut nseeds = vec![];
+ for i in (0..seeds.len()).step_by(2) {
+ for j in seeds[i]..seeds[i] + seeds[i + 1] {
+ nseeds.push(j);
+ }
+ }
+ almanac.seeds = nseeds;
+
+ let mut seeds = almanac.seeds.clone();
+ for (_, maps) in almanac.maps.iter() {
+ for seed in seeds.iter_mut() {
+ let tmp = seed.clone();
+ for seed_map in maps.iter() {
+ if seed_map.contains(tmp) {
+ *seed += (seed_map.dest as i64 - seed_map.src as i64) as i64;
+ }
+ }
+ }
+ }
+ *seeds.iter().min().unwrap() as u32
+}
+
+fn solve_part_two(data: &str) -> u64 {
+ let mut almanac = Almanac::from(data);
+ let seeds = almanac.seeds.clone();
+ let mut set: HashSet<i64> = HashSet::new();
+ let mut sum = 0;
+ for i in (0..seeds.len()).step_by(2) {
+ for j in seeds[i]..seeds[i] + seeds[i + 1] {
+ set.insert(j);
+ }
+ sum += seeds[i] + seeds[i + 1];
+ }
+ dbg!(set.len());
+ sum as u64
+}
+
+type Seeds = Vec<i64>;
+
+#[derive(Debug)]
+struct Almanac<'a> {
+ seeds: Seeds,
+ maps: Vec<(&'a str, Vec<SeedMap>)>,
+}
+
+impl<'a> From<&'a str> for Almanac<'a> {
+ fn from(data: &'a str) -> Self {
+ let data: Vec<&str> = data.split("\n\n").collect();
+ let (_, seeds) = data[0].split_once(": ").unwrap();
+ let seeds: Vec<_> = seeds
+ .split(' ')
+ .map(|x| x.parse::<i64>().unwrap())
+ .collect();
+ let mut maps: Vec<(&'a str, Vec<SeedMap>)> = Vec::new();
+ for map in data.iter().skip(1) {
+ let (desc, seed_maps) = map.split_once(':').unwrap();
+ let (name, _) = desc.split_once(' ').unwrap();
+ let mut v = vec![];
+ for smap in seed_maps.trim_start().trim_end().split('\n') {
+ v.push(SeedMap::from(smap));
+ }
+ maps.push((name, v));
+ }
+ Self { seeds, maps }
+ }
+}
+
+#[derive(Debug)]
+struct SeedMap {
+ src: usize,
+ dest: usize,
+ range_len: usize,
+}
+
+impl SeedMap {
+ fn contains(&self, seed: i64) -> bool {
+ (self.src..self.src + self.range_len).contains(&(seed as usize))
+ }
+}
+
+impl From<&str> for SeedMap {
+ fn from(seed_map: &str) -> Self {
+ let map: Vec<_> = seed_map
+ .split(' ')
+ .map(|x| x.parse::<usize>().expect("Should be parsabel to usize"))
+ .collect();
+ Self {
+ src: map[1],
+ dest: map[0],
+ range_len: map[2],
+ }
+ }
+}
+
+fn main() {
+ let test = include_str!("../input/day5.test");
+ let prod = include_str!("../input/day5.prod");
+ println!("part_1 test: {:?}", solve_part_one(test));
+ println!("part_1 prod {:?}", solve_part_one(prod));
+ // println!("part_2 test: {:?}", solve_part_two(test));
+ // println!("part_2 prod {:?}", solve_part_two(prod));
+}