Compare commits
2 commits
9380266a2a
...
b2bd814c8a
Author | SHA1 | Date | |
---|---|---|---|
b2bd814c8a | |||
228c5fb6d5 |
3 changed files with 55 additions and 422 deletions
35
example.txt
35
example.txt
|
@ -1,33 +1,2 @@
|
||||||
seeds: 79 14 55 13
|
Time: 7 15 30
|
||||||
|
Distance: 9 40 200
|
||||||
seed-to-soil map:
|
|
||||||
50 98 2
|
|
||||||
52 50 48
|
|
||||||
|
|
||||||
soil-to-fertilizer map:
|
|
||||||
0 15 37
|
|
||||||
37 52 2
|
|
||||||
39 0 15
|
|
||||||
|
|
||||||
fertilizer-to-water map:
|
|
||||||
49 53 8
|
|
||||||
0 11 42
|
|
||||||
42 0 7
|
|
||||||
57 7 4
|
|
||||||
|
|
||||||
water-to-light map:
|
|
||||||
88 18 7
|
|
||||||
18 25 70
|
|
||||||
|
|
||||||
light-to-temperature map:
|
|
||||||
45 77 23
|
|
||||||
81 45 19
|
|
||||||
68 64 13
|
|
||||||
|
|
||||||
temperature-to-humidity map:
|
|
||||||
0 69 1
|
|
||||||
1 0 69
|
|
||||||
|
|
||||||
humidity-to-location map:
|
|
||||||
60 56 37
|
|
||||||
56 93 4
|
|
||||||
|
|
174
input.txt
174
input.txt
|
@ -1,172 +1,2 @@
|
||||||
seeds: 5844012 110899473 1132285750 58870036 986162929 109080640 3089574276 100113624 2693179996 275745330 2090752257 201704169 502075018 396653347 1540050181 277513792 1921754120 26668991 3836386950 66795009
|
Time: 44 82 69 81
|
||||||
|
Distance: 202 1076 1138 1458
|
||||||
seed-to-soil map:
|
|
||||||
3547471595 1239929038 174680800
|
|
||||||
3052451552 758183681 481745357
|
|
||||||
0 1427884524 1775655006
|
|
||||||
2844087171 549819300 208364381
|
|
||||||
3767989253 4004864866 5194940
|
|
||||||
3534196909 1414609838 13274686
|
|
||||||
1775655006 114264781 435554519
|
|
||||||
4148908402 4010059806 146058894
|
|
||||||
2729822390 0 114264781
|
|
||||||
3773184193 4156118700 138848596
|
|
||||||
2211209525 3203539530 518612865
|
|
||||||
3912032789 3767989253 236875613
|
|
||||||
|
|
||||||
soil-to-fertilizer map:
|
|
||||||
912405184 1056091028 152837752
|
|
||||||
194471272 1208928780 200072008
|
|
||||||
136115250 240819204 58356022
|
|
||||||
3502815281 3536983174 299994001
|
|
||||||
2321814552 2458149869 18748048
|
|
||||||
3173949445 2623931701 9591555
|
|
||||||
394543280 888648379 167442649
|
|
||||||
1990258415 3891640206 212931291
|
|
||||||
1068754270 54862533 153774684
|
|
||||||
1222528954 660792432 186471834
|
|
||||||
3340878967 3405750148 131233026
|
|
||||||
3472111993 3836977175 30703288
|
|
||||||
561985929 299175226 225501956
|
|
||||||
2942828492 4104571497 88527954
|
|
||||||
874532405 850775600 37872779
|
|
||||||
3031356446 3867680463 23959743
|
|
||||||
842350418 208637217 32181987
|
|
||||||
0 524677182 136115250
|
|
||||||
1065242936 847264266 3511334
|
|
||||||
2203189706 2339525023 118624846
|
|
||||||
1929736108 2563409394 60522307
|
|
||||||
3802809282 1847367009 492158014
|
|
||||||
1847367009 2790861223 82369099
|
|
||||||
2442430445 2873230322 500398047
|
|
||||||
3183541000 2633523256 157337967
|
|
||||||
3141827666 3373628369 32121779
|
|
||||||
787487885 0 54862533
|
|
||||||
3055316189 2476897917 86511477
|
|
||||||
2340562600 4193099451 101867845
|
|
||||||
|
|
||||||
fertilizer-to-water map:
|
|
||||||
798315344 439687669 1930292
|
|
||||||
1174979421 2966258900 475289790
|
|
||||||
439687669 778614573 55925503
|
|
||||||
3743699694 3453541232 155280637
|
|
||||||
2989334775 1659556189 96021468
|
|
||||||
1650269211 3441548690 11992542
|
|
||||||
3898980331 3608821869 395986965
|
|
||||||
1705125292 2123762646 842496254
|
|
||||||
3375514705 1755577657 368184989
|
|
||||||
646363825 441617961 94777173
|
|
||||||
1662261753 1616692650 42863539
|
|
||||||
495613172 627863920 150750653
|
|
||||||
2777061135 1174979421 212273640
|
|
||||||
741140998 834540076 57174346
|
|
||||||
800245636 536395134 91468786
|
|
||||||
2547621546 1387253061 229439589
|
|
||||||
3085356243 4004808834 290158462
|
|
||||||
|
|
||||||
water-to-light map:
|
|
||||||
541719462 212840988 165903288
|
|
||||||
3437755571 1615831015 672632835
|
|
||||||
1051033542 2678450187 510773217
|
|
||||||
243353905 378744276 104057369
|
|
||||||
1561806759 3801474127 134575711
|
|
||||||
707622750 677109833 258560892
|
|
||||||
2580483557 1051033542 195631857
|
|
||||||
0 935670725 30512917
|
|
||||||
347411274 482801645 194308188
|
|
||||||
30512917 0 127836567
|
|
||||||
2190497220 2288463850 389986337
|
|
||||||
3068589955 1246665399 369165616
|
|
||||||
1754579039 3936049838 66442917
|
|
||||||
4110388406 3616895237 184578890
|
|
||||||
158349484 127836567 85004421
|
|
||||||
2776115414 4002492755 292474541
|
|
||||||
1821021956 3247419973 369475264
|
|
||||||
1696382470 3189223404 58196569
|
|
||||||
|
|
||||||
light-to-temperature map:
|
|
||||||
338228166 2812162941 77503977
|
|
||||||
3123877206 693964345 40932068
|
|
||||||
3939438903 614787731 633466
|
|
||||||
3301169239 2299402886 215156012
|
|
||||||
3516325251 499164007 115623724
|
|
||||||
3852145506 3365439095 87293397
|
|
||||||
875755064 3565078024 729889272
|
|
||||||
2849390436 734896413 11914872
|
|
||||||
2861305308 215265512 77518872
|
|
||||||
4220385528 2056242491 68417151
|
|
||||||
2221674563 3167682469 34693717
|
|
||||||
2765973467 292784384 83416969
|
|
||||||
3198884011 1699097031 22283517
|
|
||||||
3164809274 2889666918 34074737
|
|
||||||
809366712 746811285 52314986
|
|
||||||
4096970661 1633036395 58945085
|
|
||||||
3221167528 2699611924 80001711
|
|
||||||
697021180 3452732492 112345532
|
|
||||||
2059345064 799126271 162329499
|
|
||||||
4155915746 629494563 64469782
|
|
||||||
2431111524 1721380548 334861943
|
|
||||||
684283267 2779613635 12737913
|
|
||||||
440342453 2923741655 243940814
|
|
||||||
3634265609 961455770 217879897
|
|
||||||
4288802679 3202376186 6164617
|
|
||||||
415732143 1691981480 4798917
|
|
||||||
1605644336 1179335667 453700728
|
|
||||||
420531060 2792351548 19811393
|
|
||||||
3631948975 1696780397 2316634
|
|
||||||
2938824180 2514558898 185053026
|
|
||||||
215265512 376201353 122962654
|
|
||||||
2256368280 2124659642 174743244
|
|
||||||
3940072369 3208540803 156898292
|
|
||||||
861681698 615421197 14073366
|
|
||||||
|
|
||||||
temperature-to-humidity map:
|
|
||||||
841576398 2731200418 60836938
|
|
||||||
1860695540 395011682 292982985
|
|
||||||
1518037021 3432774193 53954373
|
|
||||||
1786573987 2461900019 55353430
|
|
||||||
2940303448 1995108352 6974538
|
|
||||||
3014069287 1664464874 53916789
|
|
||||||
753139746 2190061656 88436652
|
|
||||||
2351822957 2925825589 209990361
|
|
||||||
3079884326 3498626816 37609115
|
|
||||||
4067060121 4186346579 108620717
|
|
||||||
4175680838 4102322798 3778367
|
|
||||||
1571991394 2415899186 46000833
|
|
||||||
2841627583 1157034722 22534242
|
|
||||||
1841927417 2517253449 18768123
|
|
||||||
2153678525 47765849 108568164
|
|
||||||
3251281674 1179568964 226737882
|
|
||||||
3067986076 3486728566 11898250
|
|
||||||
1308101633 1785172964 209935388
|
|
||||||
2262246689 1406306846 89576268
|
|
||||||
902413336 2278498308 137400878
|
|
||||||
1039814214 3765380846 268287419
|
|
||||||
45422022 156334013 238677669
|
|
||||||
3617672799 2612163195 119037223
|
|
||||||
2947277986 1718381663 66791301
|
|
||||||
1617992227 1495883114 168581760
|
|
||||||
284099691 687994667 469040055
|
|
||||||
4214721882 4106101165 80245414
|
|
||||||
2839283756 45422022 2343827
|
|
||||||
3117493441 2792037356 133788233
|
|
||||||
2864161825 2536021572 76141623
|
|
||||||
4179459205 4067060121 35262677
|
|
||||||
3736710022 3135815950 296958243
|
|
||||||
3478019556 2002082890 139653243
|
|
||||||
2610138841 3536235931 229144915
|
|
||||||
2561813318 2141736133 48325523
|
|
||||||
|
|
||||||
humidity-to-location map:
|
|
||||||
608325534 0 231346900
|
|
||||||
222429954 453776854 385895580
|
|
||||||
3710263359 3540956206 563631409
|
|
||||||
1193511298 1116937854 38719102
|
|
||||||
1702450793 1176729484 153572024
|
|
||||||
1694669826 1109156887 7780967
|
|
||||||
0 231346900 222429954
|
|
||||||
1856022817 1686715664 1854240542
|
|
||||||
1588644556 4104587615 106025270
|
|
||||||
1109156887 4210612885 84354411
|
|
||||||
4273894768 1155656956 21072528
|
|
||||||
1232230400 1330301508 356414156
|
|
||||||
|
|
268
src/main.rs
268
src/main.rs
|
@ -1,242 +1,76 @@
|
||||||
use std::cmp::{max, min};
|
use std::io::stdin;
|
||||||
use std::{collections::HashMap, io::stdin};
|
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::{bail, Result};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
/// solve ax² + bx + c = 0
|
||||||
struct Range {
|
fn solve_quadratic(a: f64, b: f64, c: f64) -> (f64, f64) {
|
||||||
start: i64,
|
let r1 = (-b + f64::sqrt(b * b - 4.0 * a * c)) / 2.0 * a;
|
||||||
len: i64,
|
let r2 = (-b - f64::sqrt(b * b - 4.0 * a * c)) / 2.0 * a;
|
||||||
|
(r1, r2)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Range {
|
fn parse_input() -> Result<(Vec<i64>, Vec<i64>)> {
|
||||||
fn intersection(&self, other: &Range) -> Option<Range> {
|
|
||||||
let i1 = max(self.start, other.start);
|
|
||||||
let i2 = min(self.start + self.len, other.start + other.len);
|
|
||||||
|
|
||||||
if i1 >= i2 {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(Range {
|
|
||||||
start: i1,
|
|
||||||
len: i2 - i1,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
struct RangeMap {
|
|
||||||
from: i64,
|
|
||||||
to: i64,
|
|
||||||
len: i64,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct SeedsMap {
|
|
||||||
range_maps: Vec<RangeMap>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SeedsMap {
|
|
||||||
fn new() -> SeedsMap {
|
|
||||||
SeedsMap { range_maps: vec![] }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_range(&mut self, range: (i64, i64, i64)) {
|
|
||||||
self.range_maps.push(RangeMap {
|
|
||||||
from: range.1,
|
|
||||||
to: range.0,
|
|
||||||
len: range.2,
|
|
||||||
});
|
|
||||||
self.range_maps.sort_by_key(|r| r.from);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn map(&self, ranges: &[Range]) -> Vec<Range> {
|
|
||||||
let mut result = vec![];
|
|
||||||
for r in ranges {
|
|
||||||
result.extend(self.map_single_range(r));
|
|
||||||
}
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
fn map_single_range(&self, range: &Range) -> Vec<Range> {
|
|
||||||
if self.range_maps.is_empty() {
|
|
||||||
return vec![*range];
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut result = vec![];
|
|
||||||
let first = self.range_maps.first().unwrap();
|
|
||||||
let last = self.range_maps.last().unwrap();
|
|
||||||
let left = min(range.start, first.from);
|
|
||||||
let right = max(range.start + range.len, last.from + last.len);
|
|
||||||
|
|
||||||
let mut last = left;
|
|
||||||
for rm in &self.range_maps {
|
|
||||||
// first, a range from last to rm.start, with no mapping
|
|
||||||
let r = Range {
|
|
||||||
start: last,
|
|
||||||
len: rm.from - last,
|
|
||||||
};
|
|
||||||
if let Some(i) = r.intersection(range) {
|
|
||||||
result.push(i);
|
|
||||||
}
|
|
||||||
// second, a range from rm.start, with mapping
|
|
||||||
let r = Range {
|
|
||||||
start: rm.from,
|
|
||||||
len: rm.len,
|
|
||||||
};
|
|
||||||
if let Some(i) = r.intersection(range) {
|
|
||||||
result.push(Range {
|
|
||||||
start: rm.to + i.start - rm.from,
|
|
||||||
len: i.len,
|
|
||||||
});
|
|
||||||
last = i.start + i.len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let r = Range {
|
|
||||||
start: last,
|
|
||||||
len: right - last,
|
|
||||||
};
|
|
||||||
if let Some(i) = r.intersection(range) {
|
|
||||||
result.push(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_input(seed_ranges: &mut Vec<Range>, maps: &mut HashMap<String, SeedsMap>) -> Result<()> {
|
|
||||||
let numbers = Regex::new(r"(\d+)")?;
|
let numbers = Regex::new(r"(\d+)")?;
|
||||||
let pairs = Regex::new(r"(\d+) (\d+)")?;
|
let mut times = vec![];
|
||||||
let mut current_map = String::new();
|
let mut distances = vec![];
|
||||||
for line in stdin().lines().map_while(Result::ok) {
|
for line in stdin().lines().map_while(Result::ok) {
|
||||||
if line.starts_with("seeds:") {
|
if line.starts_with("Time:") {
|
||||||
*seed_ranges = pairs
|
times = numbers
|
||||||
.captures_iter(&line)
|
.captures_iter(&line.replace(' ', ""))
|
||||||
.map(|c| -> Result<Range> {
|
|
||||||
Ok(Range {
|
|
||||||
start: c.get(1).unwrap().as_str().parse()?,
|
|
||||||
len: c.get(2).unwrap().as_str().parse()?,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.map_while(Result::ok)
|
|
||||||
.collect();
|
|
||||||
} else if line.ends_with(" map:") {
|
|
||||||
current_map = line
|
|
||||||
.split_whitespace()
|
|
||||||
.next()
|
|
||||||
.unwrap_or_default()
|
|
||||||
.to_owned();
|
|
||||||
} else {
|
|
||||||
let nums: Vec<i64> = numbers
|
|
||||||
.captures_iter(&line)
|
|
||||||
.map(|c| c.get(1).unwrap().as_str().parse())
|
.map(|c| c.get(1).unwrap().as_str().parse())
|
||||||
.map_while(Result::ok)
|
.map_while(Result::ok)
|
||||||
.collect();
|
.collect();
|
||||||
if nums.len() == 3 {
|
} else if line.starts_with("Distance:") {
|
||||||
let map = maps
|
distances = numbers
|
||||||
.entry(current_map.clone())
|
.captures_iter(&line.replace(' ', ""))
|
||||||
.or_insert_with(SeedsMap::new);
|
.map(|c| c.get(1).unwrap().as_str().parse())
|
||||||
map.add_range((nums[0], nums[1], nums[2]));
|
.map_while(Result::ok)
|
||||||
}
|
.collect();
|
||||||
|
} else {
|
||||||
|
bail!("unexpected line: {}", line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok((times, distances))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
let mut maps: HashMap<String, SeedsMap> = HashMap::new();
|
let (times, distances) = parse_input()?;
|
||||||
let mut seed_ranges: Vec<Range> = vec![];
|
|
||||||
|
|
||||||
parse_input(&mut seed_ranges, &mut maps)?;
|
if times.len() != distances.len() {
|
||||||
|
bail!(
|
||||||
let map_names = [
|
"times has {} elements, but distances has {} elements",
|
||||||
"seed-to-soil",
|
times.len(),
|
||||||
"soil-to-fertilizer",
|
distances.len()
|
||||||
"fertilizer-to-water",
|
);
|
||||||
"water-to-light",
|
|
||||||
"light-to-temperature",
|
|
||||||
"temperature-to-humidity",
|
|
||||||
"humidity-to-location",
|
|
||||||
];
|
|
||||||
|
|
||||||
let mut locations = vec![];
|
|
||||||
for range in seed_ranges {
|
|
||||||
let mut mapped_ranges = vec![range];
|
|
||||||
for map_name in map_names {
|
|
||||||
let mapped = maps.get(map_name).unwrap().map(&mapped_ranges);
|
|
||||||
mapped_ranges = mapped;
|
|
||||||
}
|
|
||||||
locations.extend(mapped_ranges.iter().map(|r| r.start));
|
|
||||||
}
|
}
|
||||||
println!("{}", locations.iter().min().unwrap());
|
|
||||||
|
let mut prod = 1;
|
||||||
|
for i in 0..times.len() {
|
||||||
|
let t = times[i];
|
||||||
|
let d = distances[i];
|
||||||
|
|
||||||
|
// the equation to solve is x * (t - x) - d = 0
|
||||||
|
// = t*x - x*x - d = 0
|
||||||
|
// = -1x² + tx - d = 0
|
||||||
|
let (r1, r2) = solve_quadratic(-1.0, t as f64, -d as f64);
|
||||||
|
let r1 = (r1 + 1.0).floor() as i64;
|
||||||
|
let r2 = (r2 - 1.0).ceil() as i64;
|
||||||
|
|
||||||
|
let ways = (r2 - r1) + 1;
|
||||||
|
|
||||||
|
println!("{t} {d}");
|
||||||
|
println!("ways: {ways}");
|
||||||
|
prod *= ways;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("{prod}");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_intersections() {
|
fn test() {}
|
||||||
let l = |r1: &Range, r2: &Range| r1.intersection(r2);
|
|
||||||
assert_eq!(
|
|
||||||
l(&Range { start: 1, len: 3 }, &Range { start: 1, len: 3 }),
|
|
||||||
Some(Range { start: 1, len: 3 })
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
l(&Range { start: 1, len: 2 }, &Range { start: 1, len: 3 }),
|
|
||||||
Some(Range { start: 1, len: 2 })
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
l(&Range { start: 2, len: 4 }, &Range { start: 0, len: 3 }),
|
|
||||||
Some(Range { start: 2, len: 1 })
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
l(&Range { start: 0, len: 3 }, &Range { start: 2, len: 4 }),
|
|
||||||
Some(Range { start: 2, len: 1 })
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
l(&Range { start: 3, len: 4 }, &Range { start: 0, len: 3 }),
|
|
||||||
None
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
l(&Range { start: 0, len: 10 }, &Range { start: 4, len: 4 }),
|
|
||||||
Some(Range { start: 4, len: 4 })
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_range_map() {
|
|
||||||
let mut m = SeedsMap::new();
|
|
||||||
m.add_range((52, 50, 48));
|
|
||||||
m.add_range((50, 98, 2));
|
|
||||||
let r = m.map_single_range(&Range { start: 79, len: 14 });
|
|
||||||
assert_eq!(r, [Range { start: 81, len: 14 }]);
|
|
||||||
|
|
||||||
let mut m = SeedsMap::new();
|
|
||||||
m.add_range((39, 0, 15));
|
|
||||||
m.add_range((0, 15, 37));
|
|
||||||
m.add_range((37, 52, 2));
|
|
||||||
let r = m.map_single_range(&Range { start: 81, len: 14 });
|
|
||||||
assert_eq!(r, [Range { start: 81, len: 14 }]);
|
|
||||||
|
|
||||||
let mut m = SeedsMap::new();
|
|
||||||
m.add_range((88, 18, 7));
|
|
||||||
m.add_range((18, 25, 70));
|
|
||||||
let r = m.map_single_range(&Range { start: 81, len: 14 });
|
|
||||||
assert_eq!(r, [Range { start: 74, len: 14 }]);
|
|
||||||
|
|
||||||
let mut m = SeedsMap::new();
|
|
||||||
m.add_range((81, 45, 19));
|
|
||||||
m.add_range((68, 64, 13));
|
|
||||||
m.add_range((45, 77, 23));
|
|
||||||
let r = m.map_single_range(&Range { start: 74, len: 14 });
|
|
||||||
assert_eq!(
|
|
||||||
r,
|
|
||||||
[Range { start: 78, len: 3 }, Range { start: 45, len: 11 }]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue