Skip to content

Commit 1c1da33

Browse files
committed
5.2 correct.
1 parent 058e4fe commit 1c1da33

File tree

1 file changed

+143
-5
lines changed

1 file changed

+143
-5
lines changed

aoc05/src/main.rs

+143-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
use std::cmp::Ordering;
2+
13
use util::input_lines;
24

3-
#[derive(Debug)]
5+
#[derive(Debug, Clone)]
46
struct Map {
57
dest: u64,
68
src: u64,
@@ -21,8 +23,22 @@ impl Map {
2123
len: iter.next().unwrap().parse().unwrap(),
2224
})
2325
}
26+
v.sort_by(|a, b| a.src.cmp(&b.src));
2427
v
2528
}
29+
fn get_dest(&self, src: u64) -> u64 {
30+
assert!(self.contains(src));
31+
self.dest + src - self.src
32+
}
33+
fn contains(&self, src: u64) -> bool {
34+
src >= self.src && src < self.src + self.len
35+
}
36+
fn src_upper_limit(&self) -> u64 {
37+
let max = self.src + self.len - 1;
38+
assert!(self.contains(max));
39+
assert!(!self.contains(max + 1));
40+
max
41+
}
2642
}
2743

2844
#[derive(Debug, Default)]
@@ -39,19 +55,57 @@ struct Input {
3955

4056
trait GetDest {
4157
fn get_dest(&self, src: u64) -> u64;
58+
fn get_first_src_range(&self, src: u64, max: u64) -> (u64, u64);
59+
fn get_src_ranges(&self, min: u64, max: u64) -> Vec<(u64, u64)> {
60+
let mut v = Vec::new();
61+
let mut x = min;
62+
while x < max {
63+
v.push(self.get_first_src_range(x, max));
64+
x = v.last().unwrap().1 + 1;
65+
}
66+
v
67+
}
68+
fn get_dest_ranges(&self, src_min: u64, src_max: u64) -> Vec<(u64, u64)>;
69+
fn get_many_dest_ranges(&self, ranges: &[(u64, u64)]) -> Vec<(u64, u64)> {
70+
let mut v = Vec::new();
71+
for (min, max) in ranges {
72+
v.extend(self.get_dest_ranges(*min, *max));
73+
}
74+
v
75+
}
4276
}
4377

4478
impl GetDest for Vec<Map> {
4579
fn get_dest(&self, src: u64) -> u64 {
4680
for m in self {
47-
if src >= m.src && src < m.src + m.len {
48-
println!("{} --> {}", src, m.dest + src - m.src);
49-
return m.dest + src - m.src;
81+
if m.contains(src) {
82+
// println!("{} --> {}", src, m.dest + src - m.src);
83+
return m.get_dest(src);
5084
}
5185
}
52-
println!("{} --> {}", src, src);
86+
// println!("{} --> {}", src, src);
5387
src
5488
}
89+
90+
fn get_first_src_range(&self, src: u64, max: u64) -> (u64, u64) {
91+
for m in self {
92+
if m.contains(src) {
93+
return (src, std::cmp::min(max, m.src_upper_limit()));
94+
}
95+
if m.src > src {
96+
return (src, std::cmp::min(max, m.src - 1));
97+
}
98+
}
99+
(src, max)
100+
}
101+
102+
fn get_dest_ranges(&self, src_min: u64, src_max: u64) -> Vec<(u64, u64)> {
103+
let mut v = Vec::new();
104+
for (min, max) in self.get_src_ranges(src_min, src_max) {
105+
v.push((self.get_dest(min), self.get_dest(max)));
106+
}
107+
v
108+
}
55109
}
56110

57111
impl Input {
@@ -100,6 +154,26 @@ impl Input {
100154
),
101155
)
102156
}
157+
fn get_best(&self, min: u64, max: u64) -> u64 {
158+
let locs = self.humidity_to_location.get_many_dest_ranges(
159+
&self.temp_to_humidity.get_many_dest_ranges(
160+
&self.light_to_temp.get_many_dest_ranges(
161+
&self.water_to_light.get_many_dest_ranges(
162+
&self.fertilizer_to_water.get_many_dest_ranges(
163+
&self
164+
.soil_to_fertilizer
165+
.get_many_dest_ranges(&self.seed_to_soil.get_dest_ranges(min, max)),
166+
),
167+
),
168+
),
169+
),
170+
);
171+
let mut min = locs[0].0;
172+
for loc in locs {
173+
min = std::cmp::min(min, loc.0);
174+
}
175+
min
176+
}
103177
}
104178

105179
fn main() {
@@ -109,4 +183,68 @@ fn main() {
109183
min_loc = std::cmp::min(min_loc, i.get_loc(*seed));
110184
}
111185
println!("Part 1: {}", min_loc);
186+
let mut min_loc = i.get_loc(i.seeds[0]);
187+
let mut iter = i.seeds.iter();
188+
while let Some(start) = iter.next() {
189+
min_loc = std::cmp::min(min_loc, i.get_best(*start, *start + *iter.next().unwrap()));
190+
}
191+
println!("Part 2: {}", min_loc);
192+
}
193+
194+
#[cfg(test)]
195+
mod tests {
196+
use super::*;
197+
198+
#[test]
199+
fn test_map() {
200+
let map = Map {
201+
dest: 10,
202+
src: 100,
203+
len: 10,
204+
};
205+
assert!(!map.contains(99));
206+
assert!(map.contains(100));
207+
assert!(map.contains(109));
208+
assert!(!map.contains(110));
209+
assert_eq!(map.src_upper_limit(), 109);
210+
assert_eq!(map.get_dest(100), 10);
211+
assert_eq!(map.get_dest(109), 19);
212+
}
213+
214+
#[test]
215+
fn test_get_dest() {
216+
let v = vec![Map {
217+
dest: 10,
218+
src: 100,
219+
len: 10,
220+
}];
221+
assert_eq!(v.get_dest(99), 99);
222+
assert_eq!(v.get_dest(100), 10);
223+
assert_eq!(v.get_dest(109), 19);
224+
assert_eq!(v.get_dest(110), 110);
225+
226+
assert_eq!(v.get_first_src_range(10, 1000), (10, 99));
227+
assert_eq!(v.get_first_src_range(103, 1000), (103, 109));
228+
assert_eq!(v.get_first_src_range(120, 1000), (120, 1000));
229+
230+
assert_eq!(v.get_src_ranges(10, 20), [(10, 20)]);
231+
assert_eq!(v.get_src_ranges(101, 103), [(101, 103)]);
232+
assert_eq!(v.get_src_ranges(110, 120), [(110, 120)]);
233+
assert_eq!(v.get_src_ranges(10, 105), [(10, 99), (100, 105)]);
234+
assert_eq!(v.get_src_ranges(105, 1000), [(105, 109), (110, 1000)]);
235+
assert_eq!(
236+
v.get_src_ranges(10, 1000),
237+
[(10, 99), (100, 109), (110, 1000)]
238+
);
239+
240+
assert_eq!(v.get_dest_ranges(10, 20), [(10, 20)]);
241+
assert_eq!(v.get_dest_ranges(101, 103), [(11, 13)]);
242+
assert_eq!(v.get_dest_ranges(110, 120), [(110, 120)]);
243+
assert_eq!(v.get_dest_ranges(10, 105), [(10, 99), (10, 15)]);
244+
assert_eq!(v.get_dest_ranges(105, 1000), [(15, 19), (110, 1000)]);
245+
assert_eq!(
246+
v.get_dest_ranges(10, 1000),
247+
[(10, 99), (10, 19), (110, 1000)]
248+
);
249+
}
112250
}

0 commit comments

Comments
 (0)