diff --git a/input/2023/day5.txt b/input/2023/day5.txt new file mode 100644 index 0000000..eeee701 --- /dev/null +++ b/input/2023/day5.txt @@ -0,0 +1,213 @@ +seeds: 3139431799 50198205 3647185634 110151761 2478641666 139825503 498892555 8913570 961540761 489996751 568452082 100080382 907727477 42158689 1617552130 312026427 342640189 97088268 2049289560 336766062 + +seed-to-soil map: +1615836342 1401909974 23067952 +785532007 269485885 88937774 +3019002892 2773729385 10470414 +4202163101 2747292152 26437233 +3183210415 4217634159 77333137 +2847460091 3211730218 136699600 +2455891790 3791729773 70553041 +3260543552 2581343101 165949051 +3840286095 2849853212 361877006 +4228600334 2361239030 66366962 +1594559581 1077839137 21276761 +380069408 165017790 44262617 +3598718222 1894384162 241567873 +0 1424977926 190757551 +1894384162 2810496375 39356837 +424332025 606264721 196539291 +3521487829 2221977524 77230393 +742681934 69797365 36566707 +1638904294 1615735477 139190145 +1335949488 0 69797365 +779248641 802804012 6283366 +2638766896 4008940964 208693195 +250963029 1142644585 70452661 +1933740999 3470280789 321448984 +190757551 209280407 60205478 +1778094439 1099115898 43528687 +2255189983 3348429818 121850971 +1000500225 809087378 268751759 +1269251984 1754925622 66697504 +874469781 358423659 126030444 +2526444831 2135952035 86025489 +2439072067 3992121241 16819723 +3426492603 3897126015 94995226 +1405746853 1213097246 188812728 +321415690 106364072 58653718 +2984159691 3862282814 34843201 +2377040954 2299207917 62031113 +3029473306 2427605992 153737109 +2612470320 2784199799 26296576 +620871316 484454103 121810618 + +soil-to-fertilizer map: +4245401761 2352458099 28057201 +2099789767 3998256334 14950546 +3446056574 2749719529 135349925 +890092371 1379309857 42097049 +953714890 896502554 10335567 +3115342240 2380515300 218129381 +3333471621 3885671381 112584953 +663999152 0 226093219 +1873325002 727305635 169196919 +2042521921 1328150912 51158945 +3581406499 4034715214 260252082 +500989478 564295961 163009674 +4273458962 4013206880 21508334 +3992733429 2099789767 164092891 +4156826320 2263882658 88575441 +3841658581 2598644681 151074848 +1094703999 226093219 21270249 +1708571521 399542480 164753481 +964050457 247363468 130653542 +1236290130 1421406906 171284482 +0 1592691388 500989478 +932189420 378017010 21525470 +2114740313 2885069454 1000601927 +1115974248 1207835030 120315882 +1407574612 906838121 300996909 + +fertilizer-to-water map: +3217858280 3761663130 355893932 +2319366035 2401839275 72374872 +1962726423 909927230 105011330 +2115307878 441322644 204058157 +2095064202 1824085445 20243676 +110580631 329763915 34129824 +2573484127 2701101998 225220022 +1780224111 2342656863 59182412 +1717605398 1571533532 62618713 +3589165621 3062909078 75538793 +842280446 1871096488 471560375 +409726333 0 243114563 +397401582 760576019 12324751 +0 667815878 92760141 +3990305711 2926322020 5981819 +251664023 1741105813 32320840 +2072629125 645380801 22435077 +92760141 363893739 17820490 +2798704149 3138447871 156185660 +3664704414 2573484127 127617871 +1839406523 381714229 59608415 +283984863 1844329121 26767367 +1313840821 1176023584 27579684 +2391740907 1790738543 33346902 +3929650615 4234312200 60655096 +3996287530 3557602002 204061128 +1402088224 772900770 137026460 +1911435456 2474214147 51290967 +1539114684 1393042818 178490714 +3573752212 4117557062 15413409 +1341420505 1014938560 60667719 +3792322285 4132970471 6723091 +4200348658 4139693562 80082634 +652840896 1203603268 189439550 +310752230 243114563 86649352 +2425087809 1075606279 100417305 +1899014938 1773426653 12420518 +2067737753 1785847171 4891372 +3799045376 2932303839 130605239 +2954889809 3294633531 262968471 +4280431292 4219776196 14536004 +144710455 1634152245 106953568 + +water-to-light map: +1071107509 759231097 26724064 +1293599454 642189614 64567949 +3147690498 1633749175 71376364 +3487999223 4080968704 155844998 +1700873635 2097781236 292450760 +1146121952 1950303734 147477502 +2864027062 1470573702 75076585 +2507471274 3021419800 175807670 +2939103647 922829268 123372939 +2826742681 2551285626 37284381 +719212681 1821763210 100196810 +4236813702 4292227071 2740225 +3643844221 3837685117 243283587 +209103905 785955161 52302440 +100332146 752700417 6530680 +1478192138 3229160565 10342236 +1358167403 3239502801 94242072 +3219066862 706757563 45942854 +3062476586 1358475140 29661777 +819409491 2390231996 26561329 +4195136152 3511184798 41677550 +1488534374 1046202207 35444248 +3887127808 3552862348 284822769 +2188804057 1705125539 116637671 +0 309410320 100332146 +1117778238 1921960020 28343714 +261406345 3333744873 74978759 +2100705169 1545650287 88098888 +3450098653 3473284228 37900570 +2742067948 1273800407 84674733 +2305441728 107380774 202029546 +3265009716 1130086491 143713916 +1993324395 0 107380774 +1523978622 465294601 176895013 +106862826 2588570007 102241079 +2683278944 864040264 58789004 +4239553927 4236813702 55413369 +1097831573 1081646455 19946665 +524293914 1101593120 28493371 +336385104 2833510990 187908810 +552787285 3197227470 31933095 +845970820 2690811086 142699904 +988670724 1388136917 82436785 +1452409475 838257601 25782663 +3092138363 409742466 55552135 +584720380 2416793325 134492301 +4171950577 3450098653 23185575 + +light-to-temperature map: +2906633798 3843376160 451591136 +1332454428 1190958320 69004583 +1837712164 0 353313230 +494809338 353313230 376619264 +871428602 729932494 461025826 +1401459011 1754772241 373416033 +3976747173 3375456648 91164221 +3495346659 3466620869 376755291 +0 1259962903 494809338 +2608238358 2459541635 298395440 +3907558614 2984992977 69188559 +3872101950 2286963246 35456664 +4067911394 2757937075 227055902 +3358224934 2322419910 137121725 +2286963246 3054181536 321275112 +1774875044 2128188274 62837120 + +temperature-to-humidity map: +3966168141 3406025946 214996780 +4181164921 3292223571 113802375 +1493139015 1471031672 367564898 +1423475871 1838596570 69663144 +0 479293006 226560784 +2500785470 2859072453 433151118 +3197453551 2500785470 96923792 +758446483 1237739489 233292183 +991738666 0 278789291 +3555740534 3884539689 410427607 +3294377343 2597709262 261363191 +226560784 705853790 531885699 +1860703913 305742584 20602508 +2933936588 3621022726 263516963 +1881306421 278789291 26953293 +1270527957 326345092 152947914 + +humidity-to-location map: +848612454 2250862530 61410922 +910023376 3689675651 35197452 +3724873103 3865027106 240221283 +483883727 3324946924 364728727 +0 1766978803 483883727 +1957894300 561533 922927950 +945220828 2590144784 734802140 +2880822250 0 561533 +3447014853 1489120553 277858250 +2881383783 923489483 565631070 +3965094386 3724873103 140154003 +1680022968 2312273452 277871332 diff --git a/src/day05.rs b/src/day05.rs new file mode 100644 index 0000000..6f06666 --- /dev/null +++ b/src/day05.rs @@ -0,0 +1,129 @@ +use std::ops::Range; + +use aoc_runner_derive::{aoc, aoc_generator}; +use nom::{ + bytes::complete::tag, + character::complete::{anychar, line_ending}, + combinator::map, + multi::{many_till, separated_list0}, + sequence::{pair, preceded, separated_pair, terminated, tuple}, + IResult, +}; + +#[derive(Debug)] +struct Map { + ranges: Vec<(Range, i32)>, +} + +impl Map { + fn new(raw_ranges: Vec<(u32, u32, u32)>) -> Self { + let mut ranges = Vec::new(); + for (dest_start, source_start, len) in raw_ranges { + let source_range = source_start..(source_start + len); + let offset = ((dest_start as i64) - (source_start as i64)) as i32; + ranges.push((source_range, offset)) + } + Self { ranges } + } + + fn transform(&self, input: u32) -> u32 { + for (range, offset) in &self.ranges { + if range.contains(&input) { + return ((input as i64) + (*offset as i64)) as u32; + } + } + input + } + + fn transform_range(&self, input: Range) -> Range { + let start = self.transform(input.start); + let end = self.transform(input.end); + start..end + } +} + +fn parse_seed_list(input: &str) -> IResult<&str, Vec> { + preceded( + tag("seeds: "), + separated_list0(tag(" "), nom::character::complete::u32), + )(input) +} + +fn parse_seed_list_as_ranges(input: &str) -> IResult<&str, Vec>> { + preceded( + tag("seeds: "), + separated_list0( + tag(" "), + map( + separated_pair( + nom::character::complete::u32, + tag(" "), + nom::character::complete::u32, + ), + |(start, length)| (start..(start + length)), + ), + ), + )(input) +} + +fn parse_raw_range(input: &str) -> IResult<&str, (u32, u32, u32)> { + tuple(( + terminated(nom::character::complete::u32, tag(" ")), + terminated(nom::character::complete::u32, tag(" ")), + nom::character::complete::u32, + ))(input) +} + +fn parse_map(input: &str) -> IResult<&str, Map> { + map( + preceded( + many_till(anychar, line_ending), + separated_list0(line_ending, parse_raw_range), + ), + Map::new, + )(input) +} + +#[aoc_generator(day5, part1)] +fn input_generator_part1(input: &str) -> (Vec, Vec) { + pair( + terminated(parse_seed_list, pair(line_ending, line_ending)), + separated_list0(pair(line_ending, line_ending), parse_map), + )(input) + .unwrap() + .1 +} + +#[aoc_generator(day5, part2)] +fn input_generator_part2(input: &str) -> (Vec>, Vec) { + pair( + terminated(parse_seed_list_as_ranges, pair(line_ending, line_ending)), + separated_list0(pair(line_ending, line_ending), parse_map), + )(input) + .unwrap() + .1 +} + +#[aoc(day5, part1)] +fn part1((seeds, maps): &(Vec, Vec)) -> u32 { + fn run_through_maps(seed: u32, maps: &[Map]) -> u32 { + maps.iter().fold(seed, |val, map| map.transform(val)) + } + seeds + .iter() + .map(|&seed| run_through_maps(seed, &maps)) + .min() + .unwrap() +} + +#[aoc(day5, part2)] +fn part2((seeds, maps): &(Vec>, Vec)) -> u32 { + fn run_through_maps(seed: u32, maps: &[Map]) -> u32 { + maps.iter().fold(seed, |val, map| map.transform(val)) + } + seeds + .iter() + .flat_map(|range| maps.iter().fold(range.clone(), |val, map| map.transform_range(val)).clone()) + .min() + .unwrap() +} diff --git a/src/lib.rs b/src/lib.rs index c0e7712..bad81fe 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,5 +4,6 @@ mod day01; mod day02; mod day03; mod day04; +mod day05; aoc_lib! { year = 2023 }