1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
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));
}
|