Compare commits
2 Commits
5a34125164
...
1866aefc5b
| Author | SHA1 | Date | |
|---|---|---|---|
| 1866aefc5b | |||
| e73fc141fd |
9
advent_of_code/2023/5/Cargo.toml
Normal file
9
advent_of_code/2023/5/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "main"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
nom = "7.1.3"
|
||||
254
advent_of_code/2023/5/input.txt
Normal file
254
advent_of_code/2023/5/input.txt
Normal file
@@ -0,0 +1,254 @@
|
||||
seeds: 1132132257 323430997 2043754183 4501055 2539071613 1059028389 1695770806 60470169 2220296232 251415938 1673679740 6063698 962820135 133182317 262615889 327780505 3602765034 194858721 2147281339 37466509
|
||||
|
||||
seed-to-soil map:
|
||||
1280158874 0 45923291
|
||||
0 1431836695 234754481
|
||||
2476778759 365219074 73714061
|
||||
3997869725 4152785341 16553125
|
||||
3014496893 3731980396 420804945
|
||||
3435301838 2667516045 60128827
|
||||
2784964719 2727644872 187996890
|
||||
792043155 613341484 49447658
|
||||
1444573280 2476024240 74468580
|
||||
2728723659 3675739336 56241060
|
||||
2704677524 4236229588 24046135
|
||||
2360313001 1780050354 116465758
|
||||
1326082165 226504189 118491115
|
||||
3495430665 3630596320 3607732
|
||||
1519041860 662789142 56785021
|
||||
3973462947 3383860003 24406778
|
||||
1575826881 45923291 119425025
|
||||
1695251906 766775600 665061095
|
||||
2667516045 3323175190 6512477
|
||||
4240794960 3329687667 54172336
|
||||
720792676 344995304 20223770
|
||||
489053726 438933135 143852141
|
||||
741016446 746305099 20470501
|
||||
3499038397 4169338466 66891122
|
||||
761486947 582785276 30556208
|
||||
3565929519 3249598798 73576392
|
||||
659636803 165348316 61155873
|
||||
234754481 2221724995 254299245
|
||||
2674028522 4260275723 30649002
|
||||
841490813 1896516112 325208883
|
||||
632905867 719574163 26730936
|
||||
1166699696 1666591176 113459178
|
||||
2972961609 3634204052 41535284
|
||||
4195000071 3408266781 45794889
|
||||
4190957500 4290924725 4042571
|
||||
3639505911 2915641762 333957036
|
||||
4014422850 3454061670 176534650
|
||||
|
||||
soil-to-fertilizer map:
|
||||
528009375 3804807330 65591757
|
||||
3608285775 3569685636 235121694
|
||||
432120564 3045118038 95888811
|
||||
3843407469 1792428879 363149111
|
||||
4206556580 2155577990 88410716
|
||||
3441777 3141006849 428678787
|
||||
1019419908 3870399087 424568209
|
||||
593601132 2619299262 425818776
|
||||
1443988117 3441777 1788987102
|
||||
3232975219 2243988706 375310556
|
||||
|
||||
fertilizer-to-water map:
|
||||
3768646817 2541098841 42522952
|
||||
657445332 493998363 293094466
|
||||
3153469588 3947073749 287697992
|
||||
2513829777 3047249136 215146452
|
||||
968568929 29638292 96921246
|
||||
1600806946 1111339724 96961929
|
||||
3880726440 2687212715 52238929
|
||||
416544049 1090614661 20725063
|
||||
1749924539 4274983783 15782292
|
||||
1306572576 1208301653 21184719
|
||||
2134505230 4234771741 40212042
|
||||
1697768875 0 29638292
|
||||
3811169769 2617656044 69556671
|
||||
487527141 787092829 169918191
|
||||
3932965369 2583621793 34034251
|
||||
178562138 1471396125 237981911
|
||||
2728976229 3010972799 36276337
|
||||
2174717272 3262395588 176952386
|
||||
3035746039 1749924539 117723549
|
||||
2794475974 2764473831 241270065
|
||||
437269112 443740334 50258029
|
||||
2790274753 4290766075 4201221
|
||||
3441167580 3767315650 179758099
|
||||
3966999620 3439347974 327967676
|
||||
2351669658 2236446487 162160119
|
||||
1585319642 1229486372 15487304
|
||||
1327757295 186177987 257562347
|
||||
2765252566 2739451644 25022187
|
||||
950539798 1709378036 18029131
|
||||
1765706831 1867648088 368798399
|
||||
1199093816 1363917365 107478760
|
||||
3763417914 3005743896 5228903
|
||||
1065490175 957011020 133603641
|
||||
3620925679 2398606606 142492235
|
||||
59618449 1244973676 118943689
|
||||
0 126559538 59618449
|
||||
|
||||
water-to-light map:
|
||||
2368177077 1928300684 68416280
|
||||
3459327457 4032125413 181740227
|
||||
2874128303 2996109939 93290692
|
||||
40167335 1203835270 50270286
|
||||
2984608918 3988581415 43543998
|
||||
1295445723 891961544 129160430
|
||||
232873619 72411133 344405432
|
||||
4002859459 4225073350 66563582
|
||||
3451555101 2874128303 4441992
|
||||
3957368975 2950619455 45490484
|
||||
4192270745 3148930063 6297777
|
||||
1638782153 2125726715 498901151
|
||||
3028152916 2912054150 38565305
|
||||
577279051 1504061698 367203335
|
||||
3418071246 2878570295 33483855
|
||||
3897839543 3089400631 59529432
|
||||
2967418995 3166056654 3449280
|
||||
3641067684 3835626234 152955181
|
||||
4147219041 3436688572 45051704
|
||||
2436593357 1021121974 182713296
|
||||
3066718221 3484273209 351353025
|
||||
2647866375 1254105556 189577037
|
||||
4198568522 3340289798 96398774
|
||||
2619306653 39188438 21015758
|
||||
2982075985 3481740276 2532933
|
||||
4069423041 3155227840 10828814
|
||||
2186332185 1443682593 52835141
|
||||
90437621 678875874 142435998
|
||||
980629741 2624627866 212815546
|
||||
2239167326 1996716964 129009751
|
||||
1424606153 571958210 106917664
|
||||
0 1871265033 40167335
|
||||
2980967789 4223965154 1108196
|
||||
1619041805 450217426 19740348
|
||||
1193445287 469957774 102000436
|
||||
944482386 426277008 23940418
|
||||
4080251855 3169505934 66967186
|
||||
1548392133 821311872 70649672
|
||||
1531523817 1911432368 16868316
|
||||
2970868275 4213865640 10099514
|
||||
3455997093 4291636932 3330364
|
||||
2137683304 416816565 9460443
|
||||
3794022865 3236473120 103816678
|
||||
2147143747 0 39188438
|
||||
2640322411 1496517734 7543964
|
||||
968422804 60204196 12206937
|
||||
|
||||
light-to-temperature map:
|
||||
224631556 2579077346 68012835
|
||||
93390978 2647090181 93292258
|
||||
836334842 260175809 93895333
|
||||
3305235739 4175688657 119278639
|
||||
2495493200 354071142 67947352
|
||||
2563440552 648390650 214063090
|
||||
4184988573 4065709934 109978723
|
||||
930230175 2740382439 151863620
|
||||
2777503642 1813071562 114742417
|
||||
3424514378 3772814840 292895094
|
||||
1492090043 422018494 226372156
|
||||
3717409472 3176683751 126763710
|
||||
3273297 2243837725 90117681
|
||||
1216313119 2511603925 67473421
|
||||
4104753748 3096448926 80234825
|
||||
2392410003 1112358810 103083197
|
||||
759707869 2434976952 76626973
|
||||
2031212648 2333955406 101021546
|
||||
2132234194 0 260175809
|
||||
1718462199 1931087276 312750449
|
||||
186683236 1682505485 37948320
|
||||
1174711552 1070757243 41601567
|
||||
292644391 1215442007 467063478
|
||||
3844173182 3512234274 260580566
|
||||
1283786540 862453740 208303503
|
||||
3096448926 3303447461 208786813
|
||||
1082093795 1720453805 92617757
|
||||
0 1927813979 3273297
|
||||
|
||||
temperature-to-humidity map:
|
||||
1908382071 0 48093237
|
||||
1668173777 369927146 108464980
|
||||
2454615458 3265918092 19222900
|
||||
2948843885 2383489773 582426713
|
||||
1291899323 304752282 65174864
|
||||
4051886972 3793288156 243080324
|
||||
2849120094 3285140992 99723791
|
||||
2415628816 3186987107 38986642
|
||||
724194709 716571124 379381363
|
||||
1103576072 2070505932 18664072
|
||||
3531270598 1602200086 102620550
|
||||
4020906946 3755760878 30980026
|
||||
1122240144 2285968817 97520956
|
||||
2779959793 1533039785 69160301
|
||||
1357074187 2089170004 196798813
|
||||
1823337263 624772153 85044808
|
||||
561911923 1433912547 99127238
|
||||
2538151277 1095952487 222368482
|
||||
1776638757 709816961 6754163
|
||||
2248869517 1776958859 59989455
|
||||
2760519759 48093237 3497277
|
||||
3770981692 4278303020 16664276
|
||||
3755760878 4263082206 15220814
|
||||
2497298857 263899862 40852420
|
||||
2473838358 1900103862 23460499
|
||||
234010997 51590514 212309348
|
||||
661039161 1836948314 63155548
|
||||
0 1923564361 87630970
|
||||
1219761100 1704820636 72138223
|
||||
87630970 478392126 146380027
|
||||
1956475308 3462247498 171643650
|
||||
3787645968 3786740904 6547252
|
||||
2764017036 2054563175 15942757
|
||||
2171486802 3384864783 77382715
|
||||
446320345 1318320969 115591578
|
||||
1783392920 3225973749 39944343
|
||||
2308858972 2965916486 106769844
|
||||
1553873000 3072686330 114300777
|
||||
3794193220 4036368480 226713726
|
||||
2128118958 2011195331 43367844
|
||||
|
||||
humidity-to-location map:
|
||||
2944942064 3820503519 61983659
|
||||
3834803738 3234323053 106874653
|
||||
2156211251 3962463577 28956273
|
||||
483302901 3882487178 79976399
|
||||
2282996952 2161034243 46548053
|
||||
2629999410 1876993734 225283872
|
||||
3370099006 3129013552 105309501
|
||||
1029930529 620272722 135507476
|
||||
3572091970 2932598747 109287331
|
||||
3739626327 942443797 51739908
|
||||
3311342369 2102277606 58756637
|
||||
3941678391 399929037 136325691
|
||||
1245368468 58880743 172279414
|
||||
790057642 1189404679 239872887
|
||||
1498307968 3341197706 67668316
|
||||
273081010 616914814 3357908
|
||||
2501095485 2803694822 128903925
|
||||
3475408507 4198283833 96683463
|
||||
1860675375 3456652816 219039792
|
||||
245544342 2207582296 27536668
|
||||
3006925723 1666468371 210525363
|
||||
3791366235 3733939634 11933242
|
||||
1165438005 1502653815 79930463
|
||||
1691906495 231160157 168768880
|
||||
1590576804 994183705 101329691
|
||||
2079715167 2235118964 76496084
|
||||
276438918 3991419850 206863983
|
||||
563279300 2507766048 226778342
|
||||
2855283282 3408866022 47786794
|
||||
1565976284 2311615048 24600520
|
||||
3217451086 1095513396 93891283
|
||||
3803299477 1429277566 31504261
|
||||
4161888175 2757743175 45951647
|
||||
2903070076 1460781827 41871988
|
||||
3681379301 3675692608 58247026
|
||||
4207839822 3041886078 87127474
|
||||
2185167524 2734544390 23198785
|
||||
2329545005 2336215568 171550480
|
||||
4078004082 1582584278 83884093
|
||||
1417647882 536254728 80660086
|
||||
58880743 755780198 186663599
|
||||
2208366309 3745872876 74630643
|
||||
338
advent_of_code/2023/5/src/main.rs
Normal file
338
advent_of_code/2023/5/src/main.rs
Normal file
@@ -0,0 +1,338 @@
|
||||
use nom::{
|
||||
bytes::complete::tag,
|
||||
character::complete::{i64, multispace0, multispace1},
|
||||
multi::separated_list1,
|
||||
sequence::{delimited, tuple},
|
||||
IResult, Parser,
|
||||
};
|
||||
|
||||
/// This function assumes your input vector is sorted.
|
||||
/// It might break if this is not the case.
|
||||
/// We don't check if this is actually true, because that would take O(n) time,
|
||||
/// while we aim for this function to only take up O(log n) time.
|
||||
fn binary_search<'a, Item: Ord + Eq>(
|
||||
value_to_find: &Item,
|
||||
vector_to_find_it_in: &'a Vec<Item>,
|
||||
) -> Option<&'a Item> {
|
||||
if vector_to_find_it_in.is_empty() {
|
||||
None
|
||||
} else {
|
||||
let mut index = vector_to_find_it_in.len() / 2;
|
||||
let mut lower = 0;
|
||||
let mut upper = vector_to_find_it_in.len() - 1;
|
||||
while upper != lower {
|
||||
if vector_to_find_it_in[index] <= *value_to_find {
|
||||
upper = index;
|
||||
} else {
|
||||
lower = index;
|
||||
}
|
||||
index = (upper - lower) / 2;
|
||||
}
|
||||
if vector_to_find_it_in[index] == *value_to_find {
|
||||
Some(&vector_to_find_it_in[index])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn give_map_parser<'a: 'b, 'b: 'a>(
|
||||
map_name: &'a str,
|
||||
) -> impl FnMut(&'a str) -> IResult<&'b str, Vec<(i64, i64, i64)>> {
|
||||
delimited(
|
||||
tag(map_name),
|
||||
separated_list1(
|
||||
multispace1,
|
||||
tuple((i64, multispace1, i64, multispace1, i64)).map(|(a, _, b, _, c)| (a, b, c)),
|
||||
),
|
||||
multispace0,
|
||||
)
|
||||
}
|
||||
|
||||
fn parse_input(
|
||||
input: &str,
|
||||
) -> IResult<
|
||||
&str,
|
||||
(
|
||||
Vec<i64>,
|
||||
Vec<(i64, i64, i64)>,
|
||||
Vec<(i64, i64, i64)>,
|
||||
Vec<(i64, i64, i64)>,
|
||||
Vec<(i64, i64, i64)>,
|
||||
Vec<(i64, i64, i64)>,
|
||||
Vec<(i64, i64, i64)>,
|
||||
Vec<(i64, i64, i64)>,
|
||||
),
|
||||
> {
|
||||
let (input, result) = tuple((
|
||||
delimited(tag("seeds: "), separated_list1(tag(" "), i64), multispace1),
|
||||
give_map_parser("seed-to-soil map:\n"),
|
||||
give_map_parser("soil-to-fertilizer map:\n"),
|
||||
give_map_parser("fertilizer-to-water map:\n"),
|
||||
give_map_parser("water-to-light map:\n"),
|
||||
give_map_parser("light-to-temperature map:\n"),
|
||||
give_map_parser("temperature-to-humidity map:\n"),
|
||||
give_map_parser("humidity-to-location map:\n"),
|
||||
))(input)?;
|
||||
|
||||
Ok((input, result))
|
||||
}
|
||||
|
||||
fn destination_to_source_mapping(source: i64, mappings: &Vec<(i64, i64, i64)>) -> i64 {
|
||||
mappings
|
||||
.iter()
|
||||
.filter(|&(_destination_start, source_start, range)| {
|
||||
source >= *source_start && source < *source_start + *range
|
||||
})
|
||||
.next()
|
||||
.map(|(destination_start, source_start, _range)| {
|
||||
destination_start + (source - source_start)
|
||||
})
|
||||
.unwrap_or(source)
|
||||
}
|
||||
|
||||
fn solve_1(
|
||||
almanac: &(
|
||||
Vec<i64>,
|
||||
Vec<(i64, i64, i64)>,
|
||||
Vec<(i64, i64, i64)>,
|
||||
Vec<(i64, i64, i64)>,
|
||||
Vec<(i64, i64, i64)>,
|
||||
Vec<(i64, i64, i64)>,
|
||||
Vec<(i64, i64, i64)>,
|
||||
Vec<(i64, i64, i64)>,
|
||||
),
|
||||
) -> i64 {
|
||||
almanac
|
||||
.0
|
||||
.iter()
|
||||
.map(|&seed| {
|
||||
let soil = destination_to_source_mapping(seed, &almanac.1);
|
||||
let fertilizer = destination_to_source_mapping(soil, &almanac.2);
|
||||
let water = destination_to_source_mapping(fertilizer, &almanac.3);
|
||||
let light = destination_to_source_mapping(water, &almanac.4);
|
||||
let temperature = destination_to_source_mapping(light, &almanac.5);
|
||||
let humidity = destination_to_source_mapping(temperature, &almanac.6);
|
||||
destination_to_source_mapping(humidity, &almanac.7)
|
||||
})
|
||||
.min()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn search_range(
|
||||
input_range: (i64, i64),
|
||||
mappings: &Vec<(i64, i64, i64)>,
|
||||
) -> Option<(i64, i64, i64)> {
|
||||
if mappings.is_empty() {
|
||||
None
|
||||
} else {
|
||||
let mut index = mappings.len() / 2;
|
||||
let mut lower = 0;
|
||||
let mut upper = mappings.len() - 1;
|
||||
|
||||
while upper != lower {
|
||||
if mappings[index].1 <= input_range.0
|
||||
&& mappings[index].1 + mappings[index].2 > input_range.0
|
||||
{
|
||||
return Some(mappings[index]);
|
||||
} else if mappings[index].1 < input_range.0 {
|
||||
lower = index;
|
||||
} else {
|
||||
upper = index - 1;
|
||||
}
|
||||
index = (upper + lower).div_ceil(2);
|
||||
}
|
||||
|
||||
if index >= mappings.len() - 1 && mappings[index].1 + mappings[index].2 < input_range.1 {
|
||||
None
|
||||
} else if mappings[index].1 == input_range.0 {
|
||||
mappings.get(index + 1).copied()
|
||||
} else {
|
||||
Some(mappings[index])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// We will assume the mappings are sorted on the source, so we can more quickly, using binary search, find
|
||||
/// the suitable ranges. This is relevant because of the large numbers involved.
|
||||
fn get_suitable_range(input_range: (i64, i64), mappings: &Vec<(i64, i64, i64)>) -> Vec<(i64, i64)> {
|
||||
let mut found_until = input_range.0;
|
||||
let mut result = vec![];
|
||||
|
||||
while found_until < input_range.1 {
|
||||
println!(
|
||||
"{} {:?} {:?}",
|
||||
found_until,
|
||||
mappings,
|
||||
search_range((found_until, input_range.1), mappings)
|
||||
);
|
||||
if let Some((destination_start, source_start, range)) =
|
||||
search_range((found_until, input_range.1), mappings)
|
||||
{
|
||||
if source_start > found_until {
|
||||
println!("ding");
|
||||
result.push((found_until, std::cmp::min(source_start, input_range.1)));
|
||||
found_until = std::cmp::min(source_start, input_range.1);
|
||||
} else {
|
||||
println!("dong");
|
||||
let max_source = std::cmp::min(source_start + range, input_range.1);
|
||||
result.push((
|
||||
found_until + (destination_start - source_start),
|
||||
destination_start + (max_source - source_start),
|
||||
));
|
||||
found_until = max_source;
|
||||
}
|
||||
} else {
|
||||
println!("dang");
|
||||
result.push((found_until, input_range.1));
|
||||
found_until = input_range.1;
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn get_suitable_ranges(
|
||||
input_ranges: &Vec<(i64, i64)>,
|
||||
mappings: &Vec<(i64, i64, i64)>,
|
||||
) -> Vec<(i64, i64)> {
|
||||
let mut output_ranges_uncompressed = input_ranges
|
||||
.iter()
|
||||
.map(|&(range_start, range_length)| {
|
||||
get_suitable_range((range_start, range_start + range_length), mappings)
|
||||
})
|
||||
.collect::<Vec<Vec<(i64, i64)>>>()
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.collect::<Vec<(i64, i64)>>();
|
||||
|
||||
output_ranges_uncompressed.sort_unstable();
|
||||
let (mut lower, mut upper) = output_ranges_uncompressed[0];
|
||||
|
||||
let mut output_ranges = vec![];
|
||||
for (range_low, range_up) in output_ranges_uncompressed {
|
||||
if range_low <= upper {
|
||||
upper = range_up;
|
||||
} else {
|
||||
output_ranges.push((lower, upper));
|
||||
lower = range_low;
|
||||
upper = range_up;
|
||||
}
|
||||
}
|
||||
output_ranges.push((lower, upper));
|
||||
output_ranges = output_ranges
|
||||
.iter()
|
||||
.map(|&(range_start, range_end)| (range_start, range_end - range_start))
|
||||
.collect::<Vec<_>>();
|
||||
output_ranges
|
||||
}
|
||||
|
||||
fn solve_2(
|
||||
almanac: &(
|
||||
Vec<i64>,
|
||||
Vec<(i64, i64, i64)>,
|
||||
Vec<(i64, i64, i64)>,
|
||||
Vec<(i64, i64, i64)>,
|
||||
Vec<(i64, i64, i64)>,
|
||||
Vec<(i64, i64, i64)>,
|
||||
Vec<(i64, i64, i64)>,
|
||||
Vec<(i64, i64, i64)>,
|
||||
),
|
||||
) -> i64 {
|
||||
let mut lowest_location_numbers = vec![];
|
||||
let mut seed_iter = almanac.0.iter();
|
||||
|
||||
let mut soil_almanac = almanac.1.iter().map(|&n| n).collect::<Vec<_>>();
|
||||
soil_almanac.sort_unstable_by(|&(_d1, source1, _r1), (_d2, source2, _r2)| source1.cmp(source2));
|
||||
let mut fertilizer_almanac = almanac.2.iter().map(|&n| n).collect::<Vec<_>>();
|
||||
fertilizer_almanac
|
||||
.sort_unstable_by(|&(_d1, source1, _r1), (_d2, source2, _r2)| source1.cmp(source2));
|
||||
let mut water_almanac = almanac.3.iter().map(|&n| n).collect::<Vec<_>>();
|
||||
water_almanac
|
||||
.sort_unstable_by(|&(_d1, source1, _r1), (_d2, source2, _r2)| source1.cmp(source2));
|
||||
let mut light_almanac = almanac.4.iter().map(|&n| n).collect::<Vec<_>>();
|
||||
light_almanac
|
||||
.sort_unstable_by(|&(_d1, source1, _r1), (_d2, source2, _r2)| source1.cmp(source2));
|
||||
let mut temperature_almanac = almanac.5.iter().map(|&n| n).collect::<Vec<_>>();
|
||||
temperature_almanac
|
||||
.sort_unstable_by(|&(_d1, source1, _r1), (_d2, source2, _r2)| source1.cmp(source2));
|
||||
let mut humidity_almanac = almanac.6.iter().map(|&n| n).collect::<Vec<_>>();
|
||||
humidity_almanac
|
||||
.sort_unstable_by(|&(_d1, source1, _r1), (_d2, source2, _r2)| source1.cmp(source2));
|
||||
let mut location_almanac = almanac.7.iter().map(|&n| n).collect::<Vec<_>>();
|
||||
location_almanac
|
||||
.sort_unstable_by(|&(_d1, source1, _r1), (_d2, source2, _r2)| source1.cmp(source2));
|
||||
|
||||
while let (Some(&lower_seed), Some(&range_length)) = (seed_iter.next(), seed_iter.next()) {
|
||||
println!("ding");
|
||||
let seed_range = vec![(lower_seed, range_length)];
|
||||
let soil_ranges = get_suitable_ranges(&seed_range, &soil_almanac);
|
||||
println!("soil");
|
||||
|
||||
let fertilizer_ranges = get_suitable_ranges(&soil_ranges, &fertilizer_almanac);
|
||||
println!("fertilizer");
|
||||
|
||||
let water_ranges = get_suitable_ranges(&fertilizer_ranges, &water_almanac);
|
||||
println!("water");
|
||||
|
||||
let light_ranges = get_suitable_ranges(&water_ranges, &light_almanac);
|
||||
println!("light");
|
||||
|
||||
let temperature_ranges = get_suitable_ranges(&light_ranges, &temperature_almanac);
|
||||
println!("temperature");
|
||||
|
||||
let humidity_ranges = get_suitable_ranges(&temperature_ranges, &humidity_almanac);
|
||||
println!("humidity");
|
||||
|
||||
lowest_location_numbers.push(
|
||||
get_suitable_ranges(&humidity_ranges, &location_almanac)
|
||||
.iter()
|
||||
.map(|&(range_min, _range_max)| range_min)
|
||||
.min()
|
||||
.unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
*lowest_location_numbers.iter().min().unwrap()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("Hello, this is Patrick!");
|
||||
|
||||
let input_text = include_str!("../input.txt");
|
||||
|
||||
let (_, almanac) = parse_input(input_text).unwrap();
|
||||
|
||||
println!(
|
||||
"The lowest location number corresponding to the initial seed numbers is {}",
|
||||
solve_1(&almanac)
|
||||
);
|
||||
|
||||
println!(
|
||||
"The lowest location number for any of the initial seed ranges is {}",
|
||||
solve_2(&almanac)
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_1() {
|
||||
let input_text = include_str!("../test_input.txt");
|
||||
|
||||
let (_, almanac) = parse_input(input_text).unwrap();
|
||||
|
||||
assert_eq!(solve_1(&almanac), 35);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_2() {
|
||||
let input_text = include_str!("../test_input.txt");
|
||||
|
||||
let (_, almanac) = parse_input(input_text).unwrap();
|
||||
|
||||
assert_eq!(solve_2(&almanac), 46);
|
||||
}
|
||||
}
|
||||
33
advent_of_code/2023/5/test_input.txt
Normal file
33
advent_of_code/2023/5/test_input.txt
Normal file
@@ -0,0 +1,33 @@
|
||||
seeds: 79 14 55 13
|
||||
|
||||
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
|
||||
7
advent_of_code/2023/7/Cargo.toml
Normal file
7
advent_of_code/2023/7/Cargo.toml
Normal file
@@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "main"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
nom = "7.1.3"
|
||||
1000
advent_of_code/2023/7/input.txt
Normal file
1000
advent_of_code/2023/7/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
263
advent_of_code/2023/7/src/main.rs
Normal file
263
advent_of_code/2023/7/src/main.rs
Normal file
@@ -0,0 +1,263 @@
|
||||
use std::{cmp::Ordering, collections::HashMap, iter::zip};
|
||||
|
||||
use nom::{
|
||||
character::complete::{alphanumeric1, multispace1, u64},
|
||||
multi::separated_list1,
|
||||
sequence::separated_pair,
|
||||
IResult, Parser,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
enum HandType {
|
||||
HighCard,
|
||||
OnePair,
|
||||
TwoPair,
|
||||
ThreeKind,
|
||||
FullHouse,
|
||||
FourKind,
|
||||
FiveKind,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
enum CardType {
|
||||
Two,
|
||||
Three,
|
||||
Four,
|
||||
Five,
|
||||
Six,
|
||||
Seven,
|
||||
Eight,
|
||||
Nine,
|
||||
T,
|
||||
Jack,
|
||||
Queen,
|
||||
King,
|
||||
Ace,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
enum CardType2 {
|
||||
Jack,
|
||||
Two,
|
||||
Three,
|
||||
Four,
|
||||
Five,
|
||||
Six,
|
||||
Seven,
|
||||
Eight,
|
||||
Nine,
|
||||
T,
|
||||
Queen,
|
||||
King,
|
||||
Ace,
|
||||
}
|
||||
|
||||
fn parse_input(input: &str) -> IResult<&str, Vec<(String, u64)>> {
|
||||
let (input, result) = separated_list1(
|
||||
multispace1,
|
||||
separated_pair(alphanumeric1::<&str, _>, multispace1, u64)
|
||||
.map(|(hand, bid)| (hand.to_string(), bid)),
|
||||
)(input)?;
|
||||
|
||||
Ok((input, result))
|
||||
}
|
||||
|
||||
fn classify_hand(hand: &String) -> HandType {
|
||||
use HandType::*;
|
||||
|
||||
let mut card_numbers: HashMap<char, i32> = HashMap::new();
|
||||
for c in hand.to_owned().chars() {
|
||||
card_numbers.insert(
|
||||
c,
|
||||
match card_numbers.get(&c) {
|
||||
Some(n) => n + 1,
|
||||
None => 1,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
let mut card_numbers = card_numbers.values().collect::<Vec<_>>();
|
||||
card_numbers.sort_unstable();
|
||||
match card_numbers[..] {
|
||||
[1, 1, 1, 1, 1] => HighCard,
|
||||
[1, 1, 1, 2] => OnePair,
|
||||
[1, 2, 2] => TwoPair,
|
||||
[1, 1, 3] => ThreeKind,
|
||||
[2, 3] => FullHouse,
|
||||
[1, 4] => FourKind,
|
||||
[5] => FiveKind,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn classify_hand2(hand: &String) -> HandType {
|
||||
use HandType::*;
|
||||
|
||||
let mut card_numbers: HashMap<char, i32> = HashMap::new();
|
||||
for c in hand.to_owned().chars() {
|
||||
card_numbers.insert(
|
||||
c,
|
||||
match card_numbers.get(&c) {
|
||||
Some(n) => n + 1,
|
||||
None => 1,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(jokers) = card_numbers.remove(&'J') {
|
||||
let mut card_numbers = card_numbers.values().collect::<Vec<_>>();
|
||||
card_numbers.sort_unstable();
|
||||
let highest = card_numbers.pop().unwrap_or(&0) + jokers;
|
||||
card_numbers.push(&highest);
|
||||
|
||||
match card_numbers[..] {
|
||||
[1, 1, 1, 2] => OnePair,
|
||||
[1, 1, 3] => ThreeKind,
|
||||
[2, 3] => FullHouse,
|
||||
[1, 4] => FourKind,
|
||||
[5] => FiveKind,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
} else {
|
||||
let mut card_numbers = card_numbers.values().collect::<Vec<_>>();
|
||||
card_numbers.sort_unstable();
|
||||
match card_numbers[..] {
|
||||
[1, 1, 1, 1, 1] => HighCard,
|
||||
[1, 1, 1, 2] => OnePair,
|
||||
[1, 2, 2] => TwoPair,
|
||||
[1, 1, 3] => ThreeKind,
|
||||
[2, 3] => FullHouse,
|
||||
[1, 4] => FourKind,
|
||||
[5] => FiveKind,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn classify_card(card: char) -> CardType {
|
||||
use CardType::*;
|
||||
|
||||
match card {
|
||||
'A' => Ace,
|
||||
'K' => King,
|
||||
'Q' => Queen,
|
||||
'J' => Jack,
|
||||
'T' => T,
|
||||
'9' => Nine,
|
||||
'8' => Eight,
|
||||
'7' => Seven,
|
||||
'6' => Six,
|
||||
'5' => Five,
|
||||
'4' => Four,
|
||||
'3' => Three,
|
||||
'2' => Two,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn classify_card2(card: char) -> CardType2 {
|
||||
use CardType2::*;
|
||||
|
||||
match card {
|
||||
'A' => Ace,
|
||||
'K' => King,
|
||||
'Q' => Queen,
|
||||
'T' => T,
|
||||
'9' => Nine,
|
||||
'8' => Eight,
|
||||
'7' => Seven,
|
||||
'6' => Six,
|
||||
'5' => Five,
|
||||
'4' => Four,
|
||||
'3' => Three,
|
||||
'2' => Two,
|
||||
'J' => Jack,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn compare_hands(hand_1: &String, hand_2: &String) -> Ordering {
|
||||
let (hand_type_1, hand_type_2) = (classify_hand(hand_1), classify_hand(hand_2));
|
||||
if hand_type_1 == hand_type_2 {
|
||||
for (card_1, card_2) in zip(hand_1.to_owned().chars(), hand_2.to_owned().chars()) {
|
||||
if card_1 != card_2 {
|
||||
return classify_card(card_1).cmp(&classify_card(card_2));
|
||||
}
|
||||
}
|
||||
Ordering::Equal
|
||||
} else {
|
||||
hand_type_1.cmp(&hand_type_2)
|
||||
}
|
||||
}
|
||||
|
||||
fn compare_hands2(hand_1: &String, hand_2: &String) -> Ordering {
|
||||
let (hand_type_1, hand_type_2) = (classify_hand2(hand_1), classify_hand2(hand_2));
|
||||
if hand_type_1 == hand_type_2 {
|
||||
for (card_1, card_2) in zip(hand_1.to_owned().chars(), hand_2.to_owned().chars()) {
|
||||
if card_1 != card_2 {
|
||||
return classify_card2(card_1).cmp(&classify_card2(card_2));
|
||||
}
|
||||
}
|
||||
Ordering::Equal
|
||||
} else {
|
||||
hand_type_1.cmp(&hand_type_2)
|
||||
}
|
||||
}
|
||||
|
||||
fn solve_1(plays: &Vec<(String, u64)>) -> u64 {
|
||||
let mut plays = plays.clone();
|
||||
|
||||
plays.sort_unstable_by(|(hand_1, _bid1), (hand_2, _bid2)| compare_hands(hand_1, hand_2));
|
||||
|
||||
plays
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(rank, (_hand, bid))| (rank as u64 + 1) * bid)
|
||||
.sum()
|
||||
}
|
||||
|
||||
fn solve_2(plays: &Vec<(String, u64)>) -> u64 {
|
||||
let mut plays = plays.clone();
|
||||
|
||||
plays.sort_unstable_by(|(hand_1, _bid1), (hand_2, _bid2)| compare_hands2(hand_1, hand_2));
|
||||
|
||||
plays
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(rank, (_hand, bid))| (rank as u64 + 1) * bid)
|
||||
.sum()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("Hello, this is Patrick!");
|
||||
|
||||
let input_text = include_str!("../input.txt");
|
||||
|
||||
let (_, plays) = parse_input(input_text).unwrap();
|
||||
|
||||
println!("The total winnings are {}", solve_1(&plays));
|
||||
println!("The new total winnings are {}", solve_2(&plays));
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_1() {
|
||||
let input_text = include_str!("../test_input.txt");
|
||||
|
||||
let (_, plays) = parse_input(input_text).unwrap();
|
||||
|
||||
assert_eq!(solve_1(&plays), 6440);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_2() {
|
||||
let input_text = include_str!("../test_input.txt");
|
||||
|
||||
let (_, plays) = parse_input(input_text).unwrap();
|
||||
|
||||
assert_eq!(solve_2(&plays), 5905);
|
||||
}
|
||||
}
|
||||
5
advent_of_code/2023/7/test_input.txt
Normal file
5
advent_of_code/2023/7/test_input.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
32T3K 765
|
||||
T55J5 684
|
||||
KK677 28
|
||||
KTJJT 220
|
||||
QQQJA 483
|
||||
Reference in New Issue
Block a user