diff --git a/day05/input b/day05/input
new file mode 100644
index 0000000..7f0754f
--- /dev/null
+++ b/day05/input
@@ -0,0 +1,500 @@
+565,190 -> 756,381
+402,695 -> 402,138
+271,844 -> 98,844
+276,41 -> 276,282
+12,93 -> 512,593
+322,257 -> 157,422
+485,728 -> 685,528
+216,137 -> 593,514
+96,897 -> 984,897
+822,842 -> 70,842
+972,794 -> 972,43
+337,859 -> 562,859
+652,559 -> 652,245
+487,408 -> 952,408
+621,186 -> 621,592
+401,320 -> 981,320
+97,604 -> 97,892
+561,737 -> 561,142
+490,553 -> 48,553
+257,223 -> 694,660
+246,642 -> 877,11
+142,746 -> 656,746
+693,274 -> 272,695
+525,836 -> 525,74
+44,72 -> 861,889
+744,44 -> 117,671
+401,802 -> 350,802
+923,567 -> 705,567
+938,276 -> 938,297
+803,41 -> 435,41
+52,156 -> 836,940
+167,856 -> 906,117
+88,341 -> 130,341
+499,560 -> 499,593
+350,365 -> 350,739
+48,128 -> 989,128
+286,685 -> 886,685
+562,239 -> 562,229
+314,49 -> 314,125
+97,912 -> 985,24
+585,607 -> 585,572
+951,895 -> 234,178
+959,734 -> 11,734
+338,242 -> 796,242
+802,286 -> 426,286
+943,21 -> 56,908
+88,807 -> 821,74
+790,546 -> 790,270
+676,482 -> 676,740
+605,927 -> 178,927
+792,554 -> 403,943
+868,33 -> 868,835
+648,242 -> 648,704
+488,535 -> 836,883
+43,687 -> 43,286
+25,894 -> 277,894
+967,839 -> 494,366
+358,122 -> 305,122
+916,474 -> 175,474
+31,168 -> 31,44
+550,662 -> 527,662
+558,802 -> 669,691
+339,105 -> 339,108
+519,872 -> 25,378
+895,194 -> 752,337
+98,952 -> 205,952
+676,53 -> 676,728
+820,238 -> 815,238
+983,686 -> 934,735
+715,895 -> 715,234
+663,820 -> 201,820
+788,863 -> 57,132
+688,900 -> 688,160
+438,77 -> 360,77
+400,209 -> 152,457
+610,883 -> 610,97
+937,61 -> 150,848
+456,79 -> 456,825
+612,344 -> 58,344
+702,926 -> 43,267
+324,415 -> 145,415
+256,668 -> 256,116
+391,824 -> 108,824
+691,570 -> 464,797
+468,470 -> 468,773
+142,937 -> 99,937
+872,232 -> 393,711
+984,229 -> 273,940
+988,15 -> 425,578
+463,744 -> 463,904
+26,21 -> 26,947
+299,936 -> 911,324
+394,402 -> 821,402
+284,123 -> 628,467
+902,896 -> 212,206
+328,329 -> 436,329
+950,28 -> 59,919
+214,677 -> 214,952
+271,897 -> 856,897
+406,179 -> 406,242
+739,63 -> 962,286
+497,592 -> 817,912
+396,118 -> 865,587
+773,922 -> 29,178
+104,13 -> 694,603
+855,717 -> 631,493
+17,464 -> 946,464
+755,766 -> 755,379
+806,236 -> 14,236
+483,322 -> 948,322
+608,428 -> 716,428
+415,730 -> 685,730
+832,417 -> 569,680
+765,408 -> 765,784
+377,695 -> 612,460
+839,506 -> 839,242
+219,383 -> 219,27
+397,398 -> 397,633
+985,26 -> 32,979
+548,956 -> 404,812
+439,25 -> 186,25
+360,679 -> 360,455
+538,446 -> 162,822
+59,742 -> 535,742
+899,591 -> 902,591
+331,391 -> 331,513
+726,747 -> 454,747
+842,624 -> 648,624
+450,746 -> 982,746
+662,401 -> 662,663
+340,193 -> 206,193
+35,963 -> 318,963
+892,489 -> 88,489
+948,84 -> 417,84
+97,301 -> 97,95
+732,93 -> 887,248
+186,879 -> 976,89
+328,964 -> 157,964
+967,903 -> 903,903
+220,438 -> 134,438
+246,586 -> 822,586
+675,787 -> 675,735
+976,855 -> 113,855
+255,867 -> 607,515
+806,684 -> 509,684
+237,213 -> 237,859
+921,696 -> 893,696
+66,957 -> 66,559
+139,300 -> 267,300
+460,535 -> 460,829
+235,981 -> 394,981
+962,921 -> 240,199
+396,62 -> 47,62
+286,606 -> 594,914
+827,124 -> 827,188
+286,911 -> 487,911
+311,631 -> 311,271
+787,605 -> 787,965
+845,620 -> 922,697
+777,334 -> 237,874
+901,398 -> 881,378
+538,917 -> 568,917
+703,831 -> 257,831
+808,413 -> 808,967
+928,904 -> 239,215
+10,14 -> 984,988
+310,89 -> 310,100
+989,980 -> 23,14
+621,674 -> 621,45
+233,944 -> 458,719
+964,12 -> 99,12
+843,727 -> 241,125
+39,248 -> 39,447
+284,402 -> 284,571
+198,961 -> 198,127
+375,692 -> 666,401
+450,625 -> 435,610
+115,953 -> 115,339
+680,673 -> 614,673
+717,543 -> 444,816
+337,561 -> 76,561
+811,430 -> 643,598
+925,549 -> 720,549
+271,880 -> 941,210
+392,365 -> 622,365
+244,681 -> 285,681
+731,896 -> 711,876
+214,849 -> 214,924
+444,829 -> 799,829
+278,324 -> 117,163
+98,174 -> 98,644
+112,730 -> 626,730
+640,657 -> 640,710
+654,208 -> 689,173
+590,804 -> 26,240
+426,306 -> 783,663
+281,290 -> 767,290
+197,979 -> 36,979
+535,590 -> 844,281
+388,27 -> 15,400
+865,847 -> 332,847
+243,109 -> 243,731
+907,29 -> 752,29
+528,984 -> 764,984
+94,924 -> 886,132
+753,22 -> 50,725
+517,852 -> 517,293
+583,209 -> 583,34
+152,886 -> 808,230
+184,655 -> 298,655
+11,248 -> 11,470
+268,249 -> 898,249
+284,264 -> 284,827
+191,827 -> 286,827
+625,309 -> 550,309
+343,572 -> 815,572
+697,418 -> 606,509
+945,204 -> 945,660
+163,461 -> 203,421
+462,131 -> 565,28
+588,514 -> 151,77
+378,148 -> 631,401
+522,910 -> 522,68
+56,16 -> 973,933
+23,262 -> 422,661
+710,158 -> 641,158
+177,201 -> 177,892
+619,612 -> 414,407
+213,594 -> 213,614
+826,436 -> 815,436
+499,444 -> 499,487
+587,917 -> 571,933
+296,504 -> 296,808
+505,514 -> 601,514
+304,496 -> 304,581
+723,420 -> 723,63
+808,896 -> 55,143
+727,940 -> 558,771
+936,279 -> 545,279
+960,547 -> 606,547
+134,870 -> 504,500
+11,988 -> 989,10
+951,946 -> 25,20
+854,949 -> 217,312
+623,733 -> 623,813
+710,496 -> 446,496
+587,957 -> 907,957
+25,989 -> 970,44
+188,649 -> 773,64
+575,376 -> 951,376
+130,988 -> 680,438
+308,904 -> 104,700
+40,743 -> 40,171
+216,443 -> 216,825
+484,642 -> 875,251
+76,900 -> 402,900
+657,780 -> 704,827
+850,12 -> 33,829
+468,532 -> 942,532
+689,80 -> 687,80
+951,504 -> 951,614
+19,746 -> 19,320
+628,758 -> 628,113
+460,964 -> 498,964
+964,21 -> 42,943
+274,346 -> 274,440
+441,940 -> 441,463
+743,642 -> 304,203
+825,628 -> 423,628
+935,301 -> 935,859
+35,294 -> 353,294
+80,179 -> 879,978
+251,389 -> 251,854
+666,366 -> 126,366
+281,24 -> 281,465
+902,249 -> 902,561
+737,936 -> 737,153
+973,247 -> 973,964
+187,520 -> 44,377
+13,165 -> 13,757
+293,390 -> 493,190
+607,317 -> 607,102
+114,900 -> 103,900
+104,912 -> 851,165
+756,196 -> 756,273
+466,191 -> 837,562
+98,673 -> 98,231
+418,597 -> 966,597
+11,987 -> 988,10
+455,559 -> 693,321
+796,177 -> 175,798
+423,74 -> 423,984
+983,211 -> 211,211
+415,613 -> 415,537
+284,304 -> 284,835
+733,409 -> 733,659
+49,974 -> 718,305
+573,617 -> 856,900
+899,875 -> 191,167
+509,401 -> 738,172
+457,122 -> 457,951
+807,50 -> 18,839
+707,557 -> 707,985
+320,432 -> 366,478
+275,765 -> 850,190
+851,345 -> 556,640
+75,764 -> 409,764
+218,786 -> 218,732
+635,26 -> 388,26
+405,451 -> 763,809
+256,619 -> 378,741
+979,10 -> 22,967
+726,68 -> 322,68
+543,775 -> 543,147
+404,275 -> 404,331
+883,152 -> 289,746
+717,885 -> 717,497
+689,112 -> 25,776
+556,241 -> 556,826
+866,120 -> 708,278
+864,574 -> 864,230
+952,946 -> 179,946
+383,624 -> 450,557
+785,901 -> 785,985
+705,494 -> 621,494
+115,599 -> 115,948
+355,406 -> 164,406
+239,678 -> 444,678
+940,477 -> 714,477
+823,714 -> 175,66
+884,182 -> 86,980
+344,844 -> 852,336
+196,919 -> 76,919
+140,262 -> 140,884
+965,331 -> 965,363
+207,771 -> 207,696
+960,646 -> 387,73
+386,884 -> 653,884
+749,684 -> 786,721
+451,256 -> 633,256
+500,324 -> 966,790
+391,435 -> 391,843
+488,741 -> 630,883
+922,898 -> 117,93
+527,351 -> 630,351
+51,809 -> 51,681
+659,148 -> 713,148
+948,839 -> 948,843
+677,491 -> 304,491
+703,40 -> 703,915
+324,95 -> 324,144
+104,588 -> 104,91
+282,252 -> 282,262
+709,270 -> 72,907
+813,820 -> 142,149
+73,432 -> 846,432
+981,778 -> 981,209
+874,439 -> 502,439
+227,471 -> 227,558
+833,597 -> 833,34
+628,886 -> 628,549
+354,603 -> 354,153
+335,135 -> 875,675
+844,830 -> 844,182
+65,725 -> 65,484
+978,103 -> 152,929
+757,261 -> 157,861
+974,184 -> 974,931
+555,214 -> 555,69
+414,426 -> 468,426
+685,542 -> 685,105
+522,624 -> 298,624
+715,71 -> 715,810
+622,747 -> 622,474
+934,265 -> 934,343
+423,511 -> 423,77
+887,502 -> 887,515
+871,719 -> 835,719
+941,929 -> 692,680
+459,176 -> 219,176
+69,80 -> 942,953
+268,186 -> 268,243
+664,123 -> 974,123
+791,313 -> 920,313
+794,363 -> 333,824
+522,553 -> 522,117
+139,311 -> 345,311
+135,942 -> 486,942
+311,746 -> 311,843
+800,498 -> 800,418
+83,59 -> 640,616
+182,752 -> 182,748
+756,145 -> 347,145
+761,767 -> 617,767
+592,167 -> 379,380
+880,772 -> 104,772
+948,979 -> 845,979
+125,696 -> 634,696
+671,494 -> 671,550
+613,835 -> 613,869
+365,206 -> 97,206
+974,835 -> 181,42
+478,175 -> 478,297
+195,807 -> 844,807
+558,724 -> 886,724
+463,852 -> 463,467
+63,256 -> 123,316
+110,652 -> 429,652
+705,488 -> 652,488
+829,822 -> 158,151
+906,307 -> 906,668
+987,874 -> 274,874
+505,454 -> 505,484
+499,738 -> 499,102
+598,928 -> 293,928
+862,564 -> 558,564
+351,438 -> 351,854
+631,612 -> 148,129
+533,124 -> 945,124
+275,877 -> 410,877
+63,677 -> 286,454
+466,258 -> 466,851
+294,79 -> 715,500
+772,463 -> 680,463
+837,496 -> 837,336
+662,982 -> 330,650
+512,982 -> 536,982
+585,395 -> 640,395
+214,292 -> 485,563
+732,457 -> 976,457
+852,885 -> 852,582
+819,38 -> 138,719
+304,555 -> 304,569
+80,803 -> 481,803
+867,32 -> 535,32
+47,767 -> 785,29
+329,506 -> 329,930
+10,270 -> 598,270
+724,478 -> 270,932
+766,781 -> 766,671
+896,860 -> 134,98
+559,676 -> 632,676
+680,386 -> 892,174
+469,692 -> 504,692
+970,366 -> 970,390
+404,573 -> 663,314
+958,402 -> 618,402
+480,920 -> 480,964
+229,104 -> 229,582
+100,498 -> 100,532
+525,150 -> 522,150
+56,777 -> 426,777
+188,762 -> 599,762
+948,123 -> 872,123
+492,814 -> 812,814
+329,373 -> 253,373
+461,233 -> 742,514
+395,787 -> 946,236
+236,185 -> 576,185
+91,961 -> 911,141
+201,340 -> 769,908
+661,442 -> 661,592
+360,606 -> 360,984
+125,464 -> 825,464
+915,166 -> 793,44
+615,313 -> 132,796
+694,128 -> 817,128
+556,933 -> 556,801
+274,136 -> 116,136
+775,616 -> 282,123
+804,540 -> 546,798
+617,576 -> 374,576
+648,211 -> 200,659
+198,293 -> 395,293
+252,822 -> 304,822
+658,917 -> 658,239
+161,325 -> 185,325
+217,460 -> 217,736
+652,910 -> 15,273
+325,233 -> 627,233
+213,252 -> 879,252
+673,252 -> 607,186
+264,870 -> 946,188
+67,763 -> 67,829
+206,469 -> 762,469
+234,455 -> 604,85
+808,484 -> 808,708
+577,578 -> 809,578
+591,721 -> 591,558
+759,493 -> 564,298
+703,334 -> 571,334
+751,702 -> 128,79
+115,141 -> 882,908
+708,949 -> 334,949
+482,456 -> 482,382
+848,164 -> 44,968
+765,219 -> 935,219
+148,890 -> 508,890
+973,82 -> 308,747
+149,622 -> 893,622
diff --git a/day05/part1.nim b/day05/part1.nim
new file mode 100644
index 0000000..2a434d5
--- /dev/null
+++ b/day05/part1.nim
@@ -0,0 +1,91 @@
+# Copyright 2021 Christian Ulrich
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# usage: ./part1 < input
+
+import sequtils
+import strutils
+
+type
+ Point = tuple[x: uint16, y: uint16]
+
+ Line = tuple[start: Point, `end`: Point]
+
+ Orientation = enum
+ Horizontal, Vertical, Diagonal
+
+ Area = array[1000, array[1000, uint8]]
+
+proc orientation(line: Line): Orientation =
+ if line.start.y == line.end.y:
+ result = Horizontal
+ elif line.start.x == line.end.x:
+ result = Vertical
+ else:
+ result = Diagonal
+
+proc add(area: var Area, line: Line) =
+ case line.orientation()
+ of Horizontal:
+ for x in line.start.x .. line.end.x:
+ area[x][line.start.y].inc()
+ of Vertical:
+ for y in line.start.y .. line.end.y:
+ area[line.start.x][y].inc()
+ of Diagonal:
+ assert(false, "not implemented")
+
+proc initLine(start, `end`: Point): Line =
+ result = (start: start, `end`: `end`)
+ let orientation = result.orientation()
+ if orientation == Horizontal and result.start.x > result.end.x or
+ orientation == Vertical and result.start.y > result.end.y or
+ orientation == Diagonal and result.start.x > result.end.x:
+ result = (start: result.end, `end`: result.start)
+
+proc parsePoint(input: string): Point =
+ let coords = input.split(',', 1)
+ if coords.len() != 2:
+ raise newException(ValueError, "invalid point")
+ result = (x: uint16(parseUint(coords[0])), y: uint16(parseUint(coords[1])))
+
+proc parseLines(): seq[Line] =
+ var line = ""
+ while readLine(stdin, line):
+ if line.len() > 0:
+ let tokens = line.split(' ', 2)
+ if tokens.len() != 3 or tokens[1] != "->":
+ raise newException(ValueError, "invalid line")
+ result.add(initLine(parsePoint(tokens[0]), parsePoint(tokens[2])))
+
+proc countOverlaps(): int =
+ let lines = parseLines()
+ var area: Area
+ for line in lines.filterIt(it.orientation() in [Horizontal, Vertical]):
+ area.add(line)
+ for x in 0 .. high(area):
+ for y in 0 .. high(area[0]):
+ if area[x][y] > 1:
+ result.inc()
+
+proc main(): int =
+ try:
+ echo countOverlaps()
+ except Exception as error:
+ echo error.msg
+ result = -1
+
+when isMainModule:
+ quit(main())
diff --git a/day05/part2.nim b/day05/part2.nim
new file mode 100644
index 0000000..267fbd0
--- /dev/null
+++ b/day05/part2.nim
@@ -0,0 +1,98 @@
+# Copyright 2021 Christian Ulrich
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# usage: ./part2 < input
+
+import strutils
+
+type
+ Point = tuple[x: uint16, y: uint16]
+
+ Line = tuple[start: Point, `end`: Point]
+
+ Orientation = enum
+ Horizontal, Vertical, Diagonal
+
+ Area = array[1000, array[1000, uint8]]
+
+proc orientation(line: Line): Orientation =
+ if line.start.y == line.end.y:
+ result = Horizontal
+ elif line.start.x == line.end.x:
+ result = Vertical
+ else:
+ result = Diagonal
+
+proc add(area: var Area, line: Line) =
+ case line.orientation()
+ of Horizontal:
+ for x in line.start.x .. line.end.x:
+ area[x][line.start.y].inc()
+ of Vertical:
+ for y in line.start.y .. line.end.y:
+ area[line.start.x][y].inc()
+ of Diagonal:
+ var x = line.start.x
+ if line.start.y < line.end.y:
+ for y in countup(line.start.y, line.end.y):
+ area[x][y].inc()
+ x.inc()
+ else:
+ for y in countdown(line.start.y, line.end.y):
+ area[x][y].inc()
+ x.inc()
+
+proc initLine(start, `end`: Point): Line =
+ result = (start: start, `end`: `end`)
+ let orientation = result.orientation()
+ if orientation == Horizontal and result.start.x > result.end.x or
+ orientation == Vertical and result.start.y > result.end.y or
+ orientation == Diagonal and result.start.x > result.end.x:
+ result = (start: result.end, `end`: result.start)
+
+proc parsePoint(input: string): Point =
+ let coords = input.split(',', 1)
+ if coords.len() != 2:
+ raise newException(ValueError, "invalid point")
+ result = (x: uint16(parseUint(coords[0])), y: uint16(parseUint(coords[1])))
+
+proc parseLines(): seq[Line] =
+ var line = ""
+ while readLine(stdin, line):
+ if line.len() > 0:
+ let tokens = line.split(' ', 2)
+ if tokens.len() != 3 or tokens[1] != "->":
+ raise newException(ValueError, "invalid line")
+ result.add(initLine(parsePoint(tokens[0]), parsePoint(tokens[2])))
+
+proc countOverlaps(): int =
+ let lines = parseLines()
+ var area: Area
+ for line in lines:
+ area.add(line)
+ for x in 0 .. high(area):
+ for y in 0 .. high(area[0]):
+ if area[x][y] > 1:
+ result.inc()
+
+proc main(): int =
+ try:
+ echo countOverlaps()
+ except Exception as error:
+ echo error.msg
+ result = -1
+
+when isMainModule:
+ quit(main())
diff --git a/day05/testinput b/day05/testinput
new file mode 100644
index 0000000..b258f68
--- /dev/null
+++ b/day05/testinput
@@ -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