Compare commits

...

2 commits

Author SHA1 Message Date
Gabe Venberg 8bd03989a8 day05 part1 2023-12-05 17:51:17 -06:00
Gabe Venberg aea643cf31 day05 parsing 2023-12-05 16:32:06 -06:00
9 changed files with 935 additions and 0 deletions

8
Cargo.lock generated
View file

@ -47,6 +47,14 @@ dependencies = [
"nom", "nom",
] ]
[[package]]
name = "day05"
version = "0.1.0"
dependencies = [
"aoc_libs",
"nom",
]
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.6.4" version = "2.6.4"

View file

@ -1 +1,2 @@
pub mod points; pub mod points;
pub mod range;

38
aoc_libs/src/range.rs Normal file
View file

@ -0,0 +1,38 @@
#[derive(Debug, PartialEq, Eq)]
pub struct InclusiveRange<T>
where
T: PartialOrd + Ord + PartialEq + Copy,
{
start: T,
end: T,
}
impl<T> InclusiveRange<T>
where
T: PartialOrd + Ord + PartialEq + Copy,
{
pub fn new(start: T, end: T) -> Self {
Self {
start: start.min(end),
end: end.max(start),
}
}
pub fn any_overlap(&self, other: &Self) -> bool {
self.start <= other.end && self.end >= other.start
}
pub fn calc_overlap(&self, other: &Self) -> Self {
let overlap_start = self.start.min(other.start);
let overlap_end = self.end.max(other.end);
InclusiveRange::new(overlap_start, overlap_end)
}
pub fn complete_overlap(&self, other: &Self) -> bool {
self.calc_overlap(other) == *self || self.calc_overlap(other) == *other
}
pub fn in_range(&self, other: T) -> bool {
self.start <= other && other <= self.end
}
}

10
days/day05/Cargo.toml Normal file
View file

@ -0,0 +1,10 @@
[package]
name = "day05"
authors.workspace = true
description.workspace = true
version.workspace = true
edition.workspace = true
[dependencies]
aoc_libs.workspace = true
nom.workspace = true

252
days/day05/src/input.txt Normal file
View file

@ -0,0 +1,252 @@
seeds: 432986705 28073546 1364097901 88338513 2733524843 234912494 3151642679 224376393 485709676 344068331 1560394266 911616092 3819746175 87998136 892394515 435690182 4218056486 23868437 848725444 8940450
seed-to-soil map:
748585809 2125564114 88980459
1317392128 775565564 217595062
1218610825 676784261 98781303
954230685 2235762425 141777617
2920242079 4081180892 51765553
2972007632 3159586797 16102841
0 2377540042 17565155
2834452876 3712797875 58062179
2892515055 2917079842 6424918
3327351062 3175689638 162608005
673338549 647264576 29519685
1197392973 2214544573 21217852
738232750 116664417 10353059
2988110473 2429807442 71556277
17565155 334379348 277510712
1700771639 228674051 105705297
3059666750 4132946445 162020851
1806476936 993160626 588628261
1096008302 127289380 101384671
622123656 1908836676 50942989
3221687601 3338297643 28028532
2408505336 3770860054 310320838
4175210607 3039830108 119756689
3326652416 3039131462 698646
2898939973 2408505336 21302106
673066645 127017476 271904
3489959067 3382623558 330174317
702858234 611890060 35374516
4086270124 2562002619 88940483
837566268 0 116664417
1534987190 1959779665 165784449
2718826174 2923504760 115626702
3249716133 3366326175 16297383
3820133384 2650943102 266136740
3266013516 2501363719 60638900
295075867 1581788887 327047789
soil-to-fertilizer map:
2018515973 2192795257 82329405
3722326327 3015971185 249665840
3046459770 3689390318 25519185
3971992167 3265637025 40217941
3071978955 3453653215 203407731
0 443504340 17965088
584437096 1722124969 470670288
1055107384 744431503 164966659
1489299099 461469428 282962075
2321848831 2380372526 153650776
2100845378 269225056 174279284
3487660258 2648616968 234666069
3275386686 3305854966 147798249
1772261174 1172578553 246254799
4012210108 2883283037 132688148
3423184935 4138946628 64475323
4144898256 2321848831 58523695
538253726 1418833352 46183370
1220074043 0 269225056
17965088 909398162 263180391
2590093273 3657060946 32329372
281145479 1465016722 257108247
2622422645 3714909503 424037125
2475499607 2534023302 114593666
fertilizer-to-water map:
3731805434 353192162 37567806
926873139 889685769 255250442
3170336676 695153543 194532226
679924479 451681440 193671776
3009343704 3081959489 160992972
1242360754 3579359343 278026518
1861131448 2500688596 20068354
4028837903 4006213119 266129393
1182123581 3242952461 60237173
3877550443 645353216 49800327
2223776164 1371077033 341527178
3364868902 2566566565 36440100
1773121333 0 76664401
264823995 2444756861 55931735
3929841219 3857385861 27802851
2166799431 1712604211 56976733
873596255 1769580944 53276884
645696746 3047731756 34227733
3927350770 3955153621 2490449
3769373240 177937131 108177203
0 3314535348 264823995
1942121274 3885188712 69964909
1881199802 390759968 60921472
1849785734 3303189634 11345714
3401309002 2855740726 104355610
2079164011 2960096336 87635420
544424016 76664401 101272730
2565303342 2520756950 45809615
1520387272 2603006665 252734061
2012086183 286114334 67077828
2611112957 1822857828 398230747
320755730 2221088575 223668286
3505664612 1144936211 226140822
4006213119 4272342512 22624784
water-to-light map:
62780592 544346201 30115959
2740764032 1352944740 34082945
377487729 807592920 35446631
1316419610 1454554942 34907962
986581913 756881718 50711202
4167758628 3240047125 127208668
818809239 1222506283 58684750
3649838514 2036598113 6212644
127663629 0 10715051
3023280854 1435387310 19167632
663070842 10715051 124076893
2774846977 2422700597 37614763
1812617371 2460315360 5121443
1640337506 1864318248 172279865
2986755724 1316419610 36525130
2023334670 2467203928 540327060
1159184084 248462172 14557802
1037293115 152894449 95567723
0 134791944 18102505
18102505 712203631 44678087
465375803 972369801 197695039
2576394916 3007530988 65274194
92896551 1281191033 34767078
3656051158 4289142647 5824649
412934360 1170064840 52441443
3417303830 3873138614 84580361
787147735 263019974 31661504
1817738814 2042810757 205595856
1285160111 843039551 30798000
2563661730 3123136764 12733186
138378680 305237152 239109049
3648071389 2465436803 1767125
1132860838 574462160 26323246
888049663 873837551 98532250
3626039273 3072805182 22032116
3530183657 4193287031 95855616
1404769450 3957718975 235568056
3042448486 1489462904 374855344
2641669110 1387027685 48359625
877493989 294681478 10555674
3501884191 3094837298 28299466
1351327572 3186605247 53441878
2690028735 3135869950 50735297
2812461740 2248406613 174293984
3661875807 3367255793 505882821
1173741886 600785406 111418225
light-to-temperature map:
964570004 989608620 226759942
2204148775 2545437438 20646474
233260112 338444213 39032265
958191857 332066066 6378147
2318799855 914518254 75090366
4247140372 3146297568 47826924
2224795249 1216368562 94004606
2871022952 1310373168 80313918
1400254919 233260112 98805954
445493256 487550555 149554087
2576473348 3962746668 294549604
3535295748 2775008885 371288683
1499060873 377476478 110074077
272292377 2215619580 173200879
3347481948 1867953550 157067409
4161267146 3794452372 85873226
3504549357 2184873189 30746391
1759636962 1780717197 87236353
2951336870 2388820459 6114967
1191329946 2566083912 208924973
1884544339 3880325598 82421070
595047343 3431307858 363144514
2393890221 731935127 182583127
4001414916 2025020959 159852230
2957451837 1390687086 390030111
1846873315 4257296272 37671024
1966965409 3194124492 237183366
1609134950 2394935426 150502012
3906584431 637104642 94830485
temperature-to-humidity map:
1406768592 2335526312 13344484
666958498 1862550129 472976183
558853371 843618476 74696086
1168798622 129171378 168640618
1713291209 297811996 183431863
1993628008 635748116 152317885
2560263686 2849350774 11516524
32266442 1212766321 287276323
2571780210 3319898101 11192927
375095240 995599149 183758131
2661986290 2353962919 50829838
3252020768 4280298713 14668583
1337439240 1793220777 69329352
3419718116 3502299739 574454544
2353962919 2650392505 198958269
633549457 1179357280 33409041
2582973137 4076754283 50515665
319542765 788066001 55552475
1896723072 32266442 96904936
1420113076 1500042644 293178133
3006421020 2404792757 245599748
2842554807 3331091028 163866213
2633488802 2990605977 28497488
2300450150 947178503 48420646
3266689351 4127269948 153028765
2145945893 481243859 154504257
3994172660 3019103465 300794636
1139934681 918314562 28863941
2712816128 2860867298 129738679
2552921188 3494957241 7342498
humidity-to-location map:
897459980 3171885613 268595078
506368722 1864971513 13322696
1166055058 2803961444 53745388
2572095034 667166679 114420176
687118932 1725187165 139784348
2478398695 0 14138781
3427672233 370325921 251085897
3888215738 3612891343 82449665
1674720770 1530101168 79955344
3970665403 925512154 2812137
519691418 2452425610 167427514
3884704963 3168374838 3510775
826903280 2381868910 70556700
2399774019 349568762 20757159
2972099388 3465151802 147739541
1754676114 131614075 217954687
2865104023 3440480691 24671111
2206760431 932309368 77882935
2284643366 1610056512 115130653
2492537476 14138781 35151040
2527688516 3695341008 44406518
3119838929 781586855 143925299
2732270071 2857706832 132833952
1599442846 2728683520 75277924
3263764228 3995626854 27783181
0 2990540784 177834054
2686515210 621411818 45754861
2420531178 2670816003 57867517
1219800446 1010192303 191374197
3678758130 3789680021 205946833
3973477540 3739747526 49932495
1972630801 2014419033 234129630
3291547409 1878294209 136124824
2889775134 49289821 82324254
1411174643 2619853124 50962879
1466122599 2248548663 133320247
177834054 1201566500 328534668
1462137522 928324291 3985077

14
days/day05/src/main.rs Normal file
View file

@ -0,0 +1,14 @@
mod part1;
mod part2;
mod parse;
fn main() {
let input = include_str!("./input.txt");
let structured_input = parse::parse(input);
println!("Part One");
println!("Result: {}", part1::part1(&structured_input));
println!("Part Two");
println!("Result: {}", part2::part2());
}

441
days/day05/src/parse.rs Normal file
View file

@ -0,0 +1,441 @@
use nom::{
bytes::complete::tag,
character::complete::{alpha1, multispace0},
multi::{count, many1, separated_list1},
sequence::{delimited, preceded, terminated},
IResult,
};
#[derive(Debug, PartialEq, Eq)]
pub struct Map {
pub from: String,
pub to: String,
pub ranges: Vec<Range>,
}
impl Map {
pub fn map(&self, src: u64)->u64 {
for range in &self.ranges {
if range.is_applicable(&src) {
return range.map(src);
}
}
src
}
fn parse(input: &str) -> IResult<&str, Self> {
let (input, (from, to)) = delimited(multispace0, Self::parse_to_from, multispace0)(input)?;
let (input, ranges) = many1(Range::parse)(input)?;
Ok((input, Map { from, to, ranges }))
}
fn parse_to_from(input: &str) -> IResult<&str, (String, String)> {
let (input, from) = alpha1(input)?;
let (input, to) = terminated(preceded(tag("-to-"), alpha1), tag(" map:\n"))(input)?;
Ok((input, (from.to_string(), to.to_string())))
}
}
#[derive(Debug, PartialEq, Eq)]
pub struct Range {
pub dest_start: u64,
pub src_start: u64,
pub len: u64,
}
impl Range {
fn is_applicable(&self, src: &u64) -> bool {
self.src_start <= *src && *src < (self.src_start + self.len)
}
fn map(&self, src: u64) -> u64 {
if self.is_applicable(&src) {
let offset = src - self.src_start;
self.dest_start + offset
} else {
src
}
}
fn parse(input: &str) -> IResult<&str, Self> {
let number = delimited(multispace0, nom::character::complete::u64, multispace0);
let (input, numbers) = count(number, 3)(input)?;
Ok((
input,
Range {
dest_start: numbers[0],
src_start: numbers[1],
len: numbers[2],
},
))
}
}
fn parse_input(input: &str) -> IResult<&str, (Vec<u64>, Vec<Map>)> {
let (input, seeds) = preceded(
tag("seeds: "),
separated_list1(tag(" "), nom::character::complete::u64),
)(input)?;
let (input, maps) = many1(Map::parse)(input)?;
Ok((input, (seeds, maps)))
}
pub fn parse(input: &str) -> (Vec<u64>, Vec<Map>) {
parse_input(input).unwrap().1
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_map() {
let tested = Map {
from: "seed".to_string(),
to: "soil".to_string(),
ranges: vec![
Range {
dest_start: 50,
src_start: 98,
len: 2,
},
Range {
dest_start: 52,
src_start: 50,
len: 48,
},
],
};
let input = [79, 14, 55, 13];
let output = input.map(|i| tested.map(i));
assert_eq!(output, [81, 14, 57, 13])
}
#[test]
fn test_is_appliccable() {
let tested = Range {
dest_start: 50,
src_start: 98,
len: 2,
};
assert!(tested.is_applicable(&99));
assert!(!tested.is_applicable(&100));
assert!(!tested.is_applicable(&97));
}
#[test]
fn test_range_map() {
let tested = Range {
dest_start: 52,
src_start: 50,
len: 48,
};
assert_eq!(tested.map(79), 81);
assert_eq!(tested.map(100), 100);
}
#[test]
fn test_map_parse() {
let input = concat!("seed-to-soil map:\n", "50 98 2\n", "52 50 48\n", "\n",);
assert_eq!(
Map::parse(input).unwrap(),
(
"",
Map {
from: "seed".to_string(),
to: "soil".to_string(),
ranges: vec![
Range {
dest_start: 50,
src_start: 98,
len: 2
},
Range {
dest_start: 52,
src_start: 50,
len: 48
},
]
},
)
)
}
#[test]
fn test_range_parse() {
assert_eq!(
Range::parse("50 98 2\n").unwrap(),
(
"",
Range {
dest_start: 50,
src_start: 98,
len: 2,
}
)
);
assert_eq!(
Range::parse("0 15 37\n").unwrap(),
(
"",
Range {
dest_start: 0,
src_start: 15,
len: 37,
}
)
)
}
#[test]
fn test_parse_to_from() {
assert_eq!(
Map::parse_to_from("seed-to-soil map:\n").unwrap(),
("", ("seed".to_string(), "soil".to_string()))
);
assert_eq!(
Map::parse_to_from("hello-to-world map:\n").unwrap(),
("", ("hello".to_string(), "world".to_string()))
);
}
#[test]
fn test_parse_input() {
let input = concat!(
"seeds: 79 14 55 13\n",
"\n",
"seed-to-soil map:\n",
"50 98 2\n",
"52 50 48\n",
"\n",
"soil-to-fertilizer map:\n",
"0 15 37\n",
"37 52 2\n",
"39 0 15\n",
);
assert_eq!(
parse_input(input).unwrap(),
(
"",
(
vec![79, 14, 55, 13],
vec![
Map {
from: "seed".to_string(),
to: "soil".to_string(),
ranges: vec![
Range {
dest_start: 50,
src_start: 98,
len: 2
},
Range {
dest_start: 52,
src_start: 50,
len: 48
},
]
},
Map {
from: "soil".to_string(),
to: "fertilizer".to_string(),
ranges: vec![
Range {
dest_start: 0,
src_start: 15,
len: 37
},
Range {
dest_start: 37,
src_start: 52,
len: 2
},
Range {
dest_start: 39,
src_start: 0,
len: 15
},
]
}
]
)
)
);
}
#[test]
fn test_parse() {
let input = concat!(
"seeds: 79 14 55 13\n",
"\n",
"seed-to-soil map:\n",
"50 98 2\n",
"52 50 48\n",
"\n",
"soil-to-fertilizer map:\n",
"0 15 37\n",
"37 52 2\n",
"39 0 15\n",
"\n",
"fertilizer-to-water map:\n",
"49 53 8\n",
"0 11 42\n",
"42 0 7\n",
"57 7 4\n",
"\n",
"water-to-light map:\n",
"88 18 7\n",
"18 25 70\n",
"\n",
"light-to-temperature map:\n",
"45 77 23\n",
"81 45 19\n",
"68 64 13\n",
"\n",
"temperature-to-humidity map:\n",
"0 69 1\n",
"1 0 69\n",
"\n",
"humidity-to-location map:\n",
"60 56 37\n",
"56 93 4\n",
);
assert_eq!(
parse(input),
(
vec![79, 14, 55, 13],
vec![
Map {
from: "seed".to_string(),
to: "soil".to_string(),
ranges: vec![
Range {
dest_start: 50,
src_start: 98,
len: 2
},
Range {
dest_start: 52,
src_start: 50,
len: 48
}
]
},
Map {
from: "soil".to_string(),
to: "fertilizer".to_string(),
ranges: vec![
Range {
dest_start: 0,
src_start: 15,
len: 37
},
Range {
dest_start: 37,
src_start: 52,
len: 2
},
Range {
dest_start: 39,
src_start: 0,
len: 15
}
]
},
Map {
from: "fertilizer".to_string(),
to: "water".to_string(),
ranges: vec![
Range {
dest_start: 49,
src_start: 53,
len: 8
},
Range {
dest_start: 0,
src_start: 11,
len: 42
},
Range {
dest_start: 42,
src_start: 0,
len: 7
},
Range {
dest_start: 57,
src_start: 7,
len: 4
}
]
},
Map {
from: "water".to_string(),
to: "light".to_string(),
ranges: vec![
Range {
dest_start: 88,
src_start: 18,
len: 7
},
Range {
dest_start: 18,
src_start: 25,
len: 70
}
]
},
Map {
from: "light".to_string(),
to: "temperature".to_string(),
ranges: vec![
Range {
dest_start: 45,
src_start: 77,
len: 23
},
Range {
dest_start: 81,
src_start: 45,
len: 19
},
Range {
dest_start: 68,
src_start: 64,
len: 13
}
]
},
Map {
from: "temperature".to_string(),
to: "humidity".to_string(),
ranges: vec![
Range {
dest_start: 0,
src_start: 69,
len: 1
},
Range {
dest_start: 1,
src_start: 0,
len: 69
}
]
},
Map {
from: "humidity".to_string(),
to: "location".to_string(),
ranges: vec![
Range {
dest_start: 60,
src_start: 56,
len: 37
},
Range {
dest_start: 56,
src_start: 93,
len: 4
}
]
}
]
)
);
}
}

156
days/day05/src/part1.rs Normal file
View file

@ -0,0 +1,156 @@
use crate::parse::*;
pub fn part1(input: &(Vec<u64>, Vec<Map>)) -> usize {
let mut seeds = input.0.clone();
for map in &input.1{
seeds = seeds.into_iter().map(|s| map.map(s)).collect()
}
*seeds.iter().min().unwrap() as usize
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part1() {
let input = (
vec![79, 14, 55, 13],
vec![
Map {
from: "seed".to_string(),
to: "soil".to_string(),
ranges: vec![
Range {
dest_start: 50,
src_start: 98,
len: 2
},
Range {
dest_start: 52,
src_start: 50,
len: 48
}
]
},
Map {
from: "soil".to_string(),
to: "fertilizer".to_string(),
ranges: vec![
Range {
dest_start: 0,
src_start: 15,
len: 37
},
Range {
dest_start: 37,
src_start: 52,
len: 2
},
Range {
dest_start: 39,
src_start: 0,
len: 15
}
]
},
Map {
from: "fertilizer".to_string(),
to: "water".to_string(),
ranges: vec![
Range {
dest_start: 49,
src_start: 53,
len: 8
},
Range {
dest_start: 0,
src_start: 11,
len: 42
},
Range {
dest_start: 42,
src_start: 0,
len: 7
},
Range {
dest_start: 57,
src_start: 7,
len: 4
}
]
},
Map {
from: "water".to_string(),
to: "light".to_string(),
ranges: vec![
Range {
dest_start: 88,
src_start: 18,
len: 7
},
Range {
dest_start: 18,
src_start: 25,
len: 70
}
]
},
Map {
from: "light".to_string(),
to: "temperature".to_string(),
ranges: vec![
Range {
dest_start: 45,
src_start: 77,
len: 23
},
Range {
dest_start: 81,
src_start: 45,
len: 19
},
Range {
dest_start: 68,
src_start: 64,
len: 13
}
]
},
Map {
from: "temperature".to_string(),
to: "humidity".to_string(),
ranges: vec![
Range {
dest_start: 0,
src_start: 69,
len: 1
},
Range {
dest_start: 1,
src_start: 0,
len: 69
}
]
},
Map {
from: "humidity".to_string(),
to: "location".to_string(),
ranges: vec![
Range {
dest_start: 60,
src_start: 56,
len: 37
},
Range {
dest_start: 56,
src_start: 93,
len: 4
}
]
}
]
);
assert_eq!(part1(&input), 35);
}
}

15
days/day05/src/part2.rs Normal file
View file

@ -0,0 +1,15 @@
use crate::parse::*;
pub fn part2() -> usize {
unimplemented!()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part2() {
assert_eq!(0, 0);
}
}