Compare commits
2 Commits
180faf92bb
...
master
Author | SHA1 | Date | |
---|---|---|---|
f2506f91ba | |||
46165b1acb |
190
input/year2023/day05.txt
Normal file
190
input/year2023/day05.txt
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
seeds: 2906961955 52237479 1600322402 372221628 2347782594 164705568 541904540 89745770 126821306 192539923 3411274151 496169308 919015581 8667739 654599767 160781040 3945616935 85197451 999146581 344584779
|
||||||
|
|
||||||
|
seed-to-soil map:
|
||||||
|
2328388605 1716277852 240111965
|
||||||
|
3183744888 3056742994 1057221520
|
||||||
|
0 1574488136 141789716
|
||||||
|
886579086 0 430196980
|
||||||
|
141789716 2525350732 49125971
|
||||||
|
881053613 1956389817 5525473
|
||||||
|
3131936012 3013025394 43717600
|
||||||
|
629464378 1322898901 251589235
|
||||||
|
2568500570 1961915290 563435442
|
||||||
|
190915687 2574476703 438548691
|
||||||
|
3175653612 4113964514 8091276
|
||||||
|
1435686684 430196980 892701921
|
||||||
|
1316776066 4122055790 118910618
|
||||||
|
|
||||||
|
soil-to-fertilizer map:
|
||||||
|
0 847324382 159395290
|
||||||
|
1690371026 1633839702 81823607
|
||||||
|
1942873068 561308539 283153025
|
||||||
|
702170285 347687930 213620609
|
||||||
|
477747447 1412279682 221560020
|
||||||
|
1284811016 1006719672 253212372
|
||||||
|
2226026093 170678435 177009495
|
||||||
|
3187826244 2792977617 352243190
|
||||||
|
4225283470 3206651416 69683826
|
||||||
|
2970405965 3691658787 56026212
|
||||||
|
1538023388 1259932044 152347638
|
||||||
|
1772194633 0 170678435
|
||||||
|
3540069434 3376298700 315360087
|
||||||
|
159395290 2084683431 318352157
|
||||||
|
915790894 1715663309 369020122
|
||||||
|
2792977617 4117538948 177428348
|
||||||
|
3026432177 3145220807 61430609
|
||||||
|
699307467 844461564 2862818
|
||||||
|
3855429521 3747684999 21637270
|
||||||
|
3877066791 3769322269 348216679
|
||||||
|
3087862786 3276335242 99963458
|
||||||
|
|
||||||
|
fertilizer-to-water map:
|
||||||
|
1957494254 3160765597 68123328
|
||||||
|
3668612865 2055686861 40068724
|
||||||
|
435525860 0 215171709
|
||||||
|
417459051 715121035 18066809
|
||||||
|
3249874551 2634587998 121218972
|
||||||
|
3537356195 3926770979 26944785
|
||||||
|
409490069 215171709 7968982
|
||||||
|
3247878798 2456653359 1995753
|
||||||
|
152557237 570466650 62164110
|
||||||
|
0 223140691 152557237
|
||||||
|
3740494262 3322870672 151571624
|
||||||
|
4127559328 2467180030 146770000
|
||||||
|
2244919185 2003747275 51939586
|
||||||
|
1782523793 2281682898 174970461
|
||||||
|
829840892 2458649112 8530918
|
||||||
|
3415930152 2819793210 9616809
|
||||||
|
3451260386 2162555289 86095809
|
||||||
|
650697569 632630760 82490275
|
||||||
|
1725834205 787129181 30553919
|
||||||
|
2298219434 2095755585 66799704
|
||||||
|
4274329328 2613950030 20637968
|
||||||
|
2025617582 4242693061 52274235
|
||||||
|
3564300980 2248651098 31671137
|
||||||
|
2296858771 2280322235 1360663
|
||||||
|
3162226157 4125227747 85652641
|
||||||
|
1564565599 1911070479 92676796
|
||||||
|
3892065886 3691277537 235493442
|
||||||
|
3371093523 1848297376 44836629
|
||||||
|
1187663862 1437436130 376901737
|
||||||
|
1689179378 2755806970 36654827
|
||||||
|
2077891817 1238471779 167027368
|
||||||
|
2365019138 2792461797 27331413
|
||||||
|
2678412296 3953715764 63025182
|
||||||
|
2741437478 817683100 420788679
|
||||||
|
2461577055 3474442296 216835241
|
||||||
|
787129181 3228888925 21340999
|
||||||
|
3595972117 3250229924 72640748
|
||||||
|
838371810 2829410019 331355578
|
||||||
|
3425546961 4085967450 25713425
|
||||||
|
1657242395 1405499147 31936983
|
||||||
|
3708681589 4210880388 31812673
|
||||||
|
1756388124 4111680875 13546872
|
||||||
|
1169727388 1893134005 17936474
|
||||||
|
2392350551 4016740946 69226504
|
||||||
|
808470180 1826926664 21370712
|
||||||
|
218943670 379920251 190546399
|
||||||
|
214721347 375697928 4222323
|
||||||
|
1769934996 1814337867 12588797
|
||||||
|
|
||||||
|
water-to-light map:
|
||||||
|
3411019791 3038265544 83843899
|
||||||
|
1902872961 1862724448 39203216
|
||||||
|
3968365807 2753393749 138464731
|
||||||
|
1729762115 1614300400 173110846
|
||||||
|
3494863690 3122109443 473502117
|
||||||
|
423365393 445887946 9248183
|
||||||
|
2869853730 3595611560 11542547
|
||||||
|
910597576 2054510840 169422772
|
||||||
|
609563085 2589844190 163549559
|
||||||
|
2522382340 1299215911 3599854
|
||||||
|
2525982194 609563085 139503131
|
||||||
|
131438599 455136129 141314541
|
||||||
|
4106830538 3607154107 188136758
|
||||||
|
2106420951 2290083024 299761166
|
||||||
|
2406182117 966254850 82053377
|
||||||
|
1157660094 1302815765 172746664
|
||||||
|
97774358 248386611 33664241
|
||||||
|
432613576 282050852 163837094
|
||||||
|
2835557666 1794281538 34296064
|
||||||
|
1953837775 2043524684 10986156
|
||||||
|
1964823931 1901927664 141597020
|
||||||
|
2881396277 749066216 217188634
|
||||||
|
3404149499 1787411246 6870292
|
||||||
|
1330406758 3795290865 240494284
|
||||||
|
773112644 4035785149 137484932
|
||||||
|
3282452284 4173270081 121697215
|
||||||
|
2665485325 3001382926 36882618
|
||||||
|
272753140 97774358 150612253
|
||||||
|
0 38271406 59502952
|
||||||
|
3098584911 1115348538 183867373
|
||||||
|
1570901042 2938014447 31884700
|
||||||
|
1942076177 1602538802 11761598
|
||||||
|
2488235494 1828577602 34146846
|
||||||
|
1080020348 2969899147 31483779
|
||||||
|
1602785742 1475562429 126976373
|
||||||
|
1111504127 2891858480 46155967
|
||||||
|
2768517355 1048308227 67040311
|
||||||
|
59502952 0 38271406
|
||||||
|
2702367943 2223933612 66149412
|
||||||
|
|
||||||
|
light-to-temperature map:
|
||||||
|
2325040309 318068442 41526915
|
||||||
|
3863810956 4139509244 32531846
|
||||||
|
3695021342 4093645836 45863408
|
||||||
|
3176344157 3053768010 518677185
|
||||||
|
2214303174 207331307 110737135
|
||||||
|
1166404663 0 207331307
|
||||||
|
3896342802 3761428671 206212717
|
||||||
|
216675148 359595357 47363132
|
||||||
|
4102555519 3967641388 126004448
|
||||||
|
264038280 406958489 888098871
|
||||||
|
4228559967 3572445195 66407329
|
||||||
|
1152137151 1295057360 14267512
|
||||||
|
3053768010 3638852524 122576147
|
||||||
|
1373735970 1526000020 840567204
|
||||||
|
0 1309324872 216675148
|
||||||
|
3740884750 4172041090 122926206
|
||||||
|
|
||||||
|
temperature-to-humidity map:
|
||||||
|
0 1391213880 85308204
|
||||||
|
3458067104 3613119976 31521054
|
||||||
|
1325453299 1240145095 151068785
|
||||||
|
4139914424 3458067104 155052872
|
||||||
|
1271510819 1186202615 53942480
|
||||||
|
85308204 0 1186202615
|
||||||
|
3489588158 3644641030 650326266
|
||||||
|
|
||||||
|
humidity-to-location map:
|
||||||
|
167312469 2495357077 210182350
|
||||||
|
1429747769 3808500825 68802537
|
||||||
|
2550869359 1829966489 80945905
|
||||||
|
1243007130 3610450429 186740639
|
||||||
|
1735537822 990200552 68491638
|
||||||
|
2426758858 2125855270 111895863
|
||||||
|
1637338839 2027656287 98198983
|
||||||
|
3109292740 3306673452 735862
|
||||||
|
3647611593 2386885260 96257179
|
||||||
|
3910495658 3919394548 32743716
|
||||||
|
3860612665 3289982755 16690697
|
||||||
|
3743868772 1910912394 116743893
|
||||||
|
1498550306 2705539427 138788533
|
||||||
|
0 1662654020 167312469
|
||||||
|
2631815264 512723076 477477476
|
||||||
|
836912419 1370893553 291760467
|
||||||
|
2271993218 3307409314 154765640
|
||||||
|
4136363029 3910495658 8898890
|
||||||
|
377494819 3797191068 11309757
|
||||||
|
1804029460 1058692190 209661300
|
||||||
|
836150842 3517760656 761577
|
||||||
|
3110028602 3518522233 91928196
|
||||||
|
2538654721 2483142439 12214638
|
||||||
|
687016715 2237751133 149134127
|
||||||
|
3201956798 2844327960 445654795
|
||||||
|
1128672886 1268353490 102540063
|
||||||
|
2057482281 0 214510937
|
||||||
|
388804576 214510937 298212139
|
||||||
|
1231212949 3505966475 11794181
|
||||||
|
2013690760 3462174954 43791521
|
||||||
|
3943239374 3952138264 193123655
|
2
input/year2023/day06.txt
Normal file
2
input/year2023/day06.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
Time: 51 92 68 90
|
||||||
|
Distance: 222 2031 1126 1225
|
@@ -24,4 +24,6 @@ pub mod year2023 {
|
|||||||
pub mod day02;
|
pub mod day02;
|
||||||
pub mod day03;
|
pub mod day03;
|
||||||
pub mod day04;
|
pub mod day04;
|
||||||
|
pub mod day05;
|
||||||
|
pub mod day06;
|
||||||
}
|
}
|
||||||
|
@@ -12,8 +12,8 @@ struct Solution {
|
|||||||
macro_rules! solution {
|
macro_rules! solution {
|
||||||
($year:tt, $day:tt) => {
|
($year:tt, $day:tt) => {
|
||||||
Solution {
|
Solution {
|
||||||
year: (&stringify!($year)).parse_u32(),
|
year: (&stringify!($year)).parse_unsigned::<u32>(),
|
||||||
day: (&stringify!($day)).parse_u32(),
|
day: (&stringify!($day)).parse_unsigned::<u32>(),
|
||||||
input: include_str!(concat![
|
input: include_str!(concat![
|
||||||
"../input/",
|
"../input/",
|
||||||
stringify!($year),
|
stringify!($year),
|
||||||
@@ -38,7 +38,7 @@ macro_rules! solution {
|
|||||||
fn main() {
|
fn main() {
|
||||||
let (year, day) = match std::env::args().nth(1) {
|
let (year, day) = match std::env::args().nth(1) {
|
||||||
Some(arg) => {
|
Some(arg) => {
|
||||||
let mut split = arg.split("::").map(|s| s.parse_u32());
|
let mut split = arg.split("::").map(|s| s.parse_unsigned());
|
||||||
(split.next(), split.next())
|
(split.next(), split.next())
|
||||||
}
|
}
|
||||||
None => (None, None),
|
None => (None, None),
|
||||||
@@ -99,5 +99,7 @@ fn year2023() -> Vec<Solution> {
|
|||||||
solution!(year2023, day02),
|
solution!(year2023, day02),
|
||||||
solution!(year2023, day03),
|
solution!(year2023, day03),
|
||||||
solution!(year2023, day04),
|
solution!(year2023, day04),
|
||||||
|
solution!(year2023, day05),
|
||||||
|
solution!(year2023, day06),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@@ -1,74 +1,133 @@
|
|||||||
|
use std::marker::PhantomData;
|
||||||
use std::str::Bytes;
|
use std::str::Bytes;
|
||||||
|
|
||||||
pub struct U32s<'a> {
|
pub trait IsSigned {}
|
||||||
|
|
||||||
|
impl IsSigned for i8 {}
|
||||||
|
impl IsSigned for i16 {}
|
||||||
|
impl IsSigned for i32 {}
|
||||||
|
impl IsSigned for i64 {}
|
||||||
|
impl IsSigned for i128 {}
|
||||||
|
impl IsSigned for isize {}
|
||||||
|
|
||||||
|
pub trait IsUnsigned {}
|
||||||
|
|
||||||
|
impl IsUnsigned for u8 {}
|
||||||
|
impl IsUnsigned for u16 {}
|
||||||
|
impl IsUnsigned for u32 {}
|
||||||
|
impl IsUnsigned for u64 {}
|
||||||
|
impl IsUnsigned for u128 {}
|
||||||
|
impl IsUnsigned for usize {}
|
||||||
|
|
||||||
|
pub struct Signed<'a, T = i64>
|
||||||
|
where
|
||||||
|
T: Add<Output = T> + Mul<Output = T> + TryFrom<i32> + TryFrom<u8> + IsSigned,
|
||||||
|
{
|
||||||
bytes: Bytes<'a>,
|
bytes: Bytes<'a>,
|
||||||
|
_phantom: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Iterator for U32s<'a> {
|
impl<'a, T> Iterator for Signed<'a, T>
|
||||||
type Item = u32;
|
where
|
||||||
|
T: Add<Output = T> + Mul<Output = T> + TryFrom<i32> + TryFrom<u8> + IsSigned,
|
||||||
|
{
|
||||||
|
type Item = T;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
try_parse_u32(&mut self.bytes)
|
try_parse_signed::<T>(&mut self.bytes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct I32s<'a> {
|
pub struct Unsigned<'a, T = u64>
|
||||||
|
where
|
||||||
|
T: Add<Output = T> + Mul<Output = T> + TryFrom<u8> + IsUnsigned,
|
||||||
|
{
|
||||||
bytes: Bytes<'a>,
|
bytes: Bytes<'a>,
|
||||||
|
_phantom: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Iterator for I32s<'a> {
|
impl<'a, T> Iterator for Unsigned<'a, T>
|
||||||
type Item = i32;
|
where
|
||||||
|
T: Add<Output = T> + Mul<Output = T> + TryFrom<u8> + IsUnsigned,
|
||||||
|
{
|
||||||
|
type Item = T;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
try_parse_i32(&mut self.bytes)
|
try_parse_unsigned::<T>(&mut self.bytes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ParseExt {
|
pub trait ParseExt {
|
||||||
fn parse_u32(&self) -> u32;
|
fn parse_signed<T>(&self) -> T
|
||||||
|
where
|
||||||
|
T: Add<Output = T> + Mul<Output = T> + TryFrom<i32> + TryFrom<u8> + IsSigned;
|
||||||
|
|
||||||
fn u32s(&self) -> U32s<'_>;
|
fn parse_unsigned<T>(&self) -> T
|
||||||
|
where
|
||||||
|
T: Add<Output = T> + Mul<Output = T> + TryFrom<u8> + IsUnsigned;
|
||||||
|
|
||||||
fn parse_i32(&self) -> i32;
|
fn signed<T>(&self) -> Signed<'_, T>
|
||||||
|
where
|
||||||
|
T: Add<Output = T> + Mul<Output = T> + TryFrom<i32> + TryFrom<u8> + IsSigned;
|
||||||
|
|
||||||
fn i32s(&self) -> I32s<'_>;
|
fn unsigned<T>(&self) -> Unsigned<'_, T>
|
||||||
|
where
|
||||||
|
T: Add<Output = T> + Mul<Output = T> + TryFrom<u8> + IsUnsigned;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParseExt for &str {
|
impl ParseExt for &str {
|
||||||
fn parse_u32(&self) -> u32 {
|
fn signed<T>(&self) -> Signed<'_, T>
|
||||||
match try_parse_u32(&mut self.bytes()) {
|
where
|
||||||
Some(num) => num,
|
T: Add<Output = T> + Mul<Output = T> + TryFrom<i32> + TryFrom<u8> + IsSigned,
|
||||||
None => panic!("unable to parse u32: {self}"),
|
{
|
||||||
}
|
Signed {
|
||||||
}
|
|
||||||
|
|
||||||
fn u32s(&self) -> U32s<'_> {
|
|
||||||
U32s {
|
|
||||||
bytes: self.bytes(),
|
bytes: self.bytes(),
|
||||||
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_i32(&self) -> i32 {
|
fn parse_signed<T>(&self) -> T
|
||||||
match try_parse_i32(&mut self.bytes()) {
|
where
|
||||||
|
T: Add<Output = T> + Mul<Output = T> + TryFrom<i32> + TryFrom<u8> + IsSigned,
|
||||||
|
{
|
||||||
|
match try_parse_signed(&mut self.bytes()) {
|
||||||
Some(num) => num,
|
Some(num) => num,
|
||||||
None => panic!("unable to parse i32: {self}"),
|
None => panic!("unable to parse signed: {self}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn i32s(&self) -> I32s<'_> {
|
fn unsigned<T>(&self) -> Unsigned<'_, T>
|
||||||
I32s {
|
where
|
||||||
|
T: Add<Output = T> + Mul<Output = T> + TryFrom<u8> + IsUnsigned,
|
||||||
|
{
|
||||||
|
Unsigned {
|
||||||
bytes: self.bytes(),
|
bytes: self.bytes(),
|
||||||
|
_phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_unsigned<T>(&self) -> T
|
||||||
|
where
|
||||||
|
T: Add<Output = T> + Mul<Output = T> + TryFrom<u8> + IsUnsigned,
|
||||||
|
{
|
||||||
|
match try_parse_unsigned(&mut self.bytes()) {
|
||||||
|
Some(num) => num,
|
||||||
|
None => panic!("unable to parse signed: {self}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_parse_u32(bytes: &mut Bytes<'_>) -> Option<u32> {
|
use std::ops::{Add, Mul};
|
||||||
|
fn try_parse_unsigned<T>(bytes: &mut Bytes<'_>) -> Option<T>
|
||||||
|
where
|
||||||
|
T: Add<Output = T> + Mul<Output = T> + TryFrom<u8> + IsUnsigned,
|
||||||
|
{
|
||||||
let mut n = loop {
|
let mut n = loop {
|
||||||
let byte = bytes.next()?;
|
let byte = bytes.next()?;
|
||||||
let digit = byte.wrapping_sub(b'0');
|
let digit = byte.wrapping_sub(b'0');
|
||||||
|
|
||||||
if digit < 10 {
|
if digit < 10 {
|
||||||
break digit as u32;
|
break T::try_from(digit).unwrap_or_else(|_| unreachable!());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -79,29 +138,33 @@ fn try_parse_u32(bytes: &mut Bytes<'_>) -> Option<u32> {
|
|||||||
let digit = byte.wrapping_sub(b'0');
|
let digit = byte.wrapping_sub(b'0');
|
||||||
|
|
||||||
if digit < 10 {
|
if digit < 10 {
|
||||||
n = 10 * n + digit as u32;
|
n = T::try_from(10).unwrap_or_else(|_| unreachable!()) * n
|
||||||
|
+ T::try_from(digit).unwrap_or_else(|_| unreachable!());
|
||||||
} else {
|
} else {
|
||||||
break Some(n);
|
break Some(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_parse_i32(bytes: &mut Bytes<'_>) -> Option<i32> {
|
fn try_parse_signed<T>(bytes: &mut Bytes<'_>) -> Option<T>
|
||||||
let mut fac = 1;
|
where
|
||||||
|
T: Add<Output = T> + Mul<Output = T> + TryFrom<i32> + TryFrom<u8> + IsSigned,
|
||||||
|
{
|
||||||
|
let mut fac = T::try_from(1i32).unwrap_or_else(|_| unreachable!());
|
||||||
let mut n = loop {
|
let mut n = loop {
|
||||||
let byte = bytes.next()?;
|
let byte = bytes.next()?;
|
||||||
if byte == b'-' {
|
if byte == b'-' {
|
||||||
let byte = bytes.next()?;
|
let byte = bytes.next()?;
|
||||||
let digit = byte.wrapping_sub(b'0');
|
let digit = byte.wrapping_sub(b'0');
|
||||||
if digit < 10 {
|
if digit < 10 {
|
||||||
fac = -1;
|
fac = T::try_from(-1i32).unwrap_or_else(|_| unreachable!());
|
||||||
break digit as i32;
|
break T::try_from(digit).unwrap_or_else(|_| unreachable!());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let digit = byte.wrapping_sub(b'0');
|
let digit = byte.wrapping_sub(b'0');
|
||||||
|
|
||||||
if digit < 10 {
|
if digit < 10 {
|
||||||
break digit as i32;
|
break T::try_from(digit).unwrap_or_else(|_| unreachable!());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -112,7 +175,8 @@ fn try_parse_i32(bytes: &mut Bytes<'_>) -> Option<i32> {
|
|||||||
let digit = byte.wrapping_sub(b'0');
|
let digit = byte.wrapping_sub(b'0');
|
||||||
|
|
||||||
if digit < 10 {
|
if digit < 10 {
|
||||||
n = 10 * n + digit as i32;
|
n = T::try_from(10).unwrap_or_else(|_| unreachable!()) * n
|
||||||
|
+ T::try_from(digit).unwrap_or_else(|_| unreachable!());
|
||||||
} else {
|
} else {
|
||||||
break Some(n * fac);
|
break Some(n * fac);
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,7 @@ use crate::util::{index::*, parse::ParseExt};
|
|||||||
|
|
||||||
fn parse(input: &str) -> impl Iterator<Item = (u8, u32)> + '_ {
|
fn parse(input: &str) -> impl Iterator<Item = (u8, u32)> + '_ {
|
||||||
let dirs = input.bytes().filter(u8::is_ascii_uppercase);
|
let dirs = input.bytes().filter(u8::is_ascii_uppercase);
|
||||||
let steps: Vec<_> = input.u32s().collect();
|
let steps: Vec<_> = input.unsigned().collect();
|
||||||
|
|
||||||
dirs.zip(steps)
|
dirs.zip(steps)
|
||||||
}
|
}
|
||||||
|
@@ -9,7 +9,7 @@ pub fn part1(input: &str) -> impl std::fmt::Display {
|
|||||||
input
|
input
|
||||||
.lines()
|
.lines()
|
||||||
.map(|s| {
|
.map(|s| {
|
||||||
s.u32s()
|
s.unsigned()
|
||||||
// This is faster than `collect().try_into().expect("")`
|
// This is faster than `collect().try_into().expect("")`
|
||||||
// presumably because of the allocation of the Vec
|
// presumably because of the allocation of the Vec
|
||||||
// and the additional check for the Option for each line
|
// and the additional check for the Option for each line
|
||||||
@@ -33,9 +33,9 @@ pub fn part2(input: &str) -> impl std::fmt::Display {
|
|||||||
let mut valid = 0;
|
let mut valid = 0;
|
||||||
|
|
||||||
while let Some((l1, l2, l3)) = get3(&mut lines) {
|
while let Some((l1, l2, l3)) = get3(&mut lines) {
|
||||||
let l1: Vec<u32> = l1.u32s().collect();
|
let l1: Vec<u32> = l1.unsigned().collect();
|
||||||
let l2: Vec<u32> = l2.u32s().collect();
|
let l2: Vec<u32> = l2.unsigned().collect();
|
||||||
let l3: Vec<u32> = l3.u32s().collect();
|
let l3: Vec<u32> = l3.unsigned().collect();
|
||||||
for i in 0..2 {
|
for i in 0..2 {
|
||||||
if valid_triangle(&[l1[i], l2[i], l3[i]]) {
|
if valid_triangle(&[l1[i], l2[i], l3[i]]) {
|
||||||
valid += 1;
|
valid += 1;
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
use crate::util::parse::ParseExt;
|
use crate::util::parse::ParseExt;
|
||||||
|
|
||||||
fn calories(input: &str) -> impl Iterator<Item = u32> + '_ {
|
fn calories(input: &str) -> impl Iterator<Item = u32> + '_ {
|
||||||
input.split("\n\n").map(|set| set.u32s().sum())
|
input.split("\n\n").map(|set| set.unsigned::<u32>().sum())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn part1(input: &str) -> impl std::fmt::Display {
|
pub fn part1(input: &str) -> impl std::fmt::Display {
|
||||||
|
@@ -4,7 +4,7 @@ fn solve(input: &str, filter: fn(u32, u32, u32, u32) -> bool) -> usize {
|
|||||||
input
|
input
|
||||||
.lines()
|
.lines()
|
||||||
.filter_map(|line| {
|
.filter_map(|line| {
|
||||||
let mut nums = line.u32s();
|
let mut nums = line.unsigned::<u32>();
|
||||||
|
|
||||||
if (filter)(nums.next()?, nums.next()?, nums.next()?, nums.next()?) {
|
if (filter)(nums.next()?, nums.next()?, nums.next()?, nums.next()?) {
|
||||||
Some(())
|
Some(())
|
||||||
|
@@ -2,7 +2,7 @@ use crate::util::parse::ParseExt;
|
|||||||
|
|
||||||
fn parse(input: &str) -> Option<(Vec<Vec<char>>, impl Iterator<Item = [u32; 3]> + '_)> {
|
fn parse(input: &str) -> Option<(Vec<Vec<char>>, impl Iterator<Item = [u32; 3]> + '_)> {
|
||||||
let (board, moveset) = input.split_once("\n\n")?;
|
let (board, moveset) = input.split_once("\n\n")?;
|
||||||
let size = board.lines().last()?.u32s().count();
|
let size = board.lines().last()?.unsigned::<u32>().count();
|
||||||
let mut crates: Vec<Vec<char>> = vec![vec![]; size + 1];
|
let mut crates: Vec<Vec<char>> = vec![vec![]; size + 1];
|
||||||
|
|
||||||
board.lines().for_each(|line| {
|
board.lines().for_each(|line| {
|
||||||
@@ -22,7 +22,7 @@ fn parse(input: &str) -> Option<(Vec<Vec<char>>, impl Iterator<Item = [u32; 3]>
|
|||||||
}
|
}
|
||||||
|
|
||||||
let moves = moveset.lines().filter_map(|line| {
|
let moves = moveset.lines().filter_map(|line| {
|
||||||
let mut nums = line.u32s();
|
let mut nums = line.unsigned();
|
||||||
Some([nums.next()?, nums.next()?, nums.next()?])
|
Some([nums.next()?, nums.next()?, nums.next()?])
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -18,7 +18,7 @@ pub fn part1(input: &str) -> impl std::fmt::Display {
|
|||||||
|
|
||||||
for b in draw.split(", ") {
|
for b in draw.split(", ") {
|
||||||
let (num, col) = b.split_once(' ')?;
|
let (num, col) = b.split_once(' ')?;
|
||||||
let num = num.parse_u32();
|
let num = num.parse_unsigned::<u32>();
|
||||||
match col {
|
match col {
|
||||||
"red" => red += num,
|
"red" => red += num,
|
||||||
"green" => green += num,
|
"green" => green += num,
|
||||||
@@ -47,7 +47,7 @@ pub fn part2(input: &str) -> impl std::fmt::Display {
|
|||||||
for draw in cubes.split("; ") {
|
for draw in cubes.split("; ") {
|
||||||
for b in draw.split(", ") {
|
for b in draw.split(", ") {
|
||||||
let (num, col) = b.split_once(' ')?;
|
let (num, col) = b.split_once(' ')?;
|
||||||
let num = num.parse_u32();
|
let num = num.parse_unsigned::<u32>();
|
||||||
|
|
||||||
match col {
|
match col {
|
||||||
"red" => {
|
"red" => {
|
||||||
|
@@ -6,8 +6,8 @@ pub fn part1(input: &str) -> impl std::fmt::Display {
|
|||||||
.map(|line| {
|
.map(|line| {
|
||||||
let (_, rest) = line.split_once(':').unwrap();
|
let (_, rest) = line.split_once(':').unwrap();
|
||||||
let (winning, numbers) = rest.split_once('|').unwrap();
|
let (winning, numbers) = rest.split_once('|').unwrap();
|
||||||
let winning = winning.u32s().collect::<Vec<_>>();
|
let winning = winning.unsigned::<u32>().collect::<Vec<_>>();
|
||||||
let numbers = numbers.u32s().filter(|n| winning.contains(n)).count() as u32;
|
let numbers = numbers.unsigned::<u32>().filter(|n| winning.contains(n)).count() as u32;
|
||||||
(numbers > 0).then(|| 2u32.pow(numbers - 1)).unwrap_or(0)
|
(numbers > 0).then(|| 2u32.pow(numbers - 1)).unwrap_or(0)
|
||||||
})
|
})
|
||||||
.sum::<u32>()
|
.sum::<u32>()
|
||||||
@@ -24,8 +24,8 @@ pub fn part2(input: &str) -> impl std::fmt::Display {
|
|||||||
.map(|(i, line)| {
|
.map(|(i, line)| {
|
||||||
let (_, rest) = line.split_once(':').unwrap();
|
let (_, rest) = line.split_once(':').unwrap();
|
||||||
let (winning, numbers) = rest.split_once('|').unwrap();
|
let (winning, numbers) = rest.split_once('|').unwrap();
|
||||||
let winning = winning.u32s().collect::<Vec<_>>();
|
let winning = winning.unsigned::<u32>().collect::<Vec<_>>();
|
||||||
let numbers = numbers.u32s().filter(|n| winning.contains(n)).count();
|
let numbers = numbers.unsigned::<u32>().filter(|n| winning.contains(n)).count();
|
||||||
let mul = mults[i];
|
let mul = mults[i];
|
||||||
mults
|
mults
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
|
151
src/year2023/day05.rs
Normal file
151
src/year2023/day05.rs
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
use crate::util::parse::ParseExt;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Map {
|
||||||
|
tuples: Vec<(usize, usize, usize)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Map {
|
||||||
|
// We divide the seed range up into smaller seed ranges:
|
||||||
|
// 1) seed range before map range
|
||||||
|
// 2) seed range after map range
|
||||||
|
// 3) seed range in map range
|
||||||
|
// for the seed range inside the map range we map it and it to the result array
|
||||||
|
// the before and after seed ranges will be saved for the next map where. apply again
|
||||||
|
// rinse and repeat until the ranges are empty
|
||||||
|
fn calc_range(&self, mut ranges: Vec<(usize, usize)>) -> Vec<(usize, usize)> {
|
||||||
|
let mut mapped = vec![];
|
||||||
|
for (dest, source, l) in &self.tuples {
|
||||||
|
let mut todo = vec![];
|
||||||
|
|
||||||
|
while let Some((range_start, range_end)) = ranges.pop() {
|
||||||
|
let before_range = (range_start, range_end.min(*source));
|
||||||
|
if before_range.1 > before_range.0 {
|
||||||
|
todo.push(before_range);
|
||||||
|
}
|
||||||
|
let after_range = ((*source + l).max(range_start), range_end);
|
||||||
|
if after_range.1 > after_range.0 {
|
||||||
|
todo.push(after_range);
|
||||||
|
}
|
||||||
|
let between_range = (range_start.max(*source), (*source + *l).min(range_end));
|
||||||
|
if between_range.1 > between_range.0 {
|
||||||
|
mapped.push((
|
||||||
|
between_range.0 - source + dest,
|
||||||
|
between_range.1 - source + dest,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ranges = todo;
|
||||||
|
}
|
||||||
|
mapped.extend(ranges);
|
||||||
|
mapped
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse(input: &str) -> (Vec<usize>, Vec<Map>) {
|
||||||
|
let mut chunks = input.split("\n\n");
|
||||||
|
let seeds = chunks
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.unsigned::<usize>()
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let maps = chunks
|
||||||
|
.map(|chunk| Map {
|
||||||
|
tuples: chunk
|
||||||
|
.lines()
|
||||||
|
.enumerate()
|
||||||
|
.filter_map(|(idx, line)| {
|
||||||
|
if idx == 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let mut nums = line.unsigned::<usize>();
|
||||||
|
Some((nums.next()?, nums.next()?, nums.next()?))
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
(seeds, maps)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part1(input: &str) -> impl std::fmt::Display {
|
||||||
|
let (mut seeds, maps) = parse(input);
|
||||||
|
|
||||||
|
for seed in seeds.iter_mut() {
|
||||||
|
for map in &maps {
|
||||||
|
for (dest, source, l) in &map.tuples {
|
||||||
|
// if seed is within range map it in-place else leave it
|
||||||
|
if *seed >= *source && *seed < *source + *l {
|
||||||
|
*seed = *seed + *dest - *source;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
seeds.sort();
|
||||||
|
seeds[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part2(input: &str) -> impl std::fmt::Display {
|
||||||
|
let (seeds, maps) = parse(input);
|
||||||
|
let seeds = seeds.chunks(2).map(|v| (v[0], v[1]));
|
||||||
|
|
||||||
|
let mut res = seeds
|
||||||
|
.map(|(start, end)| {
|
||||||
|
let mut ranges = maps
|
||||||
|
.iter()
|
||||||
|
.fold(vec![(start, start + end)], |acc, map| map.calc_range(acc));
|
||||||
|
ranges.sort();
|
||||||
|
// We want the lowest, so take lower end of range
|
||||||
|
ranges[0].0
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
res.sort();
|
||||||
|
res[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
static TEST_INPUT: &str = "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";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part1() {
|
||||||
|
assert_eq!("35", part1(TEST_INPUT).to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part2() {
|
||||||
|
assert_eq!("46", part2(TEST_INPUT).to_string())
|
||||||
|
}
|
49
src/year2023/day06.rs
Normal file
49
src/year2023/day06.rs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
use crate::util::parse::ParseExt;
|
||||||
|
|
||||||
|
pub fn part1(input: &str) -> impl std::fmt::Display {
|
||||||
|
let mut lines = input.lines();
|
||||||
|
let times = lines.next().unwrap();
|
||||||
|
let dists = lines.next().unwrap();
|
||||||
|
|
||||||
|
times
|
||||||
|
.signed::<i32>()
|
||||||
|
.zip(dists.signed())
|
||||||
|
.map(|(lim, dist)| {
|
||||||
|
(0..dist)
|
||||||
|
.filter_map(|d| (d * (lim - d) > dist).then_some(1))
|
||||||
|
.sum::<u32>()
|
||||||
|
})
|
||||||
|
.product::<u32>()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part2(input: &str) -> impl std::fmt::Display {
|
||||||
|
let mut lines = input.lines();
|
||||||
|
let time = lines
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.chars()
|
||||||
|
.filter(|a| a.is_ascii_digit())
|
||||||
|
.collect::<String>().as_str()
|
||||||
|
.parse_signed::<i128>();
|
||||||
|
let dist = lines
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.chars()
|
||||||
|
.filter(|a| a.is_ascii_digit())
|
||||||
|
.collect::<String>().as_str()
|
||||||
|
.parse_signed::<i128>();
|
||||||
|
|
||||||
|
(0..time)
|
||||||
|
.filter_map(|d| (d * (time - d) > dist).then_some(1))
|
||||||
|
.sum::<i128>()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part1() {
|
||||||
|
assert_eq!("", part1("").to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part2() {
|
||||||
|
assert_eq!("", part2("").to_string())
|
||||||
|
}
|
Reference in New Issue
Block a user