aboutsummaryrefslogtreecommitdiff
path: root/2021/05
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--2021/05/README.md3
-rw-r--r--2021/05/example10
-rw-r--r--2021/05/first.go48
-rw-r--r--2021/05/first_v2.go60
-rw-r--r--2021/05/go.mod3
-rw-r--r--2021/05/input500
-rw-r--r--2021/05/line/line.go239
-rw-r--r--2021/05/second.go61
-rw-r--r--2021/05/second_v2.go58
9 files changed, 982 insertions, 0 deletions
diff --git a/2021/05/README.md b/2021/05/README.md
new file mode 100644
index 0000000..6a4996d
--- /dev/null
+++ b/2021/05/README.md
@@ -0,0 +1,3 @@
+I went a little overboard with a parsing tutorial.
+
+I wanted to manually write a parser from quite some time now and seized this opportunity. It would have been trivial with just a scanner or even a regex, but hey learning!
diff --git a/2021/05/example b/2021/05/example
new file mode 100644
index 0000000..b258f68
--- /dev/null
+++ b/2021/05/example
@@ -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
diff --git a/2021/05/first.go b/2021/05/first.go
new file mode 100644
index 0000000..3bd007b
--- /dev/null
+++ b/2021/05/first.go
@@ -0,0 +1,48 @@
+package main
+
+import (
+ "bufio"
+ "fmt"
+ "os"
+
+ "git.adyxax.org/aoc/2021/05/line"
+)
+
+func main() {
+ matrix := make([][]int, 1000)
+ for i := 0; i < 1000; i++ {
+ matrix[i] = make([]int, 1000)
+ }
+
+ parser := line.NewParser(bufio.NewReader(os.Stdin))
+ for {
+ l, err := parser.Parse()
+ if err != nil {
+ break
+ }
+ if l.X1 == l.X2 {
+ if l.Y1 > l.Y2 {
+ l.Y1, l.Y2 = l.Y2, l.Y1
+ }
+ for i := l.Y1; i <= l.Y2; i++ {
+ matrix[l.X1][i]++
+ }
+ } else if l.Y1 == l.Y2 {
+ if l.X1 > l.X2 {
+ l.X1, l.X2 = l.X2, l.X1
+ }
+ for i := l.X1; i <= l.X2; i++ {
+ matrix[i][l.Y1]++
+ }
+ }
+ }
+ score := 0
+ for i := 0; i < 1000; i++ {
+ for j := 0; j < 1000; j++ {
+ if matrix[i][j] >= 2 {
+ score++
+ }
+ }
+ }
+ fmt.Println(score)
+}
diff --git a/2021/05/first_v2.go b/2021/05/first_v2.go
new file mode 100644
index 0000000..d99f80b
--- /dev/null
+++ b/2021/05/first_v2.go
@@ -0,0 +1,60 @@
+package main
+
+import (
+ "bufio"
+ "fmt"
+ "os"
+
+ "git.adyxax.org/aoc/2021/05/line"
+)
+
+func abs(a int) int {
+ if a < 0 {
+ return -a
+ }
+ return a
+}
+
+func computeDelta(a, b int) int {
+ if a < b {
+ return 1
+ } else if a > b {
+ return -1
+ }
+ return 0
+}
+
+func main() {
+ matrix := make([][]int, 1000)
+ for i := 0; i < 1000; i++ {
+ matrix[i] = make([]int, 1000)
+ }
+
+ parser := line.NewParser(bufio.NewReader(os.Stdin))
+ for {
+ l, err := parser.Parse()
+ if err != nil {
+ break
+ }
+ length := abs(l.X2 - l.X1)
+ if length == 0 {
+ length = abs(l.Y2 - l.Y1)
+ }
+ dx := computeDelta(l.X1, l.X2)
+ dy := computeDelta(l.Y1, l.Y2)
+ if dx == 0 || dy == 0 {
+ for i := 0; i <= length; i++ {
+ matrix[l.X1+i*dx][l.Y1+i*dy]++
+ }
+ }
+ }
+ score := 0
+ for i := 0; i < 1000; i++ {
+ for j := 0; j < 1000; j++ {
+ if matrix[i][j] >= 2 {
+ score++
+ }
+ }
+ }
+ fmt.Println(score)
+}
diff --git a/2021/05/go.mod b/2021/05/go.mod
new file mode 100644
index 0000000..81fcab6
--- /dev/null
+++ b/2021/05/go.mod
@@ -0,0 +1,3 @@
+module git.adyxax.org/aoc/2021/05
+
+go 1.17
diff --git a/2021/05/input b/2021/05/input
new file mode 100644
index 0000000..527ecf6
--- /dev/null
+++ b/2021/05/input
@@ -0,0 +1,500 @@
+223,805 -> 223,548
+609,164 -> 609,503
+461,552 -> 796,552
+207,361 -> 207,34
+503,879 -> 503,946
+937,52 -> 937,268
+560,652 -> 118,652
+771,103 -> 85,789
+119,156 -> 947,984
+356,634 -> 607,634
+348,812 -> 873,287
+409,490 -> 726,490
+298,790 -> 298,454
+407,543 -> 820,130
+206,89 -> 591,89
+164,709 -> 976,709
+208,921 -> 208,131
+515,209 -> 515,745
+876,639 -> 281,44
+270,453 -> 727,910
+190,417 -> 190,755
+522,726 -> 903,726
+390,651 -> 603,864
+707,549 -> 926,330
+471,869 -> 471,561
+970,735 -> 401,735
+612,624 -> 612,88
+844,879 -> 844,453
+400,38 -> 400,350
+832,225 -> 984,225
+971,642 -> 42,642
+70,862 -> 447,485
+183,79 -> 183,708
+598,700 -> 598,287
+635,195 -> 39,195
+587,362 -> 349,362
+108,88 -> 965,945
+700,299 -> 165,299
+295,824 -> 785,334
+211,284 -> 390,105
+288,326 -> 672,710
+595,231 -> 595,679
+671,576 -> 813,718
+14,845 -> 784,75
+700,129 -> 43,129
+83,913 -> 889,107
+830,596 -> 322,596
+391,450 -> 391,779
+384,32 -> 384,430
+311,948 -> 938,321
+460,288 -> 460,392
+924,602 -> 924,595
+703,458 -> 703,475
+335,953 -> 335,195
+692,314 -> 927,314
+131,433 -> 131,737
+590,771 -> 965,771
+650,13 -> 963,13
+586,904 -> 658,976
+238,824 -> 782,824
+366,45 -> 691,370
+428,758 -> 201,758
+240,545 -> 30,545
+396,154 -> 332,154
+549,307 -> 233,307
+187,240 -> 851,904
+151,135 -> 937,921
+342,850 -> 342,156
+695,200 -> 695,754
+385,880 -> 893,372
+986,966 -> 813,966
+727,661 -> 727,402
+316,937 -> 316,797
+422,235 -> 422,282
+965,684 -> 882,684
+266,222 -> 419,69
+649,843 -> 635,857
+618,84 -> 126,576
+588,822 -> 588,636
+569,142 -> 569,607
+899,479 -> 488,890
+986,52 -> 369,52
+987,478 -> 551,914
+867,951 -> 973,845
+90,401 -> 304,401
+60,836 -> 798,836
+143,675 -> 686,675
+743,974 -> 743,305
+981,899 -> 551,469
+705,430 -> 493,430
+301,366 -> 823,366
+978,712 -> 617,712
+426,805 -> 426,345
+532,855 -> 532,54
+612,143 -> 612,133
+57,52 -> 955,950
+880,50 -> 16,914
+89,908 -> 89,214
+487,867 -> 586,867
+181,285 -> 181,470
+526,666 -> 86,226
+117,704 -> 117,961
+289,101 -> 983,795
+586,429 -> 442,429
+442,869 -> 734,869
+564,479 -> 564,382
+447,486 -> 62,101
+42,218 -> 509,218
+21,890 -> 843,68
+84,978 -> 921,141
+590,960 -> 590,934
+54,949 -> 967,36
+799,39 -> 767,39
+979,232 -> 979,628
+489,482 -> 339,482
+759,473 -> 290,942
+960,958 -> 32,30
+134,180 -> 134,864
+972,981 -> 13,22
+106,385 -> 11,385
+849,454 -> 447,454
+477,385 -> 955,863
+853,180 -> 922,180
+509,274 -> 751,32
+905,295 -> 779,295
+661,629 -> 104,629
+935,117 -> 93,959
+165,372 -> 746,953
+988,141 -> 122,141
+625,621 -> 625,406
+24,710 -> 465,710
+417,468 -> 851,34
+365,285 -> 572,285
+217,164 -> 217,214
+943,439 -> 465,439
+80,102 -> 80,717
+869,19 -> 54,834
+399,480 -> 399,458
+644,826 -> 644,911
+651,189 -> 651,687
+671,946 -> 332,607
+531,417 -> 657,417
+847,350 -> 847,112
+315,733 -> 871,177
+749,118 -> 692,118
+55,616 -> 55,894
+570,307 -> 633,307
+12,964 -> 883,93
+84,299 -> 84,185
+49,187 -> 903,187
+592,40 -> 842,40
+639,381 -> 802,544
+59,61 -> 836,61
+968,51 -> 266,753
+883,373 -> 883,130
+612,45 -> 406,45
+206,698 -> 206,823
+385,685 -> 385,46
+656,338 -> 73,921
+256,794 -> 365,903
+671,247 -> 248,247
+722,509 -> 635,422
+460,783 -> 615,783
+946,980 -> 946,129
+343,780 -> 343,723
+218,371 -> 218,856
+363,809 -> 143,589
+434,739 -> 889,739
+75,71 -> 975,971
+57,253 -> 582,778
+976,237 -> 976,148
+386,866 -> 386,544
+901,797 -> 901,630
+976,706 -> 195,706
+264,420 -> 272,428
+693,72 -> 693,379
+888,832 -> 888,490
+363,900 -> 363,350
+25,312 -> 25,58
+292,307 -> 481,307
+715,393 -> 976,132
+641,450 -> 96,450
+650,38 -> 432,38
+339,97 -> 476,97
+916,24 -> 13,927
+933,934 -> 34,35
+971,367 -> 971,919
+726,310 -> 477,559
+12,984 -> 986,10
+318,531 -> 318,72
+604,979 -> 12,387
+890,39 -> 890,213
+944,954 -> 33,43
+507,830 -> 284,607
+724,111 -> 724,242
+425,912 -> 425,445
+371,903 -> 371,634
+415,314 -> 415,509
+884,849 -> 884,454
+726,647 -> 447,926
+588,463 -> 588,426
+807,453 -> 807,593
+32,449 -> 975,449
+593,757 -> 593,607
+521,850 -> 521,139
+843,478 -> 843,317
+408,834 -> 408,455
+65,241 -> 864,241
+532,138 -> 613,138
+477,239 -> 477,676
+92,400 -> 92,935
+268,104 -> 300,104
+942,20 -> 93,869
+294,134 -> 695,134
+748,477 -> 748,311
+581,879 -> 481,879
+292,57 -> 874,639
+829,787 -> 944,787
+130,780 -> 442,780
+754,435 -> 956,435
+306,659 -> 306,491
+252,612 -> 646,612
+846,949 -> 846,924
+197,888 -> 145,836
+156,790 -> 151,790
+903,305 -> 671,73
+195,79 -> 195,40
+781,67 -> 781,635
+742,743 -> 742,280
+297,42 -> 618,42
+237,151 -> 156,151
+851,930 -> 47,126
+425,368 -> 659,134
+57,890 -> 898,49
+86,62 -> 86,445
+133,499 -> 133,604
+202,567 -> 872,567
+749,578 -> 749,804
+379,379 -> 147,379
+510,474 -> 510,388
+184,115 -> 738,115
+904,613 -> 550,613
+755,649 -> 755,305
+461,306 -> 461,547
+469,124 -> 542,124
+736,218 -> 736,968
+307,662 -> 307,188
+360,970 -> 58,668
+36,267 -> 214,267
+980,330 -> 22,330
+222,972 -> 222,178
+846,774 -> 714,774
+798,837 -> 789,837
+567,258 -> 567,502
+325,582 -> 325,976
+138,386 -> 138,691
+326,878 -> 326,386
+790,276 -> 811,276
+517,522 -> 81,86
+493,567 -> 406,567
+522,370 -> 13,370
+31,697 -> 607,121
+297,524 -> 297,320
+790,681 -> 753,681
+90,961 -> 901,150
+262,46 -> 262,68
+18,26 -> 977,985
+782,381 -> 956,381
+353,740 -> 353,595
+32,448 -> 941,448
+405,254 -> 686,254
+853,57 -> 297,613
+555,209 -> 439,209
+765,679 -> 142,56
+175,903 -> 175,685
+693,653 -> 845,653
+394,108 -> 394,901
+351,108 -> 335,108
+841,83 -> 841,716
+525,608 -> 525,496
+874,32 -> 874,214
+354,760 -> 44,760
+249,330 -> 864,945
+553,377 -> 553,944
+903,374 -> 335,374
+387,34 -> 387,86
+380,331 -> 380,124
+618,520 -> 797,520
+718,169 -> 703,169
+355,184 -> 851,184
+582,570 -> 582,313
+312,952 -> 312,460
+269,70 -> 269,197
+701,907 -> 701,768
+645,417 -> 645,548
+931,532 -> 367,532
+497,361 -> 497,348
+563,642 -> 976,642
+376,504 -> 376,448
+538,945 -> 538,773
+594,886 -> 594,281
+879,558 -> 192,558
+985,68 -> 66,987
+599,420 -> 599,41
+296,318 -> 296,132
+330,619 -> 302,619
+245,137 -> 918,810
+823,798 -> 556,531
+64,201 -> 723,860
+955,365 -> 955,829
+372,976 -> 255,859
+804,962 -> 168,962
+200,442 -> 200,97
+965,964 -> 870,869
+534,158 -> 128,564
+380,739 -> 577,542
+740,391 -> 740,651
+167,177 -> 619,177
+215,449 -> 215,330
+494,612 -> 19,137
+458,634 -> 458,257
+884,817 -> 393,326
+407,291 -> 19,679
+627,173 -> 627,570
+53,93 -> 552,592
+809,363 -> 119,363
+588,418 -> 588,764
+807,131 -> 807,834
+616,61 -> 514,61
+553,642 -> 236,325
+959,553 -> 683,553
+36,754 -> 36,830
+533,293 -> 144,293
+950,780 -> 396,780
+949,878 -> 14,878
+453,180 -> 989,180
+22,46 -> 670,694
+479,206 -> 479,552
+22,53 -> 599,53
+254,964 -> 884,334
+578,813 -> 100,813
+945,247 -> 778,80
+312,978 -> 312,518
+882,225 -> 882,967
+581,683 -> 293,395
+107,540 -> 534,967
+382,946 -> 28,946
+864,743 -> 246,743
+538,558 -> 733,753
+811,436 -> 814,436
+982,33 -> 65,950
+785,829 -> 945,829
+322,471 -> 346,471
+904,528 -> 904,669
+231,471 -> 772,471
+773,490 -> 669,386
+867,482 -> 417,32
+352,856 -> 352,478
+723,355 -> 619,355
+667,922 -> 667,247
+642,386 -> 241,386
+594,35 -> 594,580
+916,723 -> 793,723
+73,774 -> 269,970
+43,273 -> 148,168
+744,637 -> 825,637
+98,30 -> 98,383
+130,277 -> 802,277
+167,122 -> 672,627
+871,866 -> 564,559
+923,475 -> 539,859
+422,714 -> 422,946
+667,950 -> 667,640
+758,181 -> 12,927
+129,927 -> 129,288
+485,661 -> 402,661
+114,573 -> 974,573
+674,779 -> 851,779
+977,184 -> 977,143
+229,937 -> 229,138
+520,887 -> 520,512
+918,329 -> 918,990
+732,41 -> 521,41
+399,245 -> 883,729
+824,618 -> 356,618
+215,218 -> 845,848
+704,34 -> 307,431
+124,166 -> 696,738
+692,749 -> 839,749
+790,637 -> 790,598
+697,396 -> 669,396
+419,140 -> 113,446
+426,738 -> 171,738
+489,494 -> 190,793
+320,301 -> 320,398
+275,809 -> 275,717
+537,703 -> 465,703
+536,450 -> 560,450
+153,927 -> 914,166
+246,692 -> 485,453
+26,179 -> 26,554
+487,678 -> 487,696
+807,719 -> 224,719
+605,920 -> 899,920
+112,262 -> 112,765
+752,898 -> 752,429
+861,103 -> 861,477
+628,505 -> 628,248
+556,293 -> 556,276
+826,682 -> 273,129
+685,324 -> 685,692
+544,410 -> 544,678
+796,633 -> 796,950
+753,843 -> 753,936
+817,40 -> 817,600
+137,941 -> 677,401
+563,457 -> 599,457
+251,644 -> 251,67
+170,792 -> 805,792
+171,486 -> 171,877
+337,481 -> 268,412
+43,158 -> 44,158
+148,610 -> 863,610
+332,765 -> 202,765
+307,637 -> 334,637
+557,380 -> 231,54
+858,76 -> 150,784
+477,329 -> 319,329
+306,608 -> 306,38
+245,42 -> 245,929
+15,786 -> 745,786
+946,321 -> 841,321
+837,281 -> 837,762
+847,391 -> 847,840
+304,52 -> 304,299
+938,122 -> 877,122
+214,347 -> 862,347
+494,540 -> 751,540
+184,29 -> 913,758
+904,12 -> 15,901
+573,23 -> 158,23
+926,603 -> 643,603
+105,506 -> 518,506
+551,917 -> 983,917
+708,33 -> 831,33
+347,173 -> 218,44
+933,175 -> 933,781
+902,556 -> 902,812
+556,485 -> 252,789
+823,807 -> 368,352
+217,744 -> 217,470
+795,455 -> 795,783
+170,944 -> 926,188
+55,655 -> 258,655
+158,57 -> 959,858
+714,823 -> 714,550
+238,18 -> 388,18
+980,985 -> 12,17
+360,596 -> 770,596
+846,684 -> 220,58
+552,107 -> 552,974
+228,552 -> 354,552
+421,41 -> 421,103
+674,475 -> 912,475
+455,626 -> 455,683
+952,841 -> 946,841
+920,792 -> 381,253
+786,918 -> 786,175
+889,859 -> 889,24
+178,604 -> 573,209
+71,621 -> 550,621
+38,36 -> 922,920
+104,690 -> 575,690
+252,883 -> 894,241
+627,107 -> 417,107
+768,913 -> 13,158
+708,337 -> 708,407
+156,941 -> 156,297
+814,653 -> 814,829
+234,920 -> 896,920
+652,170 -> 128,170
+765,825 -> 347,825
+681,901 -> 681,112
+410,301 -> 979,301
+462,681 -> 462,726
+117,957 -> 117,693
+479,948 -> 698,948
+839,965 -> 97,223
+102,189 -> 102,366
+93,798 -> 819,72
+27,336 -> 27,655
+161,635 -> 527,269
+140,272 -> 140,336
+884,915 -> 41,72
+575,563 -> 155,563
+387,601 -> 387,597
+355,186 -> 782,613
+866,435 -> 816,435
+96,161 -> 764,161
+971,29 -> 21,979
diff --git a/2021/05/line/line.go b/2021/05/line/line.go
new file mode 100644
index 0000000..aedf455
--- /dev/null
+++ b/2021/05/line/line.go
@@ -0,0 +1,239 @@
+package line
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "io"
+ "strconv"
+)
+
+type Line struct {
+ X1, Y1, X2, Y2 int
+}
+
+// Token represents a lexical token.
+type Token int
+
+const (
+ // Special tokens
+ ILLEGAL Token = iota
+ EOF
+ WHITESPACE
+
+ // Literals
+ INT // integers
+
+ // Misc characters
+ COMMA // ,
+ ARROW // ->
+)
+
+func isWhitespace(ch rune) bool {
+ return ch == ' ' || ch == '\t' || ch == '\n'
+}
+
+func isDigit(ch rune) bool {
+ return (ch >= '0' && ch <= '9')
+}
+
+var eof = rune(0)
+
+// Scanner represents a lexical scanner.
+type Scanner struct {
+ r *bufio.Reader
+}
+
+// NewScanner returns a new instance of Scanner.
+func NewScanner(r io.Reader) *Scanner {
+ return &Scanner{r: bufio.NewReader(r)}
+}
+
+// read reads the next rune from the bufferred reader.
+// Returns the rune(0) if an error occurs (or io.EOF is returned).
+func (s *Scanner) read() rune {
+ ch, _, err := s.r.ReadRune()
+ if err != nil {
+ return eof
+ }
+ return ch
+}
+
+// unread places the previously read rune back on the reader.
+func (s *Scanner) unread() { _ = s.r.UnreadRune() }
+
+// Scan returns the next token and literal value.
+func (s *Scanner) Scan() (tok Token, lit string) {
+ // Read the next rune.
+ ch := s.read()
+
+ // If we see whitespace then consume all contiguous whitespace.
+ // If we see a digit then consume as an int.
+ if isWhitespace(ch) {
+ return s.scanWhitespace(ch)
+ } else if isDigit(ch) {
+ return s.scanInt(ch)
+ }
+
+ // Otherwise read the individual character.
+ switch ch {
+ case eof:
+ return EOF, ""
+ case ',':
+ return COMMA, string(ch)
+ case '-':
+ return s.scanArrow(ch)
+ }
+
+ return ILLEGAL, string(ch)
+}
+
+// scanWhitespace consumes the current rune and all contiguous whitespace.
+func (s *Scanner) scanWhitespace(read rune) (tok Token, lit string) {
+ // Create a buffer and read the current character into it.
+ var buf bytes.Buffer
+ buf.WriteRune(read)
+
+ // Read every subsequent whitespace character into the buffer.
+ // Non-whitespace characters and EOF will cause the loop to exit.
+ for {
+ if ch := s.read(); ch == eof {
+ break
+ } else if !isWhitespace(ch) {
+ s.unread()
+ break
+ } else {
+ buf.WriteRune(ch)
+ }
+ }
+
+ return WHITESPACE, buf.String()
+}
+
+// scanInt consumes the current rune and all contiguous digit runes.
+func (s *Scanner) scanInt(read rune) (tok Token, lit string) {
+ // Create a buffer and read the current character into it.
+ var buf bytes.Buffer
+ buf.WriteRune(read)
+
+ // Read every subsequent ident character into the buffer.
+ // Non-ident characters and EOF will cause the loop to exit.
+ for {
+ if ch := s.read(); ch == eof {
+ break
+ } else if !isDigit(ch) {
+ s.unread()
+ break
+ } else {
+ _, _ = buf.WriteRune(ch)
+ }
+ }
+
+ // Otherwise return as a regular identifier.
+ return INT, buf.String()
+}
+
+func (s *Scanner) scanArrow(read rune) (tok Token, lit string) {
+ // Create a buffer and read the current character into it.
+ var buf bytes.Buffer
+ buf.WriteRune(read)
+
+ // Read every subsequent ident character into the buffer.
+ // Non-ident characters and EOF will cause the loop to exit.
+ for {
+ if ch := s.read(); ch == eof {
+ break
+ } else if ch == '>' {
+ _, _ = buf.WriteRune(ch)
+ return ARROW, buf.String()
+ } else {
+ _, _ = buf.WriteRune(ch)
+ break
+ }
+ }
+
+ // Otherwise return as a regular identifier.
+ return ILLEGAL, buf.String()
+}
+
+// Parser represents a parser.
+type Parser struct {
+ s *Scanner
+ buf struct {
+ tok Token // last read token
+ lit string // last read literal
+ n int // buffer size (max=1)
+ }
+}
+
+// NewParser returns a new instance of Parser.
+func NewParser(r io.Reader) *Parser {
+ return &Parser{s: NewScanner(r)}
+}
+
+// scan returns the next token from the underlying scanner.
+// If a token has been unscanned then read that instead.
+func (p *Parser) scan() (tok Token, lit string) {
+ // If we have a token on the buffer, then return it.
+ if p.buf.n != 0 {
+ p.buf.n = 0
+ return p.buf.tok, p.buf.lit
+ }
+
+ // Otherwise read the next token from the scanner.
+ tok, lit = p.s.Scan()
+
+ // Save it to the buffer in case we unscan later.
+ p.buf.tok, p.buf.lit = tok, lit
+
+ return
+}
+
+// unscan pushes the previously read token back onto the buffer.
+func (p *Parser) unscan() { p.buf.n = 1 }
+
+// scanIgnoreWhitespace scans the next non-whitespace token.
+func (p *Parser) scanIgnoreWhitespace() (tok Token, lit string) {
+ tok, lit = p.scan()
+ if tok == WHITESPACE {
+ tok, lit = p.scan()
+ }
+ return
+}
+
+func (p *Parser) Parse() (*Line, error) {
+ l := &Line{}
+ if tok, lit := p.scanIgnoreWhitespace(); tok != INT {
+ return nil, fmt.Errorf("found %q, expected INT", lit)
+ } else {
+ l.X1, _ = strconv.Atoi(lit)
+ }
+ if tok, lit := p.scanIgnoreWhitespace(); tok != COMMA {
+ return nil, fmt.Errorf("found %q, expected COMMA", lit)
+ }
+ if tok, lit := p.scanIgnoreWhitespace(); tok != INT {
+ return nil, fmt.Errorf("found %q, expected INT", lit)
+ } else {
+ l.Y1, _ = strconv.Atoi(lit)
+ }
+ if tok, lit := p.scanIgnoreWhitespace(); tok != ARROW {
+ return nil, fmt.Errorf("found %q, expected ARROW", lit)
+ }
+ if tok, lit := p.scanIgnoreWhitespace(); tok != INT {
+ return nil, fmt.Errorf("found %q, expected INT", lit)
+ } else {
+ l.X2, _ = strconv.Atoi(lit)
+ }
+ if tok, lit := p.scanIgnoreWhitespace(); tok != COMMA {
+ return nil, fmt.Errorf("found %q, expected COMMA", lit)
+ }
+ if tok, lit := p.scanIgnoreWhitespace(); tok != INT {
+ return nil, fmt.Errorf("found %q, expected INT", lit)
+ } else {
+ l.Y2, _ = strconv.Atoi(lit)
+ }
+ if tok, lit := p.scan(); tok != WHITESPACE {
+ return nil, fmt.Errorf("found %q, expected WHITESPACE", lit)
+ }
+ return l, nil
+}
diff --git a/2021/05/second.go b/2021/05/second.go
new file mode 100644
index 0000000..c79025a
--- /dev/null
+++ b/2021/05/second.go
@@ -0,0 +1,61 @@
+package main
+
+import (
+ "bufio"
+ "fmt"
+ "os"
+
+ "git.adyxax.org/aoc/2021/05/line"
+)
+
+func main() {
+ matrix := make([][]int, 1000)
+ for i := 0; i < 1000; i++ {
+ matrix[i] = make([]int, 1000)
+ }
+
+ parser := line.NewParser(bufio.NewReader(os.Stdin))
+ for {
+ l, err := parser.Parse()
+ if err != nil {
+ break
+ }
+ if l.X1 == l.X2 {
+ if l.Y1 > l.Y2 {
+ l.Y1, l.Y2 = l.Y2, l.Y1
+ }
+ for i := l.Y1; i <= l.Y2; i++ {
+ matrix[l.X1][i]++
+ }
+ } else if l.Y1 == l.Y2 {
+ if l.X1 > l.X2 {
+ l.X1, l.X2 = l.X2, l.X1
+ }
+ for i := l.X1; i <= l.X2; i++ {
+ matrix[i][l.Y1]++
+ }
+ } else {
+ if l.X1 > l.X2 {
+ l.X1, l.X2, l.Y1, l.Y2 = l.X2, l.X1, l.Y2, l.Y1
+ }
+ if l.Y1 < l.Y2 {
+ for i := 0; i <= l.X2-l.X1; i++ {
+ matrix[l.X1+i][l.Y1+i]++
+ }
+ } else {
+ for i := 0; i <= l.X2-l.X1; i++ {
+ matrix[l.X1+i][l.Y1-i]++
+ }
+ }
+ }
+ }
+ score := 0
+ for i := 0; i < 1000; i++ {
+ for j := 0; j < 1000; j++ {
+ if matrix[i][j] >= 2 {
+ score++
+ }
+ }
+ }
+ fmt.Println(score)
+}
diff --git a/2021/05/second_v2.go b/2021/05/second_v2.go
new file mode 100644
index 0000000..7d02a19
--- /dev/null
+++ b/2021/05/second_v2.go
@@ -0,0 +1,58 @@
+package main
+
+import (
+ "bufio"
+ "fmt"
+ "os"
+
+ "git.adyxax.org/aoc/2021/05/line"
+)
+
+func abs(a int) int {
+ if a < 0 {
+ return -a
+ }
+ return a
+}
+
+func computeDelta(a, b int) int {
+ if a < b {
+ return 1
+ } else if a > b {
+ return -1
+ }
+ return 0
+}
+
+func main() {
+ matrix := make([][]int, 1000)
+ for i := 0; i < 1000; i++ {
+ matrix[i] = make([]int, 1000)
+ }
+
+ parser := line.NewParser(bufio.NewReader(os.Stdin))
+ for {
+ l, err := parser.Parse()
+ if err != nil {
+ break
+ }
+ length := abs(l.X2 - l.X1)
+ if length == 0 {
+ length = abs(l.Y2 - l.Y1)
+ }
+ dx := computeDelta(l.X1, l.X2)
+ dy := computeDelta(l.Y1, l.Y2)
+ for i := 0; i <= length; i++ {
+ matrix[l.X1+i*dx][l.Y1+i*dy]++
+ }
+ }
+ score := 0
+ for i := 0; i < 1000; i++ {
+ for j := 0; j < 1000; j++ {
+ if matrix[i][j] >= 2 {
+ score++
+ }
+ }
+ }
+ fmt.Println(score)
+}