Implement day 5

Nom is really nice and fast, why did I write parsers manually before.
This commit is contained in:
2021-12-05 11:31:14 +01:00
parent 5e52da6e6b
commit 1433b0cdbe
6 changed files with 619 additions and 4 deletions

5
.gitignore vendored
View File

@@ -59,3 +59,8 @@ target/
# Rust lock # Rust lock
*.lock *.lock
# Performance data
perf.data
perf.data.old
flamegraph.svg

View File

@@ -6,6 +6,7 @@ edition = "2021"
[dependencies] [dependencies]
clap = "3.0.0-beta.5" clap = "3.0.0-beta.5"
nom = "7"
[profile.release] [profile.release]
# Keep debug information in release for better flamegraphs # Keep debug information in release for better flamegraphs

500
2021/inputs/05.txt Normal file
View File

@@ -0,0 +1,500 @@
781,721 -> 781,611
334,551 -> 119,551
25,153 -> 765,893
588,619 -> 588,683
167,63 -> 439,335
340,129 -> 35,129
578,712 -> 509,712
855,426 -> 855,649
778,71 -> 778,411
21,314 -> 631,924
552,148 -> 148,552
531,889 -> 789,889
85,963 -> 986,62
914,140 -> 257,797
520,721 -> 794,721
49,936 -> 960,25
458,941 -> 839,560
113,797 -> 113,604
554,136 -> 554,655
112,208 -> 112,504
78,410 -> 169,319
176,148 -> 906,878
56,98 -> 835,877
538,981 -> 178,621
553,102 -> 553,688
452,761 -> 452,70
487,574 -> 487,589
356,406 -> 154,406
11,646 -> 11,416
543,19 -> 924,400
862,773 -> 929,773
292,901 -> 292,97
985,236 -> 667,236
745,572 -> 667,572
752,794 -> 775,817
269,649 -> 269,198
928,327 -> 469,786
284,937 -> 755,466
308,876 -> 308,790
201,94 -> 988,881
233,958 -> 903,288
210,879 -> 91,879
760,48 -> 133,675
55,79 -> 956,980
988,15 -> 15,988
25,974 -> 966,33
903,671 -> 292,60
587,770 -> 403,954
83,379 -> 432,728
30,121 -> 334,425
375,516 -> 375,409
72,370 -> 72,152
575,595 -> 575,363
248,64 -> 896,712
703,421 -> 395,421
66,978 -> 977,67
450,961 -> 450,773
830,895 -> 830,661
373,58 -> 442,58
739,383 -> 739,712
510,188 -> 510,99
350,880 -> 248,880
771,278 -> 549,278
266,434 -> 266,838
315,490 -> 884,490
360,651 -> 428,583
333,452 -> 333,109
313,414 -> 713,14
23,982 -> 989,16
196,201 -> 889,894
485,761 -> 99,375
288,918 -> 50,680
912,206 -> 142,976
242,10 -> 841,609
972,11 -> 16,967
859,142 -> 390,611
48,348 -> 212,348
246,514 -> 726,34
29,754 -> 29,706
617,296 -> 224,689
671,487 -> 397,213
913,898 -> 155,140
437,688 -> 18,269
150,150 -> 869,869
386,873 -> 940,319
57,326 -> 148,417
847,12 -> 319,540
741,640 -> 520,640
111,458 -> 111,754
595,615 -> 861,881
244,722 -> 905,722
323,394 -> 323,304
560,562 -> 560,678
48,750 -> 48,228
80,40 -> 80,723
730,839 -> 191,300
300,773 -> 977,96
619,892 -> 827,892
22,226 -> 656,226
125,968 -> 125,637
116,923 -> 512,923
59,741 -> 59,499
484,930 -> 487,930
362,175 -> 362,778
960,986 -> 53,79
170,748 -> 576,748
810,291 -> 743,291
761,924 -> 339,502
730,850 -> 920,850
778,949 -> 778,766
254,724 -> 254,394
685,177 -> 685,441
442,290 -> 833,290
181,209 -> 72,100
91,924 -> 953,62
318,880 -> 318,659
570,632 -> 570,966
955,227 -> 667,227
439,666 -> 439,224
276,385 -> 276,56
544,521 -> 544,867
187,626 -> 187,13
307,235 -> 859,235
759,416 -> 668,416
357,882 -> 981,882
651,71 -> 651,457
615,711 -> 615,502
474,162 -> 305,162
320,33 -> 320,48
799,420 -> 799,389
448,46 -> 313,46
925,141 -> 925,928
332,101 -> 332,373
41,948 -> 749,948
276,672 -> 207,672
315,736 -> 86,736
844,688 -> 466,688
357,199 -> 107,199
902,950 -> 14,62
277,251 -> 923,251
963,38 -> 34,967
71,389 -> 577,389
712,911 -> 712,573
186,976 -> 148,938
407,389 -> 637,619
917,118 -> 917,960
988,571 -> 362,571
845,941 -> 189,285
686,537 -> 306,537
915,929 -> 946,960
447,30 -> 447,364
832,833 -> 832,888
957,953 -> 203,199
982,73 -> 400,655
159,704 -> 159,844
284,347 -> 159,347
903,280 -> 93,280
769,961 -> 140,332
899,145 -> 293,751
850,643 -> 148,643
580,870 -> 739,870
686,250 -> 686,237
142,528 -> 142,936
827,224 -> 827,287
972,946 -> 155,946
706,851 -> 862,851
564,231 -> 564,428
511,662 -> 511,752
838,842 -> 585,842
60,871 -> 870,61
719,824 -> 719,648
183,232 -> 936,985
131,56 -> 953,878
406,952 -> 80,952
884,518 -> 945,518
427,439 -> 662,439
829,920 -> 829,634
966,262 -> 966,933
813,27 -> 813,934
784,101 -> 784,160
744,313 -> 744,850
969,213 -> 206,976
957,56 -> 28,985
312,620 -> 312,680
454,131 -> 454,776
360,174 -> 175,359
711,114 -> 692,95
452,839 -> 938,839
641,56 -> 641,334
566,890 -> 51,890
869,109 -> 869,102
119,36 -> 119,796
301,583 -> 301,451
733,603 -> 733,714
718,703 -> 581,566
709,513 -> 915,513
405,13 -> 572,13
782,26 -> 391,26
15,74 -> 858,917
975,978 -> 38,41
11,316 -> 982,316
303,367 -> 303,129
847,143 -> 847,158
856,687 -> 856,870
715,524 -> 715,812
451,288 -> 272,467
576,179 -> 119,179
10,623 -> 10,44
652,631 -> 796,775
930,613 -> 913,613
803,746 -> 803,566
306,602 -> 306,137
582,491 -> 582,296
181,116 -> 231,116
802,646 -> 802,884
75,623 -> 75,424
370,680 -> 370,923
806,497 -> 939,497
301,331 -> 818,331
912,916 -> 27,31
24,82 -> 683,741
862,205 -> 316,751
245,842 -> 383,842
544,946 -> 518,920
129,192 -> 18,303
831,915 -> 31,115
306,824 -> 454,676
851,341 -> 125,341
790,154 -> 790,988
407,586 -> 477,656
144,988 -> 925,207
264,391 -> 264,466
901,651 -> 646,651
865,936 -> 390,461
631,737 -> 631,166
103,939 -> 937,105
505,813 -> 505,218
260,457 -> 141,457
52,762 -> 54,762
26,95 -> 889,958
638,41 -> 330,41
612,775 -> 191,354
863,224 -> 863,287
674,87 -> 674,110
189,76 -> 954,841
372,483 -> 503,483
166,75 -> 619,75
938,983 -> 18,63
442,573 -> 858,157
681,590 -> 878,590
276,465 -> 500,241
644,703 -> 651,710
848,363 -> 254,363
204,109 -> 216,97
81,529 -> 81,674
74,44 -> 978,948
929,237 -> 598,237
298,644 -> 298,712
678,367 -> 360,685
413,27 -> 413,799
684,403 -> 684,500
188,601 -> 972,601
33,257 -> 33,897
278,299 -> 278,635
261,983 -> 804,440
216,324 -> 216,526
399,332 -> 399,613
826,702 -> 826,332
137,203 -> 624,203
326,552 -> 36,262
142,927 -> 343,927
21,330 -> 410,719
721,768 -> 289,336
807,715 -> 807,287
775,678 -> 62,678
771,10 -> 491,10
287,829 -> 287,599
589,947 -> 767,947
160,348 -> 798,986
699,264 -> 108,855
605,145 -> 568,145
264,615 -> 545,615
633,111 -> 11,733
589,886 -> 589,897
728,839 -> 78,189
739,924 -> 948,924
140,354 -> 830,354
619,662 -> 332,662
592,960 -> 592,290
510,908 -> 510,828
792,518 -> 792,749
148,20 -> 832,704
529,837 -> 863,503
802,371 -> 301,371
682,429 -> 682,537
885,918 -> 38,71
590,229 -> 795,24
782,704 -> 244,704
936,71 -> 981,71
27,272 -> 27,253
558,48 -> 558,69
661,422 -> 661,145
152,335 -> 152,362
516,407 -> 26,407
449,731 -> 592,731
187,456 -> 594,863
145,290 -> 15,290
667,213 -> 214,666
660,872 -> 660,605
649,617 -> 986,954
86,914 -> 959,41
895,967 -> 24,96
40,154 -> 762,154
27,106 -> 855,934
929,913 -> 319,303
749,314 -> 387,676
76,380 -> 824,380
632,329 -> 632,436
154,496 -> 154,528
127,958 -> 127,613
592,606 -> 363,606
929,228 -> 929,890
832,596 -> 801,565
824,978 -> 134,978
638,485 -> 638,291
783,848 -> 783,77
646,877 -> 646,117
461,279 -> 850,668
300,450 -> 115,265
916,205 -> 145,976
510,760 -> 124,760
884,668 -> 884,153
285,370 -> 705,790
845,42 -> 17,870
784,59 -> 71,772
627,268 -> 333,562
731,403 -> 22,403
980,43 -> 43,980
16,988 -> 973,31
720,881 -> 300,881
23,182 -> 723,882
129,887 -> 51,887
186,934 -> 186,452
114,815 -> 39,815
868,777 -> 868,222
554,218 -> 911,218
247,408 -> 777,938
391,69 -> 285,69
239,472 -> 614,847
422,918 -> 422,245
852,905 -> 852,634
631,164 -> 17,778
987,988 -> 11,12
435,891 -> 435,136
564,409 -> 767,612
611,508 -> 611,535
744,965 -> 631,965
308,604 -> 509,604
77,250 -> 589,762
505,950 -> 685,950
907,222 -> 850,222
700,674 -> 754,620
238,294 -> 53,479
875,130 -> 875,544
368,547 -> 368,965
618,206 -> 311,206
127,972 -> 852,247
561,192 -> 982,613
573,399 -> 573,464
311,109 -> 764,562
69,813 -> 809,813
195,594 -> 317,594
900,467 -> 638,467
806,810 -> 806,918
451,17 -> 128,17
93,837 -> 878,52
299,726 -> 531,958
968,984 -> 18,34
957,38 -> 14,38
283,583 -> 32,332
922,822 -> 953,853
589,466 -> 753,466
203,791 -> 933,791
122,739 -> 778,83
294,658 -> 289,658
365,200 -> 365,513
611,941 -> 701,941
927,111 -> 107,931
754,529 -> 181,529
364,933 -> 567,933
717,960 -> 717,11
612,472 -> 612,807
971,252 -> 531,252
88,911 -> 387,911
885,837 -> 75,27
222,289 -> 714,781
754,40 -> 293,501
866,517 -> 949,517
858,586 -> 331,586
157,21 -> 731,595
173,216 -> 822,865
353,206 -> 353,318
68,88 -> 957,88
370,645 -> 200,815
981,83 -> 89,975
259,112 -> 259,435
184,920 -> 825,279
252,357 -> 252,56
722,349 -> 368,703
928,973 -> 597,973
677,656 -> 788,545
222,766 -> 527,461
870,787 -> 972,889
11,986 -> 986,11
163,918 -> 748,333
111,75 -> 823,75
603,250 -> 375,478
338,582 -> 338,454
372,179 -> 452,179
571,96 -> 571,723
243,460 -> 267,460
850,63 -> 43,870
837,863 -> 113,139
21,886 -> 709,198
154,650 -> 181,650
320,506 -> 320,706
983,722 -> 983,657
830,225 -> 190,865
924,12 -> 11,925
838,827 -> 258,247
690,792 -> 690,582
465,658 -> 146,977
790,935 -> 39,184
318,627 -> 318,125
245,939 -> 291,939
803,219 -> 254,768
262,476 -> 441,476
790,225 -> 790,372
250,722 -> 613,722
368,326 -> 368,474
148,666 -> 394,912
813,588 -> 238,13
84,323 -> 84,957
566,716 -> 822,716
794,633 -> 459,633
355,634 -> 237,634
950,755 -> 950,867
292,696 -> 340,696
121,391 -> 361,631
58,516 -> 624,516
859,37 -> 184,712
686,819 -> 428,819
11,12 -> 988,989
718,679 -> 280,679
515,524 -> 515,664
136,459 -> 136,56
703,763 -> 703,858
290,733 -> 290,33
910,928 -> 910,21
570,937 -> 570,808
462,215 -> 462,747
388,181 -> 712,505
933,705 -> 933,601
605,492 -> 188,492
737,818 -> 564,818
214,629 -> 735,108
139,942 -> 598,942
708,187 -> 541,187
646,611 -> 325,611
788,356 -> 718,426
267,250 -> 267,930
94,819 -> 94,191
661,537 -> 661,363
464,290 -> 471,297
656,68 -> 337,68
31,515 -> 797,515
876,21 -> 81,21
630,932 -> 21,323
259,58 -> 542,58
703,523 -> 703,949
470,310 -> 470,20
69,983 -> 977,75
569,908 -> 569,931
645,718 -> 645,665
819,371 -> 819,705
772,709 -> 772,736
330,870 -> 382,818
982,317 -> 982,778
626,411 -> 626,887
466,33 -> 466,635
519,939 -> 519,131
402,253 -> 402,300
180,712 -> 826,66
55,764 -> 941,764
659,859 -> 659,944
346,374 -> 346,500
880,333 -> 880,767
42,969 -> 983,28
363,688 -> 363,148
645,880 -> 265,500

View File

@@ -60,3 +60,12 @@ impl<'a, I: FromStr> Iterator for LineParser<'a, I> {
self.iter.next()?.parse().ok() self.iter.next()?.parse().ok()
} }
} }
/// Return two arguments in their natural PartialOrd order
pub fn ordered<O: PartialOrd>(a: O, b: O) -> (O, O) {
if a < b {
(a, b)
} else {
(b, a)
}
}

View File

@@ -1,9 +1,99 @@
use std::collections::HashMap;
use std::io::Read; use std::io::Read;
use std::iter::repeat;
pub fn part1(_input: &mut dyn Read) -> String { use nom::bytes::complete::tag;
todo!() use nom::sequence::tuple;
use nom::Finish;
use nom::IResult;
use crate::common::ordered;
use crate::common::LineIter;
type Coord = (u16, u16);
fn coordinates(input: &str) -> IResult<&str, Coord> {
use nom::character::complete;
let (input, (x, _, y)) = tuple((complete::u16, complete::char(','), complete::u16))(input)?;
Ok((input, (x, y)))
} }
pub fn part2(_input: &mut dyn Read) -> String { fn line_definition(input: &str) -> IResult<&str, (Coord, Coord)> {
todo!() let (input, (begin, _, end)) = tuple((coordinates, tag(" -> "), coordinates))(input)?;
// Sorting the coordinates saves trouble later
Ok((input, ordered(begin, end)))
}
fn stripe(
map: &mut HashMap<Coord, u16>,
xs: impl Iterator<Item = u16>,
ys: impl Iterator<Item = u16>,
) {
for (x, y) in xs.zip(ys) {
*map.entry((x, y)).or_default() += 1;
}
}
fn part_common(input: &mut dyn Read, diagonals: bool) -> String {
let mut reader = LineIter::new(input);
let mut map = HashMap::new();
while let Some(line) = reader.next() {
let (begin, end) = line_definition(line).finish().unwrap().1;
if begin.0 == end.0 {
let y_range = begin.1..=end.1;
stripe(&mut map, repeat(begin.0), y_range);
} else if begin.1 == end.1 {
let x_range = begin.0..=end.0;
stripe(&mut map, x_range, repeat(begin.1));
} else if diagonals {
let x_range = begin.0..=end.0;
let y_range = (begin.1.min(end.1))..=(begin.1.max(end.1));
if begin.1 > end.1 {
// For a downward slope we need to reverse Y
stripe(&mut map, x_range, y_range.rev());
} else {
stripe(&mut map, x_range, y_range);
}
}
}
map.values().filter(|&&v| v > 1).count().to_string()
}
pub fn part1(input: &mut dyn Read) -> String {
part_common(input, false)
}
pub fn part2(input: &mut dyn Read) -> String {
part_common(input, true)
}
#[cfg(test)]
mod tests {
use crate::test_implementation;
use super::*;
const SAMPLE: &[u8] = include_bytes!("samples/05.txt");
#[test]
fn test_parser() {
assert_eq!(line_definition("6,4 -> 2,0"), Ok(("", ((2, 0), (6, 4)))));
}
#[test]
fn sample_part1() {
test_implementation(part1, SAMPLE, 5)
}
#[test]
fn sample_part2() {
test_implementation(part2, SAMPLE, 12)
}
} }

10
2021/src/samples/05.txt Normal file
View File

@@ -0,0 +1,10 @@
0,9 -> 5,9
8,0 -> 0,8
9,4 -> 3,4
2,2 -> 2,1
7,0 -> 7,4
6,4 -> 2,0
0,9 -> 2,9
3,4 -> 1,4
0,0 -> 8,8
5,5 -> 8,2