Compare commits
No commits in common. "c2ea2ec16e932ebbcbd448e8cde2bb6489832683" and "16cb2be49b0f6a92ccc5329100686489ef8514d4" have entirely different histories.
c2ea2ec16e
...
16cb2be49b
147
day14-input.txt
147
day14-input.txt
|
@ -1,147 +0,0 @@
|
||||||
502,19 -> 507,19
|
|
||||||
523,100 -> 523,104 -> 519,104 -> 519,111 -> 528,111 -> 528,104 -> 526,104 -> 526,100
|
|
||||||
488,59 -> 488,51 -> 488,59 -> 490,59 -> 490,52 -> 490,59 -> 492,59 -> 492,55 -> 492,59 -> 494,59 -> 494,52 -> 494,59 -> 496,59 -> 496,50 -> 496,59 -> 498,59 -> 498,58 -> 498,59 -> 500,59 -> 500,56 -> 500,59 -> 502,59 -> 502,56 -> 502,59 -> 504,59 -> 504,57 -> 504,59
|
|
||||||
507,117 -> 521,117 -> 521,116
|
|
||||||
517,34 -> 522,34
|
|
||||||
513,97 -> 513,89 -> 513,97 -> 515,97 -> 515,94 -> 515,97 -> 517,97 -> 517,94 -> 517,97 -> 519,97 -> 519,93 -> 519,97 -> 521,97 -> 521,88 -> 521,97 -> 523,97 -> 523,94 -> 523,97
|
|
||||||
513,97 -> 513,89 -> 513,97 -> 515,97 -> 515,94 -> 515,97 -> 517,97 -> 517,94 -> 517,97 -> 519,97 -> 519,93 -> 519,97 -> 521,97 -> 521,88 -> 521,97 -> 523,97 -> 523,94 -> 523,97
|
|
||||||
510,75 -> 510,78 -> 505,78 -> 505,84 -> 518,84 -> 518,78 -> 515,78 -> 515,75
|
|
||||||
503,34 -> 508,34
|
|
||||||
501,15 -> 506,15
|
|
||||||
523,136 -> 523,138 -> 518,138 -> 518,145 -> 535,145 -> 535,138 -> 528,138 -> 528,136
|
|
||||||
513,113 -> 513,114 -> 527,114
|
|
||||||
488,59 -> 488,51 -> 488,59 -> 490,59 -> 490,52 -> 490,59 -> 492,59 -> 492,55 -> 492,59 -> 494,59 -> 494,52 -> 494,59 -> 496,59 -> 496,50 -> 496,59 -> 498,59 -> 498,58 -> 498,59 -> 500,59 -> 500,56 -> 500,59 -> 502,59 -> 502,56 -> 502,59 -> 504,59 -> 504,57 -> 504,59
|
|
||||||
497,72 -> 497,63 -> 497,72 -> 499,72 -> 499,65 -> 499,72 -> 501,72 -> 501,71 -> 501,72 -> 503,72 -> 503,67 -> 503,72 -> 505,72 -> 505,63 -> 505,72 -> 507,72 -> 507,71 -> 507,72 -> 509,72 -> 509,70 -> 509,72 -> 511,72 -> 511,69 -> 511,72
|
|
||||||
497,72 -> 497,63 -> 497,72 -> 499,72 -> 499,65 -> 499,72 -> 501,72 -> 501,71 -> 501,72 -> 503,72 -> 503,67 -> 503,72 -> 505,72 -> 505,63 -> 505,72 -> 507,72 -> 507,71 -> 507,72 -> 509,72 -> 509,70 -> 509,72 -> 511,72 -> 511,69 -> 511,72
|
|
||||||
497,72 -> 497,63 -> 497,72 -> 499,72 -> 499,65 -> 499,72 -> 501,72 -> 501,71 -> 501,72 -> 503,72 -> 503,67 -> 503,72 -> 505,72 -> 505,63 -> 505,72 -> 507,72 -> 507,71 -> 507,72 -> 509,72 -> 509,70 -> 509,72 -> 511,72 -> 511,69 -> 511,72
|
|
||||||
497,72 -> 497,63 -> 497,72 -> 499,72 -> 499,65 -> 499,72 -> 501,72 -> 501,71 -> 501,72 -> 503,72 -> 503,67 -> 503,72 -> 505,72 -> 505,63 -> 505,72 -> 507,72 -> 507,71 -> 507,72 -> 509,72 -> 509,70 -> 509,72 -> 511,72 -> 511,69 -> 511,72
|
|
||||||
488,59 -> 488,51 -> 488,59 -> 490,59 -> 490,52 -> 490,59 -> 492,59 -> 492,55 -> 492,59 -> 494,59 -> 494,52 -> 494,59 -> 496,59 -> 496,50 -> 496,59 -> 498,59 -> 498,58 -> 498,59 -> 500,59 -> 500,56 -> 500,59 -> 502,59 -> 502,56 -> 502,59 -> 504,59 -> 504,57 -> 504,59
|
|
||||||
523,136 -> 523,138 -> 518,138 -> 518,145 -> 535,145 -> 535,138 -> 528,138 -> 528,136
|
|
||||||
530,150 -> 535,150
|
|
||||||
526,133 -> 526,131 -> 526,133 -> 528,133 -> 528,129 -> 528,133 -> 530,133 -> 530,129 -> 530,133
|
|
||||||
523,100 -> 523,104 -> 519,104 -> 519,111 -> 528,111 -> 528,104 -> 526,104 -> 526,100
|
|
||||||
488,59 -> 488,51 -> 488,59 -> 490,59 -> 490,52 -> 490,59 -> 492,59 -> 492,55 -> 492,59 -> 494,59 -> 494,52 -> 494,59 -> 496,59 -> 496,50 -> 496,59 -> 498,59 -> 498,58 -> 498,59 -> 500,59 -> 500,56 -> 500,59 -> 502,59 -> 502,56 -> 502,59 -> 504,59 -> 504,57 -> 504,59
|
|
||||||
510,34 -> 515,34
|
|
||||||
497,72 -> 497,63 -> 497,72 -> 499,72 -> 499,65 -> 499,72 -> 501,72 -> 501,71 -> 501,72 -> 503,72 -> 503,67 -> 503,72 -> 505,72 -> 505,63 -> 505,72 -> 507,72 -> 507,71 -> 507,72 -> 509,72 -> 509,70 -> 509,72 -> 511,72 -> 511,69 -> 511,72
|
|
||||||
510,75 -> 510,78 -> 505,78 -> 505,84 -> 518,84 -> 518,78 -> 515,78 -> 515,75
|
|
||||||
488,59 -> 488,51 -> 488,59 -> 490,59 -> 490,52 -> 490,59 -> 492,59 -> 492,55 -> 492,59 -> 494,59 -> 494,52 -> 494,59 -> 496,59 -> 496,50 -> 496,59 -> 498,59 -> 498,58 -> 498,59 -> 500,59 -> 500,56 -> 500,59 -> 502,59 -> 502,56 -> 502,59 -> 504,59 -> 504,57 -> 504,59
|
|
||||||
488,59 -> 488,51 -> 488,59 -> 490,59 -> 490,52 -> 490,59 -> 492,59 -> 492,55 -> 492,59 -> 494,59 -> 494,52 -> 494,59 -> 496,59 -> 496,50 -> 496,59 -> 498,59 -> 498,58 -> 498,59 -> 500,59 -> 500,56 -> 500,59 -> 502,59 -> 502,56 -> 502,59 -> 504,59 -> 504,57 -> 504,59
|
|
||||||
524,34 -> 529,34
|
|
||||||
498,46 -> 502,46
|
|
||||||
510,46 -> 514,46
|
|
||||||
509,19 -> 514,19
|
|
||||||
513,97 -> 513,89 -> 513,97 -> 515,97 -> 515,94 -> 515,97 -> 517,97 -> 517,94 -> 517,97 -> 519,97 -> 519,93 -> 519,97 -> 521,97 -> 521,88 -> 521,97 -> 523,97 -> 523,94 -> 523,97
|
|
||||||
526,133 -> 526,131 -> 526,133 -> 528,133 -> 528,129 -> 528,133 -> 530,133 -> 530,129 -> 530,133
|
|
||||||
497,13 -> 502,13
|
|
||||||
504,46 -> 508,46
|
|
||||||
488,59 -> 488,51 -> 488,59 -> 490,59 -> 490,52 -> 490,59 -> 492,59 -> 492,55 -> 492,59 -> 494,59 -> 494,52 -> 494,59 -> 496,59 -> 496,50 -> 496,59 -> 498,59 -> 498,58 -> 498,59 -> 500,59 -> 500,56 -> 500,59 -> 502,59 -> 502,56 -> 502,59 -> 504,59 -> 504,57 -> 504,59
|
|
||||||
545,155 -> 545,157 -> 541,157 -> 541,160 -> 556,160 -> 556,157 -> 550,157 -> 550,155
|
|
||||||
513,97 -> 513,89 -> 513,97 -> 515,97 -> 515,94 -> 515,97 -> 517,97 -> 517,94 -> 517,97 -> 519,97 -> 519,93 -> 519,97 -> 521,97 -> 521,88 -> 521,97 -> 523,97 -> 523,94 -> 523,97
|
|
||||||
510,75 -> 510,78 -> 505,78 -> 505,84 -> 518,84 -> 518,78 -> 515,78 -> 515,75
|
|
||||||
497,72 -> 497,63 -> 497,72 -> 499,72 -> 499,65 -> 499,72 -> 501,72 -> 501,71 -> 501,72 -> 503,72 -> 503,67 -> 503,72 -> 505,72 -> 505,63 -> 505,72 -> 507,72 -> 507,71 -> 507,72 -> 509,72 -> 509,70 -> 509,72 -> 511,72 -> 511,69 -> 511,72
|
|
||||||
513,97 -> 513,89 -> 513,97 -> 515,97 -> 515,94 -> 515,97 -> 517,97 -> 517,94 -> 517,97 -> 519,97 -> 519,93 -> 519,97 -> 521,97 -> 521,88 -> 521,97 -> 523,97 -> 523,94 -> 523,97
|
|
||||||
488,59 -> 488,51 -> 488,59 -> 490,59 -> 490,52 -> 490,59 -> 492,59 -> 492,55 -> 492,59 -> 494,59 -> 494,52 -> 494,59 -> 496,59 -> 496,50 -> 496,59 -> 498,59 -> 498,58 -> 498,59 -> 500,59 -> 500,56 -> 500,59 -> 502,59 -> 502,56 -> 502,59 -> 504,59 -> 504,57 -> 504,59
|
|
||||||
488,59 -> 488,51 -> 488,59 -> 490,59 -> 490,52 -> 490,59 -> 492,59 -> 492,55 -> 492,59 -> 494,59 -> 494,52 -> 494,59 -> 496,59 -> 496,50 -> 496,59 -> 498,59 -> 498,58 -> 498,59 -> 500,59 -> 500,56 -> 500,59 -> 502,59 -> 502,56 -> 502,59 -> 504,59 -> 504,57 -> 504,59
|
|
||||||
507,43 -> 511,43
|
|
||||||
523,100 -> 523,104 -> 519,104 -> 519,111 -> 528,111 -> 528,104 -> 526,104 -> 526,100
|
|
||||||
506,31 -> 511,31
|
|
||||||
497,72 -> 497,63 -> 497,72 -> 499,72 -> 499,65 -> 499,72 -> 501,72 -> 501,71 -> 501,72 -> 503,72 -> 503,67 -> 503,72 -> 505,72 -> 505,63 -> 505,72 -> 507,72 -> 507,71 -> 507,72 -> 509,72 -> 509,70 -> 509,72 -> 511,72 -> 511,69 -> 511,72
|
|
||||||
510,75 -> 510,78 -> 505,78 -> 505,84 -> 518,84 -> 518,78 -> 515,78 -> 515,75
|
|
||||||
513,97 -> 513,89 -> 513,97 -> 515,97 -> 515,94 -> 515,97 -> 517,97 -> 517,94 -> 517,97 -> 519,97 -> 519,93 -> 519,97 -> 521,97 -> 521,88 -> 521,97 -> 523,97 -> 523,94 -> 523,97
|
|
||||||
507,117 -> 521,117 -> 521,116
|
|
||||||
488,59 -> 488,51 -> 488,59 -> 490,59 -> 490,52 -> 490,59 -> 492,59 -> 492,55 -> 492,59 -> 494,59 -> 494,52 -> 494,59 -> 496,59 -> 496,50 -> 496,59 -> 498,59 -> 498,58 -> 498,59 -> 500,59 -> 500,56 -> 500,59 -> 502,59 -> 502,56 -> 502,59 -> 504,59 -> 504,57 -> 504,59
|
|
||||||
534,152 -> 539,152
|
|
||||||
513,97 -> 513,89 -> 513,97 -> 515,97 -> 515,94 -> 515,97 -> 517,97 -> 517,94 -> 517,97 -> 519,97 -> 519,93 -> 519,97 -> 521,97 -> 521,88 -> 521,97 -> 523,97 -> 523,94 -> 523,97
|
|
||||||
488,59 -> 488,51 -> 488,59 -> 490,59 -> 490,52 -> 490,59 -> 492,59 -> 492,55 -> 492,59 -> 494,59 -> 494,52 -> 494,59 -> 496,59 -> 496,50 -> 496,59 -> 498,59 -> 498,58 -> 498,59 -> 500,59 -> 500,56 -> 500,59 -> 502,59 -> 502,56 -> 502,59 -> 504,59 -> 504,57 -> 504,59
|
|
||||||
497,72 -> 497,63 -> 497,72 -> 499,72 -> 499,65 -> 499,72 -> 501,72 -> 501,71 -> 501,72 -> 503,72 -> 503,67 -> 503,72 -> 505,72 -> 505,63 -> 505,72 -> 507,72 -> 507,71 -> 507,72 -> 509,72 -> 509,70 -> 509,72 -> 511,72 -> 511,69 -> 511,72
|
|
||||||
495,19 -> 500,19
|
|
||||||
488,59 -> 488,51 -> 488,59 -> 490,59 -> 490,52 -> 490,59 -> 492,59 -> 492,55 -> 492,59 -> 494,59 -> 494,52 -> 494,59 -> 496,59 -> 496,50 -> 496,59 -> 498,59 -> 498,58 -> 498,59 -> 500,59 -> 500,56 -> 500,59 -> 502,59 -> 502,56 -> 502,59 -> 504,59 -> 504,57 -> 504,59
|
|
||||||
513,97 -> 513,89 -> 513,97 -> 515,97 -> 515,94 -> 515,97 -> 517,97 -> 517,94 -> 517,97 -> 519,97 -> 519,93 -> 519,97 -> 521,97 -> 521,88 -> 521,97 -> 523,97 -> 523,94 -> 523,97
|
|
||||||
497,72 -> 497,63 -> 497,72 -> 499,72 -> 499,65 -> 499,72 -> 501,72 -> 501,71 -> 501,72 -> 503,72 -> 503,67 -> 503,72 -> 505,72 -> 505,63 -> 505,72 -> 507,72 -> 507,71 -> 507,72 -> 509,72 -> 509,70 -> 509,72 -> 511,72 -> 511,69 -> 511,72
|
|
||||||
513,97 -> 513,89 -> 513,97 -> 515,97 -> 515,94 -> 515,97 -> 517,97 -> 517,94 -> 517,97 -> 519,97 -> 519,93 -> 519,97 -> 521,97 -> 521,88 -> 521,97 -> 523,97 -> 523,94 -> 523,97
|
|
||||||
523,136 -> 523,138 -> 518,138 -> 518,145 -> 535,145 -> 535,138 -> 528,138 -> 528,136
|
|
||||||
497,72 -> 497,63 -> 497,72 -> 499,72 -> 499,65 -> 499,72 -> 501,72 -> 501,71 -> 501,72 -> 503,72 -> 503,67 -> 503,72 -> 505,72 -> 505,63 -> 505,72 -> 507,72 -> 507,71 -> 507,72 -> 509,72 -> 509,70 -> 509,72 -> 511,72 -> 511,69 -> 511,72
|
|
||||||
527,152 -> 532,152
|
|
||||||
513,97 -> 513,89 -> 513,97 -> 515,97 -> 515,94 -> 515,97 -> 517,97 -> 517,94 -> 517,97 -> 519,97 -> 519,93 -> 519,97 -> 521,97 -> 521,88 -> 521,97 -> 523,97 -> 523,94 -> 523,97
|
|
||||||
533,148 -> 538,148
|
|
||||||
510,75 -> 510,78 -> 505,78 -> 505,84 -> 518,84 -> 518,78 -> 515,78 -> 515,75
|
|
||||||
488,59 -> 488,51 -> 488,59 -> 490,59 -> 490,52 -> 490,59 -> 492,59 -> 492,55 -> 492,59 -> 494,59 -> 494,52 -> 494,59 -> 496,59 -> 496,50 -> 496,59 -> 498,59 -> 498,58 -> 498,59 -> 500,59 -> 500,56 -> 500,59 -> 502,59 -> 502,56 -> 502,59 -> 504,59 -> 504,57 -> 504,59
|
|
||||||
516,46 -> 520,46
|
|
||||||
497,72 -> 497,63 -> 497,72 -> 499,72 -> 499,65 -> 499,72 -> 501,72 -> 501,71 -> 501,72 -> 503,72 -> 503,67 -> 503,72 -> 505,72 -> 505,63 -> 505,72 -> 507,72 -> 507,71 -> 507,72 -> 509,72 -> 509,70 -> 509,72 -> 511,72 -> 511,69 -> 511,72
|
|
||||||
497,72 -> 497,63 -> 497,72 -> 499,72 -> 499,65 -> 499,72 -> 501,72 -> 501,71 -> 501,72 -> 503,72 -> 503,67 -> 503,72 -> 505,72 -> 505,63 -> 505,72 -> 507,72 -> 507,71 -> 507,72 -> 509,72 -> 509,70 -> 509,72 -> 511,72 -> 511,69 -> 511,72
|
|
||||||
545,155 -> 545,157 -> 541,157 -> 541,160 -> 556,160 -> 556,157 -> 550,157 -> 550,155
|
|
||||||
501,119 -> 501,120 -> 512,120 -> 512,119
|
|
||||||
513,97 -> 513,89 -> 513,97 -> 515,97 -> 515,94 -> 515,97 -> 517,97 -> 517,94 -> 517,97 -> 519,97 -> 519,93 -> 519,97 -> 521,97 -> 521,88 -> 521,97 -> 523,97 -> 523,94 -> 523,97
|
|
||||||
488,59 -> 488,51 -> 488,59 -> 490,59 -> 490,52 -> 490,59 -> 492,59 -> 492,55 -> 492,59 -> 494,59 -> 494,52 -> 494,59 -> 496,59 -> 496,50 -> 496,59 -> 498,59 -> 498,58 -> 498,59 -> 500,59 -> 500,56 -> 500,59 -> 502,59 -> 502,56 -> 502,59 -> 504,59 -> 504,57 -> 504,59
|
|
||||||
512,25 -> 517,25
|
|
||||||
526,133 -> 526,131 -> 526,133 -> 528,133 -> 528,129 -> 528,133 -> 530,133 -> 530,129 -> 530,133
|
|
||||||
497,72 -> 497,63 -> 497,72 -> 499,72 -> 499,65 -> 499,72 -> 501,72 -> 501,71 -> 501,72 -> 503,72 -> 503,67 -> 503,72 -> 505,72 -> 505,63 -> 505,72 -> 507,72 -> 507,71 -> 507,72 -> 509,72 -> 509,70 -> 509,72 -> 511,72 -> 511,69 -> 511,72
|
|
||||||
513,97 -> 513,89 -> 513,97 -> 515,97 -> 515,94 -> 515,97 -> 517,97 -> 517,94 -> 517,97 -> 519,97 -> 519,93 -> 519,97 -> 521,97 -> 521,88 -> 521,97 -> 523,97 -> 523,94 -> 523,97
|
|
||||||
513,31 -> 518,31
|
|
||||||
526,133 -> 526,131 -> 526,133 -> 528,133 -> 528,129 -> 528,133 -> 530,133 -> 530,129 -> 530,133
|
|
||||||
488,59 -> 488,51 -> 488,59 -> 490,59 -> 490,52 -> 490,59 -> 492,59 -> 492,55 -> 492,59 -> 494,59 -> 494,52 -> 494,59 -> 496,59 -> 496,50 -> 496,59 -> 498,59 -> 498,58 -> 498,59 -> 500,59 -> 500,56 -> 500,59 -> 502,59 -> 502,56 -> 502,59 -> 504,59 -> 504,57 -> 504,59
|
|
||||||
520,31 -> 525,31
|
|
||||||
497,72 -> 497,63 -> 497,72 -> 499,72 -> 499,65 -> 499,72 -> 501,72 -> 501,71 -> 501,72 -> 503,72 -> 503,67 -> 503,72 -> 505,72 -> 505,63 -> 505,72 -> 507,72 -> 507,71 -> 507,72 -> 509,72 -> 509,70 -> 509,72 -> 511,72 -> 511,69 -> 511,72
|
|
||||||
482,21 -> 482,22 -> 490,22
|
|
||||||
510,75 -> 510,78 -> 505,78 -> 505,84 -> 518,84 -> 518,78 -> 515,78 -> 515,75
|
|
||||||
498,17 -> 503,17
|
|
||||||
523,136 -> 523,138 -> 518,138 -> 518,145 -> 535,145 -> 535,138 -> 528,138 -> 528,136
|
|
||||||
545,155 -> 545,157 -> 541,157 -> 541,160 -> 556,160 -> 556,157 -> 550,157 -> 550,155
|
|
||||||
513,43 -> 517,43
|
|
||||||
523,100 -> 523,104 -> 519,104 -> 519,111 -> 528,111 -> 528,104 -> 526,104 -> 526,100
|
|
||||||
505,17 -> 510,17
|
|
||||||
497,72 -> 497,63 -> 497,72 -> 499,72 -> 499,65 -> 499,72 -> 501,72 -> 501,71 -> 501,72 -> 503,72 -> 503,67 -> 503,72 -> 505,72 -> 505,63 -> 505,72 -> 507,72 -> 507,71 -> 507,72 -> 509,72 -> 509,70 -> 509,72 -> 511,72 -> 511,69 -> 511,72
|
|
||||||
509,28 -> 514,28
|
|
||||||
545,155 -> 545,157 -> 541,157 -> 541,160 -> 556,160 -> 556,157 -> 550,157 -> 550,155
|
|
||||||
537,150 -> 542,150
|
|
||||||
497,72 -> 497,63 -> 497,72 -> 499,72 -> 499,65 -> 499,72 -> 501,72 -> 501,71 -> 501,72 -> 503,72 -> 503,67 -> 503,72 -> 505,72 -> 505,63 -> 505,72 -> 507,72 -> 507,71 -> 507,72 -> 509,72 -> 509,70 -> 509,72 -> 511,72 -> 511,69 -> 511,72
|
|
||||||
501,43 -> 505,43
|
|
||||||
513,97 -> 513,89 -> 513,97 -> 515,97 -> 515,94 -> 515,97 -> 517,97 -> 517,94 -> 517,97 -> 519,97 -> 519,93 -> 519,97 -> 521,97 -> 521,88 -> 521,97 -> 523,97 -> 523,94 -> 523,97
|
|
||||||
488,59 -> 488,51 -> 488,59 -> 490,59 -> 490,52 -> 490,59 -> 492,59 -> 492,55 -> 492,59 -> 494,59 -> 494,52 -> 494,59 -> 496,59 -> 496,50 -> 496,59 -> 498,59 -> 498,58 -> 498,59 -> 500,59 -> 500,56 -> 500,59 -> 502,59 -> 502,56 -> 502,59 -> 504,59 -> 504,57 -> 504,59
|
|
||||||
497,72 -> 497,63 -> 497,72 -> 499,72 -> 499,65 -> 499,72 -> 501,72 -> 501,71 -> 501,72 -> 503,72 -> 503,67 -> 503,72 -> 505,72 -> 505,63 -> 505,72 -> 507,72 -> 507,71 -> 507,72 -> 509,72 -> 509,70 -> 509,72 -> 511,72 -> 511,69 -> 511,72
|
|
||||||
501,119 -> 501,120 -> 512,120 -> 512,119
|
|
||||||
507,37 -> 511,37
|
|
||||||
497,72 -> 497,63 -> 497,72 -> 499,72 -> 499,65 -> 499,72 -> 501,72 -> 501,71 -> 501,72 -> 503,72 -> 503,67 -> 503,72 -> 505,72 -> 505,63 -> 505,72 -> 507,72 -> 507,71 -> 507,72 -> 509,72 -> 509,70 -> 509,72 -> 511,72 -> 511,69 -> 511,72
|
|
||||||
488,59 -> 488,51 -> 488,59 -> 490,59 -> 490,52 -> 490,59 -> 492,59 -> 492,55 -> 492,59 -> 494,59 -> 494,52 -> 494,59 -> 496,59 -> 496,50 -> 496,59 -> 498,59 -> 498,58 -> 498,59 -> 500,59 -> 500,56 -> 500,59 -> 502,59 -> 502,56 -> 502,59 -> 504,59 -> 504,57 -> 504,59
|
|
||||||
523,100 -> 523,104 -> 519,104 -> 519,111 -> 528,111 -> 528,104 -> 526,104 -> 526,100
|
|
||||||
488,59 -> 488,51 -> 488,59 -> 490,59 -> 490,52 -> 490,59 -> 492,59 -> 492,55 -> 492,59 -> 494,59 -> 494,52 -> 494,59 -> 496,59 -> 496,50 -> 496,59 -> 498,59 -> 498,58 -> 498,59 -> 500,59 -> 500,56 -> 500,59 -> 502,59 -> 502,56 -> 502,59 -> 504,59 -> 504,57 -> 504,59
|
|
||||||
513,97 -> 513,89 -> 513,97 -> 515,97 -> 515,94 -> 515,97 -> 517,97 -> 517,94 -> 517,97 -> 519,97 -> 519,93 -> 519,97 -> 521,97 -> 521,88 -> 521,97 -> 523,97 -> 523,94 -> 523,97
|
|
||||||
501,119 -> 501,120 -> 512,120 -> 512,119
|
|
||||||
510,40 -> 514,40
|
|
||||||
488,19 -> 493,19
|
|
||||||
482,21 -> 482,22 -> 490,22
|
|
||||||
494,15 -> 499,15
|
|
||||||
523,136 -> 523,138 -> 518,138 -> 518,145 -> 535,145 -> 535,138 -> 528,138 -> 528,136
|
|
||||||
526,133 -> 526,131 -> 526,133 -> 528,133 -> 528,129 -> 528,133 -> 530,133 -> 530,129 -> 530,133
|
|
||||||
513,97 -> 513,89 -> 513,97 -> 515,97 -> 515,94 -> 515,97 -> 517,97 -> 517,94 -> 517,97 -> 519,97 -> 519,93 -> 519,97 -> 521,97 -> 521,88 -> 521,97 -> 523,97 -> 523,94 -> 523,97
|
|
||||||
488,59 -> 488,51 -> 488,59 -> 490,59 -> 490,52 -> 490,59 -> 492,59 -> 492,55 -> 492,59 -> 494,59 -> 494,52 -> 494,59 -> 496,59 -> 496,50 -> 496,59 -> 498,59 -> 498,58 -> 498,59 -> 500,59 -> 500,56 -> 500,59 -> 502,59 -> 502,56 -> 502,59 -> 504,59 -> 504,57 -> 504,59
|
|
||||||
488,59 -> 488,51 -> 488,59 -> 490,59 -> 490,52 -> 490,59 -> 492,59 -> 492,55 -> 492,59 -> 494,59 -> 494,52 -> 494,59 -> 496,59 -> 496,50 -> 496,59 -> 498,59 -> 498,58 -> 498,59 -> 500,59 -> 500,56 -> 500,59 -> 502,59 -> 502,56 -> 502,59 -> 504,59 -> 504,57 -> 504,59
|
|
||||||
488,59 -> 488,51 -> 488,59 -> 490,59 -> 490,52 -> 490,59 -> 492,59 -> 492,55 -> 492,59 -> 494,59 -> 494,52 -> 494,59 -> 496,59 -> 496,50 -> 496,59 -> 498,59 -> 498,58 -> 498,59 -> 500,59 -> 500,56 -> 500,59 -> 502,59 -> 502,56 -> 502,59 -> 504,59 -> 504,57 -> 504,59
|
|
||||||
526,133 -> 526,131 -> 526,133 -> 528,133 -> 528,129 -> 528,133 -> 530,133 -> 530,129 -> 530,133
|
|
||||||
513,97 -> 513,89 -> 513,97 -> 515,97 -> 515,94 -> 515,97 -> 517,97 -> 517,94 -> 517,97 -> 519,97 -> 519,93 -> 519,97 -> 521,97 -> 521,88 -> 521,97 -> 523,97 -> 523,94 -> 523,97
|
|
||||||
488,59 -> 488,51 -> 488,59 -> 490,59 -> 490,52 -> 490,59 -> 492,59 -> 492,55 -> 492,59 -> 494,59 -> 494,52 -> 494,59 -> 496,59 -> 496,50 -> 496,59 -> 498,59 -> 498,58 -> 498,59 -> 500,59 -> 500,56 -> 500,59 -> 502,59 -> 502,56 -> 502,59 -> 504,59 -> 504,57 -> 504,59
|
|
||||||
545,155 -> 545,157 -> 541,157 -> 541,160 -> 556,160 -> 556,157 -> 550,157 -> 550,155
|
|
||||||
513,97 -> 513,89 -> 513,97 -> 515,97 -> 515,94 -> 515,97 -> 517,97 -> 517,94 -> 517,97 -> 519,97 -> 519,93 -> 519,97 -> 521,97 -> 521,88 -> 521,97 -> 523,97 -> 523,94 -> 523,97
|
|
||||||
523,136 -> 523,138 -> 518,138 -> 518,145 -> 535,145 -> 535,138 -> 528,138 -> 528,136
|
|
||||||
504,40 -> 508,40
|
|
||||||
497,72 -> 497,63 -> 497,72 -> 499,72 -> 499,65 -> 499,72 -> 501,72 -> 501,71 -> 501,72 -> 503,72 -> 503,67 -> 503,72 -> 505,72 -> 505,63 -> 505,72 -> 507,72 -> 507,71 -> 507,72 -> 509,72 -> 509,70 -> 509,72 -> 511,72 -> 511,69 -> 511,72
|
|
||||||
526,133 -> 526,131 -> 526,133 -> 528,133 -> 528,129 -> 528,133 -> 530,133 -> 530,129 -> 530,133
|
|
||||||
523,100 -> 523,104 -> 519,104 -> 519,111 -> 528,111 -> 528,104 -> 526,104 -> 526,100
|
|
||||||
545,155 -> 545,157 -> 541,157 -> 541,160 -> 556,160 -> 556,157 -> 550,157 -> 550,155
|
|
||||||
516,28 -> 521,28
|
|
||||||
545,155 -> 545,157 -> 541,157 -> 541,160 -> 556,160 -> 556,157 -> 550,157 -> 550,155
|
|
||||||
497,72 -> 497,63 -> 497,72 -> 499,72 -> 499,65 -> 499,72 -> 501,72 -> 501,71 -> 501,72 -> 503,72 -> 503,67 -> 503,72 -> 505,72 -> 505,63 -> 505,72 -> 507,72 -> 507,71 -> 507,72 -> 509,72 -> 509,70 -> 509,72 -> 511,72 -> 511,69 -> 511,72
|
|
||||||
497,72 -> 497,63 -> 497,72 -> 499,72 -> 499,65 -> 499,72 -> 501,72 -> 501,71 -> 501,72 -> 503,72 -> 503,67 -> 503,72 -> 505,72 -> 505,63 -> 505,72 -> 507,72 -> 507,71 -> 507,72 -> 509,72 -> 509,70 -> 509,72 -> 511,72 -> 511,69 -> 511,72
|
|
||||||
488,59 -> 488,51 -> 488,59 -> 490,59 -> 490,52 -> 490,59 -> 492,59 -> 492,55 -> 492,59 -> 494,59 -> 494,52 -> 494,59 -> 496,59 -> 496,50 -> 496,59 -> 498,59 -> 498,58 -> 498,59 -> 500,59 -> 500,56 -> 500,59 -> 502,59 -> 502,56 -> 502,59 -> 504,59 -> 504,57 -> 504,59
|
|
||||||
491,17 -> 496,17
|
|
||||||
488,59 -> 488,51 -> 488,59 -> 490,59 -> 490,52 -> 490,59 -> 492,59 -> 492,55 -> 492,59 -> 494,59 -> 494,52 -> 494,59 -> 496,59 -> 496,50 -> 496,59 -> 498,59 -> 498,58 -> 498,59 -> 500,59 -> 500,56 -> 500,59 -> 502,59 -> 502,56 -> 502,59 -> 504,59 -> 504,57 -> 504,59
|
|
||||||
526,133 -> 526,131 -> 526,133 -> 528,133 -> 528,129 -> 528,133 -> 530,133 -> 530,129 -> 530,133
|
|
||||||
497,72 -> 497,63 -> 497,72 -> 499,72 -> 499,65 -> 499,72 -> 501,72 -> 501,71 -> 501,72 -> 503,72 -> 503,67 -> 503,72 -> 505,72 -> 505,63 -> 505,72 -> 507,72 -> 507,71 -> 507,72 -> 509,72 -> 509,70 -> 509,72 -> 511,72 -> 511,69 -> 511,72
|
|
||||||
497,72 -> 497,63 -> 497,72 -> 499,72 -> 499,65 -> 499,72 -> 501,72 -> 501,71 -> 501,72 -> 503,72 -> 503,67 -> 503,72 -> 505,72 -> 505,63 -> 505,72 -> 507,72 -> 507,71 -> 507,72 -> 509,72 -> 509,70 -> 509,72 -> 511,72 -> 511,69 -> 511,72
|
|
||||||
523,100 -> 523,104 -> 519,104 -> 519,111 -> 528,111 -> 528,104 -> 526,104 -> 526,100
|
|
||||||
513,113 -> 513,114 -> 527,114
|
|
||||||
488,59 -> 488,51 -> 488,59 -> 490,59 -> 490,52 -> 490,59 -> 492,59 -> 492,55 -> 492,59 -> 494,59 -> 494,52 -> 494,59 -> 496,59 -> 496,50 -> 496,59 -> 498,59 -> 498,58 -> 498,59 -> 500,59 -> 500,56 -> 500,59 -> 502,59 -> 502,56 -> 502,59 -> 504,59 -> 504,57 -> 504,59
|
|
||||||
510,75 -> 510,78 -> 505,78 -> 505,84 -> 518,84 -> 518,78 -> 515,78 -> 515,75
|
|
||||||
488,59 -> 488,51 -> 488,59 -> 490,59 -> 490,52 -> 490,59 -> 492,59 -> 492,55 -> 492,59 -> 494,59 -> 494,52 -> 494,59 -> 496,59 -> 496,50 -> 496,59 -> 498,59 -> 498,58 -> 498,59 -> 500,59 -> 500,56 -> 500,59 -> 502,59 -> 502,56 -> 502,59 -> 504,59 -> 504,57 -> 504,59
|
|
||||||
541,152 -> 546,152
|
|
||||||
523,136 -> 523,138 -> 518,138 -> 518,145 -> 535,145 -> 535,138 -> 528,138 -> 528,136
|
|
|
@ -1,385 +0,0 @@
|
||||||
;; https://adventofcode.com/2022/day/14
|
|
||||||
|
|
||||||
;; so, 2d space vertical and left-right. point from which sand falls down and lines (likely horizontal || vertical) that collide with falling sand
|
|
||||||
;; gathering input. i've only thought of doing initialization in two sweeps.
|
|
||||||
;;
|
|
||||||
;; one to get "leftmost" and "rightmost", top & bottom coords.
|
|
||||||
;; so that i'm putting it all into one class that has accessors that translate it to
|
|
||||||
;; ordinary 2d array
|
|
||||||
;;
|
|
||||||
;; sand is pouring from (500, 0) - (column, row) - from
|
|
||||||
;; columns : left -> right
|
|
||||||
;; rows : top to bottom
|
|
||||||
;; top is already 0
|
|
||||||
;;
|
|
||||||
;; chars: #\. - empty space
|
|
||||||
;; #\# - stone
|
|
||||||
;; #\o - falling sand ; will not be actually stored I suppose
|
|
||||||
;; #\x - resting sand
|
|
||||||
|
|
||||||
(defclass arena ()
|
|
||||||
((grid :initarg :grid :initform (error "supply value for :grid"))
|
|
||||||
(leftmost :initarg :left :accessor leftmost)
|
|
||||||
(bottommost :initarg :bottom :accessor bottommost)
|
|
||||||
(rightmost :initarg :right :accessor rightmost)))
|
|
||||||
|
|
||||||
(defun make-arena (left right bottom)
|
|
||||||
(let ((cols-num (1+ (- right left)))
|
|
||||||
(rows-num (1+ bottom)))
|
|
||||||
(make-instance 'arena :left left :right right :bottom bottom
|
|
||||||
:grid (make-array (list rows-num cols-num)
|
|
||||||
:initial-element #\.))))
|
|
||||||
|
|
||||||
(make-array '(2 5) :initial-element "hello")
|
|
||||||
;; now. translation for coordinates, and in a way that would allow writing into place?
|
|
||||||
|
|
||||||
;; can i just defmethod getf for nonexistent place?
|
|
||||||
|
|
||||||
(defparameter *test-arena* (make-arena 100 110 7))
|
|
||||||
(setf (aref (slot-value *test-arena* 'grid) 0 4) #\*)
|
|
||||||
|
|
||||||
;; or just do through macros? nah, try functions first, it's just i liked idea of aref
|
|
||||||
;; (x y) -> (row col) in grid
|
|
||||||
(defun translate-coords (arena x y)
|
|
||||||
(list y (- x (leftmost arena))))
|
|
||||||
|
|
||||||
(destructuring-bind (rrow ccol) (translate-coords *test-arena* 104 2)
|
|
||||||
(list rrow ccol))
|
|
||||||
|
|
||||||
(defun get-place (arena x y)
|
|
||||||
(destructuring-bind (row col) (translate-coords arena x y)
|
|
||||||
(aref (slot-value arena 'grid) row col)))
|
|
||||||
|
|
||||||
(get-place *test-arena* 104 0)
|
|
||||||
|
|
||||||
(defun set-place (arena x y value)
|
|
||||||
(destructuring-bind (row col) (translate-coords arena x y)
|
|
||||||
(setf (aref (slot-value arena 'grid) row col) value)))
|
|
||||||
|
|
||||||
(set-place *test-arena* 104 1 #\&)
|
|
||||||
(slot-value *test-arena* 'grid)
|
|
||||||
|
|
||||||
;; ok. now funciton that would add lines from input?
|
|
||||||
(ql:quickload 'cl-ppcre)
|
|
||||||
(defun input-line-to-rock-coords (line)
|
|
||||||
(mapcar (lambda (coords) (mapcar #'parse-integer (cl-ppcre:split "," coords)))
|
|
||||||
(cl-ppcre:split " -> " line)))
|
|
||||||
|
|
||||||
(input-line-to-rock-coords " 503,4 -> 502,4 -> 502,9 -> 494,9 ")
|
|
||||||
|
|
||||||
;; now. i want to do first pass and find leftmost, rightmost and bottommost
|
|
||||||
|
|
||||||
(defparameter *day14-input-file* "day14-test.txt")
|
|
||||||
|
|
||||||
(mapcar #'input-line-to-rock-coords (uiop:read-file-lines *day14-input-file*))
|
|
||||||
;; now find flatten list in Alexandria
|
|
||||||
|
|
||||||
(ql:quickload 'alexandria)
|
|
||||||
(defparameter *test-input-flat-coords*
|
|
||||||
(alexandria:flatten (mapcar #'input-line-to-rock-coords (uiop:read-file-lines *day14-input-file*))))
|
|
||||||
;; well, it fully flattens it by default. maybe there it's configurable?
|
|
||||||
;; using destructuring of pairs would be better
|
|
||||||
(loop
|
|
||||||
for (x y) on *test-input-flat-coords*
|
|
||||||
by #'cddr
|
|
||||||
do (format t "x:~a y:~a~%" x y))
|
|
||||||
|
|
||||||
(loop
|
|
||||||
for (x y) on *test-input-flat-coords*
|
|
||||||
by #'cddr
|
|
||||||
minimize x
|
|
||||||
do (print x))
|
|
||||||
|
|
||||||
(loop
|
|
||||||
for (x y) on *test-input-flat-coords*
|
|
||||||
by #'cddr
|
|
||||||
minimize y
|
|
||||||
do (print y))
|
|
||||||
|
|
||||||
(loop
|
|
||||||
for (x y) on *test-input-flat-coords*
|
|
||||||
by #'cddr
|
|
||||||
collect x into x-es
|
|
||||||
collect y into y-es
|
|
||||||
finally (return (list (apply #'min x-es) (apply #'min y-es))))
|
|
||||||
;; this : I was forgetting :by #'cddr
|
|
||||||
|
|
||||||
;; here's limits
|
|
||||||
(let ((flat-coords
|
|
||||||
(alexandria:flatten (mapcar #'input-line-to-rock-coords (uiop:read-file-lines *day14-input-file*))
|
|
||||||
)))
|
|
||||||
(loop
|
|
||||||
for (x y) on flat-coords
|
|
||||||
by #'cddr
|
|
||||||
minimize x into leftmost
|
|
||||||
maximize x into rightmost
|
|
||||||
maximize y into bottommost
|
|
||||||
finally (return (list leftmost rightmost bottommost))))
|
|
||||||
|
|
||||||
;; next - build arena
|
|
||||||
|
|
||||||
;; building empty arena
|
|
||||||
(setq *test-arena*
|
|
||||||
(let ((flat-coords
|
|
||||||
(alexandria:flatten (mapcar #'input-line-to-rock-coords (uiop:read-file-lines *day14-input-file*)))))
|
|
||||||
(destructuring-bind (leftmost rightmost bottommost)
|
|
||||||
(loop
|
|
||||||
for (x y) on flat-coords
|
|
||||||
by #'cddr
|
|
||||||
minimize x into leftmost
|
|
||||||
maximize x into rightmost
|
|
||||||
maximize y into bottommost
|
|
||||||
finally (return (list leftmost rightmost bottommost)))
|
|
||||||
(make-arena leftmost rightmost bottommost))))
|
|
||||||
|
|
||||||
(slot-value *test-arena* 'grid)
|
|
||||||
|
|
||||||
;; now adding rock lines from coord list
|
|
||||||
'(((498 4) (498 6) (496 6)) ((503 4) (502 4) (502 9) (494 9)))
|
|
||||||
;; and one line is
|
|
||||||
(defparameter *test-rock-line-coords* '((498 4) (498 6) (496 6)))
|
|
||||||
|
|
||||||
(loop
|
|
||||||
for (x y) in *test-rock-line-coords*
|
|
||||||
do (format t "x:~a y:~a~%" x y))
|
|
||||||
;; can i take two at a time?
|
|
||||||
;; well, maybe use DO
|
|
||||||
(do* ((coords-list *test-rock-line-coords* (cdr coords-list))
|
|
||||||
(first-coords (first *test-rock-line-coords*) (first coords-list))
|
|
||||||
(second-coords (second *test-rock-line-coords*) (second coords-list)))
|
|
||||||
((not second-coords) "end")
|
|
||||||
(format t "~a -> ~a, in ~a~%" first-coords second-coords coords-list))
|
|
||||||
|
|
||||||
;; yup.
|
|
||||||
;; now in this DO i have "start point" -> "end point"
|
|
||||||
;; let's do separate function that
|
|
||||||
|
|
||||||
(let ((start-x 10)
|
|
||||||
(start-y 1)
|
|
||||||
(end-x 25)
|
|
||||||
(end-y 1))
|
|
||||||
(loop for x from start-x to end-x do
|
|
||||||
(loop for y from start-y to end-y do
|
|
||||||
(format t "(~a, ~a), " x y)))
|
|
||||||
(terpri))
|
|
||||||
|
|
||||||
(let ((start-x 100)
|
|
||||||
(start-y 2)
|
|
||||||
(end-x 100)
|
|
||||||
(end-y 11))
|
|
||||||
(loop for x from start-x to end-x do
|
|
||||||
(loop for y from start-y to end-y do
|
|
||||||
(format t "(~a, ~a), " x y)))
|
|
||||||
(terpri))
|
|
||||||
|
|
||||||
;; that works
|
|
||||||
|
|
||||||
(defun put-rock-line (arena start-x end-x start-y end-y)
|
|
||||||
(loop for x from start-x to end-x do
|
|
||||||
(progn
|
|
||||||
(loop for y from start-y to end-y
|
|
||||||
do (set-place arena x y #\#)))))
|
|
||||||
;; yas.
|
|
||||||
;; now do this for each pair of coords
|
|
||||||
|
|
||||||
(put-rock-line *test-arena* 101 109 1 1)
|
|
||||||
|
|
||||||
|
|
||||||
(setq *test-arena* (make-arena 100 110 7))
|
|
||||||
(slot-value *test-arena* 'grid)
|
|
||||||
|
|
||||||
(get-place *test-arena* 101 1)
|
|
||||||
|
|
||||||
(put-rock-line *test-arena* 101 109 1 1)
|
|
||||||
(set-place *test-arena* 101 1 #\#)
|
|
||||||
(set-place *test-arena* 102 1 #\#)
|
|
||||||
|
|
||||||
;; copy over previous per-2-coords-loop:
|
|
||||||
(loop
|
|
||||||
for (x y) in *test-rock-line-coords*
|
|
||||||
do (format t "x:~a y:~a~%" x y))
|
|
||||||
;; can i take two at a time?
|
|
||||||
;; well, maybe use DO
|
|
||||||
(do* ((coords-list *test-rock-line-coords* (cdr coords-list))
|
|
||||||
(first-coords (first *test-rock-line-coords*) (first coords-list))
|
|
||||||
(second-coords (second *test-rock-line-coords*) (second coords-list)))
|
|
||||||
((not second-coords) "end")
|
|
||||||
(destructuring-bind ((start-x start-y) (end-x end-y))
|
|
||||||
(list first-coords second-coords)
|
|
||||||
(put-rock-line *test-arena* start-x end-x start-y end-y) ))
|
|
||||||
;; yes
|
|
||||||
|
|
||||||
(array-dimension (make-array '(3 10)) 1)
|
|
||||||
|
|
||||||
(get-place *test-arena* 101 3)
|
|
||||||
(get-place *test-arena* 0 0)
|
|
||||||
|
|
||||||
(slot-value *test-arena* 'grid)
|
|
||||||
;; oh, it doesn't work when numbers are in wrong order.
|
|
||||||
;; ugh the LOOP for i from 9 to 3
|
|
||||||
;; how do i deal with that?
|
|
||||||
|
|
||||||
(defun put-rock-line (arena start-x end-x start-y end-y)
|
|
||||||
(let ((start-x (min start-x end-x))
|
|
||||||
(end-x (max start-x end-x))
|
|
||||||
(start-y (min start-y end-y))
|
|
||||||
(end-y (max start-y end-y)))
|
|
||||||
(loop for x from start-x to end-x do
|
|
||||||
(progn
|
|
||||||
(loop for y from start-y to end-y
|
|
||||||
do (set-place arena x y #\#))))))
|
|
||||||
|
|
||||||
(defun put-rock-chain (arena rock-coods-chain)
|
|
||||||
(do* ((coords-list rock-coods-chain (cdr coords-list))
|
|
||||||
(first-coords (first rock-coods-chain) (first coords-list))
|
|
||||||
(second-coords (second rock-coods-chain) (second coords-list)))
|
|
||||||
((not second-coords) "end")
|
|
||||||
(destructuring-bind ((start-x start-y) (end-x end-y))
|
|
||||||
(list first-coords second-coords)
|
|
||||||
(put-rock-line arena start-x end-x start-y end-y) )))
|
|
||||||
|
|
||||||
(defun put-rock-lines (arena rock-coords-lines)
|
|
||||||
(loop
|
|
||||||
for rock-coord-line in rock-coords-lines
|
|
||||||
do (put-rock-chain arena rock-coord-line)))
|
|
||||||
|
|
||||||
(defparameter *test-input-coords-chains* nil)
|
|
||||||
(setq *test-input-coords-chains*
|
|
||||||
(mapcar #'input-line-to-rock-coords
|
|
||||||
(uiop:read-file-lines *day14-input-file*)))
|
|
||||||
|
|
||||||
|
|
||||||
(slot-value *test-arena* 'grid)
|
|
||||||
|
|
||||||
(put-rock-lines *test-arena* *test-input-coords-chains*)
|
|
||||||
|
|
||||||
;; i think this works.
|
|
||||||
;; seems to be the complete initialization
|
|
||||||
|
|
||||||
;; now for the sand simulation part.
|
|
||||||
;; again, envision this as lots of loops
|
|
||||||
|
|
||||||
;; inner loop - one new sand
|
|
||||||
;; created at (500, 0), starts dropping
|
|
||||||
;; either until out-of-bounds
|
|
||||||
;; or settled by checks of lower-part
|
|
||||||
|
|
||||||
|
|
||||||
;; out-of-bounds is air
|
|
||||||
;; and . char is air
|
|
||||||
(defun is-point-air (x y arena)
|
|
||||||
(or (eq #\. (get-place arena x y))
|
|
||||||
(not (get-place arena x y))))
|
|
||||||
(is-point-air 498 4 *test-arena*)
|
|
||||||
(is-point-air 498 3 *test-arena*)
|
|
||||||
(is-point-air 500 0 *test-arena*)
|
|
||||||
(is-point-air 502 3 *test-arena*)
|
|
||||||
(is-point-air 502 4 *test-arena*)
|
|
||||||
|
|
||||||
(defun sand-check-next-move (sand-x sand-y arena)
|
|
||||||
(let* ((next-y (1+ sand-y))
|
|
||||||
(possible-next-steps (list (list sand-x next-y)
|
|
||||||
(list (1- sand-x) next-y)
|
|
||||||
(list (1+ sand-x) next-y))))
|
|
||||||
(first (remove-if-not (lambda (coords)
|
|
||||||
(is-point-air (first coords) (second coords) arena))
|
|
||||||
possible-next-steps))))
|
|
||||||
;; let's return next step or nil if it rests
|
|
||||||
|
|
||||||
(sand-check-next-move 502 3 *test-arena*)
|
|
||||||
(get-place *test-arena* 501 4)
|
|
||||||
(get-place *test-arena* 503 4)
|
|
||||||
|
|
||||||
(sand-check-next-move 500 7 *test-arena*)
|
|
||||||
(sand-check-next-move 500 8 *test-arena*)
|
|
||||||
(get-place *test-arena* 501 4)
|
|
||||||
(get-place *test-arena* 503 4)
|
|
||||||
|
|
||||||
(aref (slot-value *test-arena* 'grid) 0)
|
|
||||||
(array-storage-vector (slot-value *test-arena* 'grid))
|
|
||||||
|
|
||||||
(defun out-of-bounds (x y arena)
|
|
||||||
(not (get-place arena x y)))
|
|
||||||
|
|
||||||
;; well, this seems to work
|
|
||||||
;; now the one grain loop
|
|
||||||
(let ((arena *test-arena*))
|
|
||||||
(do*
|
|
||||||
((prev-coords nil sand-coords)
|
|
||||||
(sand-coords '(500 0) (sand-check-next-move
|
|
||||||
(first sand-coords) (second sand-coords) arena)))
|
|
||||||
((or (not sand-coords) ; sand rests
|
|
||||||
(out-of-bounds (first sand-coords) (second sand-coords) arena)) ; end condition - rest or out of bounds
|
|
||||||
(when (not sand-coords)
|
|
||||||
(set-place arena (first prev-coords) (second prev-coords) #\x)))
|
|
||||||
(format t "sc: ~a, prev: ~a~%" sand-coords prev-coords)))
|
|
||||||
|
|
||||||
(init-arena)
|
|
||||||
(slot-value *test-arena* 'grid)
|
|
||||||
(not (get-place *test-arena* 500 0 ))
|
|
||||||
(set-place *test-arena* 500 0 #\x)
|
|
||||||
|
|
||||||
(defun drop-sand-unit (arena)
|
|
||||||
(do*
|
|
||||||
((prev-coords nil sand-coords)
|
|
||||||
(sand-coords '(500 0) (sand-check-next-move
|
|
||||||
(first sand-coords) (second sand-coords) arena)))
|
|
||||||
((or (not sand-coords) ; sand rests
|
|
||||||
(out-of-bounds (first sand-coords) (second sand-coords) arena)) ; end condition - rest or out of bounds
|
|
||||||
(when (not sand-coords)
|
|
||||||
(set-place arena (first prev-coords) (second prev-coords) #\x)))
|
|
||||||
(format t "sc: ~a, prev: ~a~%" sand-coords prev-coords)))
|
|
||||||
|
|
||||||
|
|
||||||
;; ok, i got inner loop
|
|
||||||
;; now what? run that loop until the grain of sand ends up our of bounds
|
|
||||||
;; what are we calculating?
|
|
||||||
|
|
||||||
;; "how many units of sand come to rest until they start falling into abyss"
|
|
||||||
;; so. do ?
|
|
||||||
(let ((arena *test-arena*))
|
|
||||||
(do ((sand-units 0 (1+ sand-units))
|
|
||||||
(drop-result (drop-sand-unit arena) (drop-sand-unit arena)))
|
|
||||||
((not drop-result)
|
|
||||||
sand-units)))
|
|
||||||
|
|
||||||
(slot-value *test-arena* 'grid)
|
|
||||||
|
|
||||||
(defun drop-sand-unit-abyss (arena)
|
|
||||||
(do ((sand-units 0 (1+ sand-units))
|
|
||||||
(drop-result (drop-sand-unit arena) (drop-sand-unit arena)))
|
|
||||||
((not drop-result)
|
|
||||||
sand-units)))
|
|
||||||
|
|
||||||
;;; PART 2
|
|
||||||
;; let's not do floor infinite.
|
|
||||||
;; let's just give it enough left-to-right?
|
|
||||||
;; since the triangle is 2 right angle triangles, then bottom is 2x height
|
|
||||||
;; so, let's add 4x height of the floor?
|
|
||||||
;;
|
|
||||||
;; new bottommost =
|
|
||||||
(+ 2 bottommost)
|
|
||||||
;; new leftmost =
|
|
||||||
(min leftmost
|
|
||||||
(- 500 (* 2 bottommost)))
|
|
||||||
;; new rightmost =
|
|
||||||
(max rightmost
|
|
||||||
(+ 500 (* 2 bottommost)))
|
|
||||||
|
|
||||||
;; and add new rock-line?
|
|
||||||
;; just through function that adds a rockline
|
|
||||||
|
|
||||||
(slot-value *test-arena* 'grid)
|
|
||||||
|
|
||||||
;; and now i'd like a more compact printing.
|
|
||||||
;; how'd i do that?
|
|
||||||
;; surely there's a way to get access ot a slice of the 2d array?
|
|
||||||
|
|
||||||
(let* ((arena *test-arena*)
|
|
||||||
(array (slot-value arena 'grid)))
|
|
||||||
(dotimes (row (array-dimension array 0))
|
|
||||||
(dotimes (col (array-dimension array 1))
|
|
||||||
(format t "~a" (aref array row col)))
|
|
||||||
(terpri)))
|
|
||||||
|
|
||||||
(drop-sand-unit *test-arena*)
|
|
|
@ -1,2 +0,0 @@
|
||||||
498,4 -> 498,6 -> 496,6
|
|
||||||
503,4 -> 502,4 -> 502,9 -> 494,9
|
|
198
day14.lisp
198
day14.lisp
|
@ -1,198 +0,0 @@
|
||||||
;; https://adventofcode.com/2022/day/14
|
|
||||||
(ql:quickload 'cl-ppcre)
|
|
||||||
(ql:quickload 'alexandria)
|
|
||||||
|
|
||||||
;; (defparameter *day14-input-file* "day14-test.txt")
|
|
||||||
(defparameter *day14-input-file* "day14-input.txt")
|
|
||||||
|
|
||||||
(defclass arena ()
|
|
||||||
((grid :initarg :grid :initform (error "supply value for :grid"))
|
|
||||||
(leftmost :initarg :left :accessor leftmost)
|
|
||||||
(bottommost :initarg :bottom :accessor bottommost)
|
|
||||||
(rightmost :initarg :right :accessor rightmost)))
|
|
||||||
|
|
||||||
(defun make-arena (left right bottom)
|
|
||||||
(let ((cols-num (1+ (- right left)))
|
|
||||||
(rows-num (1+ bottom)))
|
|
||||||
(make-instance 'arena :left left :right right :bottom bottom
|
|
||||||
:grid (make-array (list rows-num cols-num)
|
|
||||||
:initial-element #\.))))
|
|
||||||
|
|
||||||
(defparameter *test-arena* nil)
|
|
||||||
|
|
||||||
|
|
||||||
;; (x y) -> (row col) in grid
|
|
||||||
(defun translate-coords (arena x y)
|
|
||||||
(list y (- x (leftmost arena))))
|
|
||||||
|
|
||||||
(defun get-place (arena x y)
|
|
||||||
(destructuring-bind (row col) (translate-coords arena x y)
|
|
||||||
(when (and (<= 0 row) (<= 0 col)
|
|
||||||
(< row (array-dimension (slot-value arena 'grid) 0))
|
|
||||||
(< col (array-dimension (slot-value arena 'grid) 1))
|
|
||||||
)
|
|
||||||
(aref (slot-value arena 'grid) row col))))
|
|
||||||
|
|
||||||
(defun set-place (arena x y value)
|
|
||||||
(destructuring-bind (row col) (translate-coords arena x y)
|
|
||||||
(when (and (<= 0 row) (<= 0 col)
|
|
||||||
(< row (array-dimension (slot-value arena 'grid) 0))
|
|
||||||
(< col (array-dimension (slot-value arena 'grid) 1))
|
|
||||||
)
|
|
||||||
(setf (aref (slot-value arena 'grid) row col) value))))
|
|
||||||
|
|
||||||
(defun input-line-to-rock-coords (line)
|
|
||||||
(mapcar (lambda (coords) (mapcar #'parse-integer (cl-ppcre:split "," coords)))
|
|
||||||
(cl-ppcre:split " -> " line)))
|
|
||||||
|
|
||||||
(defparameter *test-input-flat-coords* nil)
|
|
||||||
|
|
||||||
|
|
||||||
(defun put-rock-line (arena start-x end-x start-y end-y)
|
|
||||||
(let ((start-x (min start-x end-x))
|
|
||||||
(end-x (max start-x end-x))
|
|
||||||
(start-y (min start-y end-y))
|
|
||||||
(end-y (max start-y end-y)))
|
|
||||||
(loop for x from start-x to end-x do
|
|
||||||
(progn
|
|
||||||
(loop for y from start-y to end-y
|
|
||||||
do (set-place arena x y #\#))))))
|
|
||||||
|
|
||||||
(defun put-rock-lines (arena rock-coords-lines)
|
|
||||||
(loop
|
|
||||||
for rock-coord-line in rock-coords-lines
|
|
||||||
do (put-rock-chain arena rock-coord-line)))
|
|
||||||
|
|
||||||
|
|
||||||
(defparameter *test-input-coords-chains* nil)
|
|
||||||
|
|
||||||
(defun put-rock-chain (arena rock-coods-chain)
|
|
||||||
(do* ((coords-list rock-coods-chain (cdr coords-list))
|
|
||||||
(first-coords (first rock-coods-chain) (first coords-list))
|
|
||||||
(second-coords (second rock-coods-chain) (second coords-list)))
|
|
||||||
((not second-coords) "end")
|
|
||||||
(destructuring-bind ((start-x start-y) (end-x end-y))
|
|
||||||
(list first-coords second-coords)
|
|
||||||
(put-rock-line arena start-x end-x start-y end-y) )))
|
|
||||||
|
|
||||||
;; reinit things
|
|
||||||
;; (init-arena)
|
|
||||||
(defun init-arena ()
|
|
||||||
|
|
||||||
(setq *test-input-flat-coords*
|
|
||||||
(alexandria:flatten (mapcar #'input-line-to-rock-coords
|
|
||||||
(uiop:read-file-lines *day14-input-file*))))
|
|
||||||
;; building empty arena
|
|
||||||
(setq *test-arena*
|
|
||||||
(let ((flat-coords
|
|
||||||
(alexandria:flatten (mapcar #'input-line-to-rock-coords (uiop:read-file-lines *day14-input-file*)))))
|
|
||||||
(destructuring-bind (leftmost rightmost bottommost)
|
|
||||||
(loop
|
|
||||||
for (x y) on flat-coords
|
|
||||||
by #'cddr
|
|
||||||
minimize x into leftmost
|
|
||||||
maximize x into rightmost
|
|
||||||
maximize y into bottommost
|
|
||||||
finally (return (list leftmost rightmost bottommost)))
|
|
||||||
(make-arena leftmost rightmost bottommost))))
|
|
||||||
|
|
||||||
(setq *test-input-coords-chains*
|
|
||||||
(mapcar #'input-line-to-rock-coords
|
|
||||||
(uiop:read-file-lines *day14-input-file*)))
|
|
||||||
|
|
||||||
; this is second step of initialization
|
|
||||||
(put-rock-lines *test-arena* *test-input-coords-chains*))
|
|
||||||
|
|
||||||
(defun is-point-air (x y arena)
|
|
||||||
(or (eq #\. (get-place arena x y))
|
|
||||||
(not (get-place arena x y))))
|
|
||||||
(defun sand-check-next-move (sand-x sand-y arena)
|
|
||||||
(let* ((next-y (1+ sand-y))
|
|
||||||
(possible-next-steps (list (list sand-x next-y)
|
|
||||||
(list (1- sand-x) next-y)
|
|
||||||
(list (1+ sand-x) next-y))))
|
|
||||||
(first (remove-if-not (lambda (coords)
|
|
||||||
(is-point-air (first coords) (second coords) arena))
|
|
||||||
possible-next-steps))))
|
|
||||||
(defun out-of-bounds (x y arena)
|
|
||||||
(not (get-place arena x y)))
|
|
||||||
|
|
||||||
|
|
||||||
(defun drop-sand-unit (arena)
|
|
||||||
(do*
|
|
||||||
((prev-coords nil sand-coords)
|
|
||||||
(sand-coords '(500 0) (sand-check-next-move
|
|
||||||
(first sand-coords) (second sand-coords) arena)))
|
|
||||||
((or (not sand-coords) ; sand rests
|
|
||||||
(out-of-bounds (first sand-coords) (second sand-coords) arena)) ; end condition - rest or out of bounds
|
|
||||||
(when (or (not sand-coords)
|
|
||||||
(equal prev-coords '(500 0))) ; if sand rests at entry point
|
|
||||||
(set-place arena (first prev-coords) (second prev-coords) #\x)))
|
|
||||||
;; (format t "sc: ~a, prev: ~a~%" sand-coords prev-coords)
|
|
||||||
))
|
|
||||||
|
|
||||||
(defun drop-sand-unit-abyss (arena)
|
|
||||||
(do ((sand-units 0 (1+ sand-units))
|
|
||||||
(drop-result (drop-sand-unit arena) (drop-sand-unit arena)))
|
|
||||||
((not drop-result)
|
|
||||||
sand-units)))
|
|
||||||
|
|
||||||
;; ok, could return arena
|
|
||||||
(init-arena)
|
|
||||||
(drop-sand-unit-abyss *test-arena*) ; 901
|
|
||||||
|
|
||||||
;;; PART 2
|
|
||||||
|
|
||||||
(defun init-arena-2 ()
|
|
||||||
|
|
||||||
(setq *test-input-flat-coords*
|
|
||||||
(alexandria:flatten (mapcar #'input-line-to-rock-coords
|
|
||||||
(uiop:read-file-lines *day14-input-file*))))
|
|
||||||
;; building empty arena
|
|
||||||
(setq *test-arena*
|
|
||||||
(let ((flat-coords
|
|
||||||
(alexandria:flatten (mapcar #'input-line-to-rock-coords (uiop:read-file-lines *day14-input-file*)))))
|
|
||||||
(destructuring-bind (leftmost rightmost bottommost)
|
|
||||||
(loop
|
|
||||||
for (x y) on flat-coords
|
|
||||||
by #'cddr
|
|
||||||
minimize x into leftmost
|
|
||||||
maximize x into rightmost
|
|
||||||
maximize y into bottommost
|
|
||||||
finally (return (list leftmost rightmost bottommost)))
|
|
||||||
(let ((new-bottommost (+ 2 bottommost))
|
|
||||||
(new-leftmost (min leftmost
|
|
||||||
(- 500 (* 2 bottommost))))
|
|
||||||
(new-rightmost (max rightmost
|
|
||||||
(+ 500 (* 2 bottommost)))))
|
|
||||||
(make-arena new-leftmost new-rightmost new-bottommost)))))
|
|
||||||
;; and put floor
|
|
||||||
(let ((floor-y (bottommost *test-arena*))
|
|
||||||
(floor-x-start (leftmost *test-arena*))
|
|
||||||
(floor-x-end (rightmost *test-arena*)))
|
|
||||||
(put-rock-line *test-arena* floor-x-start floor-x-end floor-y floor-y))
|
|
||||||
|
|
||||||
(setq *test-input-coords-chains*
|
|
||||||
(mapcar #'input-line-to-rock-coords
|
|
||||||
(uiop:read-file-lines *day14-input-file*)))
|
|
||||||
|
|
||||||
; this is second step of initialization
|
|
||||||
(put-rock-lines *test-arena* *test-input-coords-chains*))
|
|
||||||
|
|
||||||
;; rewriting previous. otherwise endless loop
|
|
||||||
(defun drop-sand-unit (arena)
|
|
||||||
(do*
|
|
||||||
((prev-coords '(500 0) sand-coords)
|
|
||||||
(sand-coords (sand-check-next-move 500 0 arena)
|
|
||||||
(sand-check-next-move
|
|
||||||
(first sand-coords) (second sand-coords) arena)))
|
|
||||||
((or (not sand-coords) ; sand rests
|
|
||||||
(out-of-bounds (first sand-coords) (second sand-coords) arena)) ; end condition - rest or out of bounds
|
|
||||||
(when (and (not sand-coords)
|
|
||||||
(not (equal prev-coords '(500 0)))) ; if sand rests
|
|
||||||
(set-place arena (first prev-coords) (second prev-coords) #\x)))
|
|
||||||
;; (format t "sc: ~a, prev: ~a~%" sand-coords prev-coords)
|
|
||||||
))
|
|
||||||
|
|
||||||
(init-arena-2)
|
|
||||||
(print (1+ (drop-sand-unit-abyss *test-arena*)))
|
|
|
@ -1,33 +0,0 @@
|
||||||
Sensor at x=2302110, y=2237242: closest beacon is at x=2348729, y=1239977
|
|
||||||
Sensor at x=47903, y=2473047: closest beacon is at x=-432198, y=2000000
|
|
||||||
Sensor at x=2363579, y=1547888: closest beacon is at x=2348729, y=1239977
|
|
||||||
Sensor at x=3619841, y=520506: closest beacon is at x=2348729, y=1239977
|
|
||||||
Sensor at x=3941908, y=3526118: closest beacon is at x=3772294, y=3485243
|
|
||||||
Sensor at x=3206, y=1564595: closest beacon is at x=-432198, y=2000000
|
|
||||||
Sensor at x=3123411, y=3392077: closest beacon is at x=2977835, y=3592946
|
|
||||||
Sensor at x=3279053, y=3984688: closest beacon is at x=2977835, y=3592946
|
|
||||||
Sensor at x=2968162, y=3938490: closest beacon is at x=2977835, y=3592946
|
|
||||||
Sensor at x=1772120, y=2862246: closest beacon is at x=2017966, y=3158243
|
|
||||||
Sensor at x=3283241, y=2619168: closest beacon is at x=3172577, y=2521434
|
|
||||||
Sensor at x=2471642, y=3890150: closest beacon is at x=2977835, y=3592946
|
|
||||||
Sensor at x=3163348, y=3743489: closest beacon is at x=2977835, y=3592946
|
|
||||||
Sensor at x=2933313, y=2919047: closest beacon is at x=3172577, y=2521434
|
|
||||||
Sensor at x=2780640, y=3629927: closest beacon is at x=2977835, y=3592946
|
|
||||||
Sensor at x=3986978, y=2079918: closest beacon is at x=3998497, y=2812428
|
|
||||||
Sensor at x=315464, y=370694: closest beacon is at x=-550536, y=260566
|
|
||||||
Sensor at x=3957316, y=3968366: closest beacon is at x=3772294, y=3485243
|
|
||||||
Sensor at x=2118533, y=1074658: closest beacon is at x=2348729, y=1239977
|
|
||||||
Sensor at x=3494855, y=3378533: closest beacon is at x=3772294, y=3485243
|
|
||||||
Sensor at x=2575727, y=210553: closest beacon is at x=2348729, y=1239977
|
|
||||||
Sensor at x=3999990, y=2813525: closest beacon is at x=3998497, y=2812428
|
|
||||||
Sensor at x=3658837, y=3026912: closest beacon is at x=3998497, y=2812428
|
|
||||||
Sensor at x=1551619, y=1701155: closest beacon is at x=2348729, y=1239977
|
|
||||||
Sensor at x=2625855, y=3330422: closest beacon is at x=2977835, y=3592946
|
|
||||||
Sensor at x=3476946, y=2445098: closest beacon is at x=3172577, y=2521434
|
|
||||||
Sensor at x=2915568, y=1714113: closest beacon is at x=2348729, y=1239977
|
|
||||||
Sensor at x=729668, y=3723377: closest beacon is at x=-997494, y=3617758
|
|
||||||
Sensor at x=3631681, y=3801747: closest beacon is at x=3772294, y=3485243
|
|
||||||
Sensor at x=2270816, y=3197807: closest beacon is at x=2017966, y=3158243
|
|
||||||
Sensor at x=3999999, y=2810929: closest beacon is at x=3998497, y=2812428
|
|
||||||
Sensor at x=3978805, y=3296024: closest beacon is at x=3772294, y=3485243
|
|
||||||
Sensor at x=1054910, y=811769: closest beacon is at x=2348729, y=1239977
|
|
|
@ -1,481 +0,0 @@
|
||||||
;; https://adventofcode.com/2022/day/15
|
|
||||||
;;
|
|
||||||
;; oh, wow. i can already imagine the second part of the task
|
|
||||||
;; so. for arrangements of (sensor closest-beacon)
|
|
||||||
;; i need to figure out which points are out of rangle for all sensors?
|
|
||||||
;; where "range" is distance between sensor and the closest-beacon
|
|
||||||
;;
|
|
||||||
;; so for each sensor also store distance, and each sensor should be able to answer query for point
|
|
||||||
;; whether it disproves existence of a beacone there
|
|
||||||
;; then for ( POINTS x SENSORS ) computations i'll be able to mark all points that aren't covered.
|
|
||||||
;;
|
|
||||||
;; doesn't seem like too much
|
|
||||||
|
|
||||||
(ql:quickload 'cl-ppcre)
|
|
||||||
;; poor man's parsing
|
|
||||||
(rest (mapcar (lambda (str)
|
|
||||||
(parse-integer str :junk-allowed t))
|
|
||||||
(cl-ppcre:split "="
|
|
||||||
"Sensor at x=2, y=18: closest beacon is at x=-2, y=15")))
|
|
||||||
|
|
||||||
;; manhattan distance : https://en.wikipedia.org/wiki/Taxicab_geometry
|
|
||||||
;; sum of abs of coord-diffs
|
|
||||||
|
|
||||||
(defclass point ()
|
|
||||||
((x :initarg :x :reader x)
|
|
||||||
(y :initarg :y :reader y)))
|
|
||||||
|
|
||||||
(defmethod print-object ((obj point) stream)
|
|
||||||
(print-unreadable-object (obj stream :type t)
|
|
||||||
(with-slots (x y)
|
|
||||||
obj
|
|
||||||
(format stream "x:~a y:~a" x y))))
|
|
||||||
|
|
||||||
(defparameter *test-point-1*
|
|
||||||
(make-instance 'point :x 1 :y 19))
|
|
||||||
|
|
||||||
(defparameter *test-point-2*
|
|
||||||
(make-instance 'point :x -2 :y -20))
|
|
||||||
|
|
||||||
(defmethod manh-dist ((one point) (two point))
|
|
||||||
(+ (abs (- (x one) (x two)))
|
|
||||||
(abs (- (y one) (y two)))))
|
|
||||||
|
|
||||||
(manh-dist *test-point-1* *test-point-2*)
|
|
||||||
;; i guess this is right
|
|
||||||
|
|
||||||
(defclass sensor ()
|
|
||||||
((self-coord :initarg :self :reader self-coord)
|
|
||||||
(beacon-coord :initarg :beacon :reader beacon-coord)
|
|
||||||
(covered-dist :initarg :dist :reader covered-dist)))
|
|
||||||
|
|
||||||
(defun make-sensor (sens-x sens-y beac-x beac-y)
|
|
||||||
(let* ((sensor (make-instance 'point :x sens-x :y sens-y))
|
|
||||||
(beacon (make-instance 'point :x beac-x :y beac-y))
|
|
||||||
(dist (manh-dist sensor beacon)))
|
|
||||||
(make-instance 'sensor :self sensor :beacon beacon :dist dist)))
|
|
||||||
|
|
||||||
(defmethod print-object ((obj sensor) stream)
|
|
||||||
(print-unreadable-object (obj stream :type t)
|
|
||||||
(with-slots (self-coord beacon-coord covered-dist)
|
|
||||||
obj
|
|
||||||
(format stream "at: ~a, linked to: ~a, covering dist: ~a"
|
|
||||||
self-coord beacon-coord covered-dist))))
|
|
||||||
|
|
||||||
|
|
||||||
(defparameter *test-sensor* (make-sensor 2 18 -2 15))
|
|
||||||
|
|
||||||
(defmethod can-have-unknown-beacon-p ((p point) (s sensor))
|
|
||||||
(> (manh-dist p (self-coord s))
|
|
||||||
(covered-dist s)))
|
|
||||||
|
|
||||||
(manh-dist *test-point-1* (self-coord *test-sensor*))
|
|
||||||
(can-have-unknown-beacon-p *test-point-1* *test-sensor*)
|
|
||||||
|
|
||||||
(manh-dist *test-point-2* (self-coord *test-sensor*))
|
|
||||||
(can-have-unknown-beacon-p *test-point-2* *test-sensor*)
|
|
||||||
|
|
||||||
;; ok. now read in all sensors?
|
|
||||||
;; and then for line with specified 'y'
|
|
||||||
;; and from leftmost to rightmost S or B for each point ask each sensor if possible
|
|
||||||
;; to have an unknown beacon, if any says "no" - then no
|
|
||||||
;; otherwise - count
|
|
||||||
|
|
||||||
(defparameter *day15-input-file* "day15-test.txt")
|
|
||||||
|
|
||||||
|
|
||||||
(defun line-to-coords (line)
|
|
||||||
(rest (mapcar (lambda (str)
|
|
||||||
(parse-integer str :junk-allowed t))
|
|
||||||
(cl-ppcre:split "=" line))))
|
|
||||||
|
|
||||||
(defparameter *day15-sensors-list* nil)
|
|
||||||
(setq *day15-sensors-list*
|
|
||||||
(mapcar (lambda (coords-list)
|
|
||||||
(apply #'make-sensor coords-list))
|
|
||||||
(mapcar #'line-to-coords (uiop:read-file-lines *day15-input-file*))))
|
|
||||||
|
|
||||||
;; next - find lovest x and highest x
|
|
||||||
;; but then i guess i'd also want lovest and highest y overall
|
|
||||||
|
|
||||||
;; that's neat
|
|
||||||
(loop
|
|
||||||
for sensor in *day15-sensors-list*
|
|
||||||
minimize (x (self-coord sensor)) into xs
|
|
||||||
minimize (x (beacon-coord sensor)) into xs
|
|
||||||
maximize (x (self-coord sensor)) into xm
|
|
||||||
maximize (x (beacon-coord sensor)) into xm
|
|
||||||
minimize (y (self-coord sensor)) into ys
|
|
||||||
minimize (y (beacon-coord sensor)) into ys
|
|
||||||
maximize (y (self-coord sensor)) into ym
|
|
||||||
maximize (y (beacon-coord sensor)) into ym
|
|
||||||
finally (return (list xs xm ys ym)))
|
|
||||||
;; (-2 25 0 22)
|
|
||||||
|
|
||||||
;; now for line y=10 check all x and count how many -for-all- sensors allow new point
|
|
||||||
|
|
||||||
(defun all-sensors-allow-for-hidden-beacon (point sensors)
|
|
||||||
(macroexpand `(and ,@(mapcar (lambda (sensor) (can-have-unknown-beacon-p point sensor))
|
|
||||||
sensors))))
|
|
||||||
|
|
||||||
(defun all-sensors-allow-for-hidden-beacon (point sensors)
|
|
||||||
(not (position nil (mapcar (lambda (sensor) (can-have-unknown-beacon-p point sensor))
|
|
||||||
sensors))))
|
|
||||||
|
|
||||||
;; well, do i have to write my own function for AND ?
|
|
||||||
(when (all-sensors-allow-for-hidden-beacon *test-point-2* *day15-sensors-list*)
|
|
||||||
1)
|
|
||||||
|
|
||||||
(when (all-sensors-allow-for-hidden-beacon *test-point-1* *day15-sensors-list*)
|
|
||||||
1)
|
|
||||||
|
|
||||||
;; count how many ARE covered
|
|
||||||
(loop
|
|
||||||
for x from -2 to 25
|
|
||||||
count (not (all-sensors-allow-for-hidden-beacon
|
|
||||||
(make-instance 'point :x x :y 10)
|
|
||||||
*day15-sensors-list*)))
|
|
||||||
|
|
||||||
;; on the image it's from -2 and till 24, so should be 27, if counting 0
|
|
||||||
;; well. we're counting posistions "wher beacon can't possibly exist"
|
|
||||||
;; so removing points which _are_ beacons?
|
|
||||||
;;
|
|
||||||
;; and - range needs to be extended significantly, no?
|
|
||||||
;; what would be enough?
|
|
||||||
;; doubling into each direction?
|
|
||||||
|
|
||||||
(defmethod points-equal ((left point) (right point))
|
|
||||||
(and (= (x left) (x right))
|
|
||||||
(= (y left) (y right))))
|
|
||||||
|
|
||||||
|
|
||||||
(points-equal (make-instance 'point :x 1 :y 1)
|
|
||||||
(make-instance 'point :x 1 :y 1))
|
|
||||||
|
|
||||||
(defun possible-to-have-beacon (point sensors)
|
|
||||||
(let ((all-checks
|
|
||||||
(mapcar (lambda (sensor)
|
|
||||||
(if (points-equal point (beacon-coord sensor))
|
|
||||||
'known-sensor
|
|
||||||
(can-have-unknown-beacon-p point sensor) ; single NIL means - not possible to have unknown
|
|
||||||
))
|
|
||||||
sensors)))
|
|
||||||
(or (not (position nil all-checks)) ; nil if all sensors allow (said T) presense of unknown beacons
|
|
||||||
(position 'known-sensor all-checks) ; exists known sensor
|
|
||||||
)))
|
|
||||||
;; beacon is possible : either sensor has beacon at that point
|
|
||||||
;; or position is out of the sensor range
|
|
||||||
;; but here's the thing. if sencor-beacon is at this point - need to short-circuit T
|
|
||||||
|
|
||||||
(possible-to-have-beacon *test-point-2* *day15-sensors-list*)
|
|
||||||
|
|
||||||
(possible-to-have-beacon *test-point-1* *day15-sensors-list*)
|
|
||||||
|
|
||||||
(possible-to-have-beacon (make-instance 'point :x -2 :y 15) *day15-sensors-list*)
|
|
||||||
|
|
||||||
;; i guess that works
|
|
||||||
|
|
||||||
;; count how many ARE covered
|
|
||||||
(loop
|
|
||||||
for x from -2 to 25
|
|
||||||
count (not (possible-to-have-beacon
|
|
||||||
(make-instance 'point :x x :y 10)
|
|
||||||
*day15-sensors-list*)))
|
|
||||||
|
|
||||||
;; ok.
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; new idea:
|
|
||||||
;; have class for "not intersecting intervals"
|
|
||||||
;; with method to add ( ? remove ) new interval
|
|
||||||
|
|
||||||
;; in part 2 we're looking for points which are outside of all scanners
|
|
||||||
;; where "last beacon" can be
|
|
||||||
|
|
||||||
;; start of idea - distance goes by x and y simmetrically.
|
|
||||||
;; between line Y1 and beacon (X2 Y2) we can calculate Y2 - Y1,
|
|
||||||
;; if that is > than length covered - then knowingly 0 points covered by scanners
|
|
||||||
;; if htat is < that covered length : abs(Y2 - Y1) = diff
|
|
||||||
;; that diff will be covered into both sides to the left and to the right of the X2
|
|
||||||
;; (Y1 X2) will be exactly diff distance away.
|
|
||||||
;; so (length - diff) is by how much we can go to the left and right and still be with distance to beacon upto length
|
|
||||||
;; Interval [(x2-diff, y1) .. (x2+diff, y1)] are all points where "there can't be unkown beacons"
|
|
||||||
;;
|
|
||||||
;; and my idea is to operate on the point intervals.
|
|
||||||
;; start with "total interval" from 0 to 4M, i guess
|
|
||||||
;; then - for each beacon calculate Interval where "can't be unknown beacons"
|
|
||||||
;; and subtract them from the line
|
|
||||||
;;
|
|
||||||
;; without use of "per point" is best
|
|
||||||
;; so. want to have class, that stores non-intersecting intervals ( scala SortedMap would be good here )
|
|
||||||
;;
|
|
||||||
;; but ok, can be just ((start end) (start2 end2)) sorted by #'first after every operation
|
|
||||||
;; what would be algo for "removing interval"
|
|
||||||
;;
|
|
||||||
;; go though the increasing 'interval starts', find first that's > our-start
|
|
||||||
;; then check current interval and previous interval
|
|
||||||
;;
|
|
||||||
;; previous interval could have end that clips current-interval
|
|
||||||
;; at-which-we-stopped could clip "end" of current-interval
|
|
||||||
|
|
||||||
;; should i just have class for interval? nah, just method, since no need in type checking?
|
|
||||||
|
|
||||||
(defun subtract-interval (minuend subtrahend)
|
|
||||||
(destructuring-bind ((m-left m-right) (s-left s-right)) (list minuend subtrahend)
|
|
||||||
(let ((resulting-interval
|
|
||||||
(if (< m-left s-left)
|
|
||||||
(list ; minuend starts to the left
|
|
||||||
m-left (min m-right s-left))
|
|
||||||
(list ; minuend starts to the right
|
|
||||||
s-right m-right)
|
|
||||||
)))
|
|
||||||
(when (<= (first resulting-interval) (second resulting-interval)) ; >= to allow intervals [4 4]
|
|
||||||
resulting-interval))))
|
|
||||||
|
|
||||||
(subtract-interval '(1 100) '(0 101)) ; NIL correct
|
|
||||||
(subtract-interval '(1 100) '(10 20)) ; only one return value, incorrect
|
|
||||||
|
|
||||||
;; oh, but it can be that our subrahend fully devours "to the right" and we'd need to check "next to the right"
|
|
||||||
;; ugh
|
|
||||||
;; went to search and found 'cl-interval
|
|
||||||
|
|
||||||
(ql:quickload 'cl-interval)
|
|
||||||
(interval:make-interval :start 1 :end 100 )
|
|
||||||
;; this is not what i need?
|
|
||||||
(defparameter *some-tree*
|
|
||||||
(interval:make-tree ))
|
|
||||||
(interval:insert *some-tree* (interval:make-interval :start 1 :end 100) )
|
|
||||||
(interval:delete *some-tree* (interval:make-interval :start 10 :end 20) )
|
|
||||||
*some-tree*
|
|
||||||
(interval:find-all *some-tree* 11) ; nope deletion doesn't work like i want it
|
|
||||||
|
|
||||||
;; ugh. write it on my own
|
|
||||||
(defstruct ([] (:constructor [] (low high)))
|
|
||||||
(low 0.0 :type real)
|
|
||||||
(high 0.0 :type real))
|
|
||||||
|
|
||||||
(defmethod sub ((i1 []) (i2 []))
|
|
||||||
([] (- ([]-low i1) ([]-high i2))
|
|
||||||
(- ([]-high i1) ([]-low i2))))
|
|
||||||
|
|
||||||
(sub ([] 1 100) ([] 10 20)) ; ([] -19 90) that's bs
|
|
||||||
|
|
||||||
;;; ugh. this is somethign completely different
|
|
||||||
;; so, back to my function
|
|
||||||
;; should be able to return list of intervals. either one or two if split
|
|
||||||
(defun subtract-interval (minuend subtrahend)
|
|
||||||
(destructuring-bind ((m-left m-right) (s-left s-right)) (list minuend subtrahend)
|
|
||||||
(cond
|
|
||||||
((< m-right s-left) (list m-left m-right)) ; minuend fully to the left
|
|
||||||
((> m-left s-right) (list m-left m-right)) ; minuend fully to the right
|
|
||||||
((and (< m-left s-left)
|
|
||||||
(> m-right s-right)) ; minuend is around subtrahend
|
|
||||||
(list (list m-left (1- s-left))
|
|
||||||
(list (1+ s-right) m-right))) ; part before and after subtrahend
|
|
||||||
((and (>= m-left s-left)
|
|
||||||
(<= m-right s-right)) ; subtrahend consumes minuend
|
|
||||||
nil)
|
|
||||||
((< m-left s-left) ; minuend start to the left, but not subtrahend consumes all right part
|
|
||||||
(list m-left (1- s-left)))
|
|
||||||
((> m-right s-right) ; minuend has part to the right of subtrahend
|
|
||||||
(list (1+ s-right) m-right)))))
|
|
||||||
|
|
||||||
(subtract-interval '(1 100) '(0 101)) ; NIL correct
|
|
||||||
(subtract-interval '(1 100) '(10 20)) ; two intervals, correct
|
|
||||||
(subtract-interval '(1 20) '(10 30)) ; correct, had deducted 10
|
|
||||||
(subtract-interval '(10 30) '(1 20)) ; correct, had deducted 20
|
|
||||||
(subtract-interval '(25 30) '(1 20)) ; correct, not changed
|
|
||||||
(subtract-interval '(1 20) '(25 30)) ; correct not changed
|
|
||||||
(subtract-interval '(1 20) nil) ; correct not changed
|
|
||||||
|
|
||||||
;; ok. now what. have interval
|
|
||||||
'(0 4000000) ; and deduct from it found intervals.
|
|
||||||
; it would produce list of intervals
|
|
||||||
; so for each new interval - deduct from all
|
|
||||||
; then i'll have list of intervals, where "unknown beacon is possible"
|
|
||||||
|
|
||||||
|
|
||||||
;; now. hm.
|
|
||||||
;; loop. no. first function that for LINE-Y and BEACON-CENTER calculates "no-unkown-beacons" interval
|
|
||||||
|
|
||||||
(defun get-no-unknown-beacons-x-interval (line-y scanner)
|
|
||||||
(let* ((y-dist (abs (- line-y (y (self-coord scanner)))))
|
|
||||||
(x-slack (- (covered-dist scanner) y-dist))
|
|
||||||
(x-sc (x (self-coord scanner))))
|
|
||||||
(when (>= x-slack 0)
|
|
||||||
(list (- x-sc x-slack) (+ x-sc x-slack)))))
|
|
||||||
|
|
||||||
*test-sensor* ; x: 2, y: 18, dist: 7
|
|
||||||
(y (self-coord *test-sensor*))
|
|
||||||
|
|
||||||
(get-no-unknown-beacons-x-interval 18 *test-sensor*)
|
|
||||||
(get-no-unknown-beacons-x-interval 17 *test-sensor*)
|
|
||||||
(get-no-unknown-beacons-x-interval 19 *test-sensor*)
|
|
||||||
;; should be (-5 9)
|
|
||||||
|
|
||||||
(get-no-unknown-beacons-x-interval 11 *test-sensor*)
|
|
||||||
(manh-dist (make-instance 'point :x 2 :y 11) (self-coord *test-sensor*))
|
|
||||||
;; seems right
|
|
||||||
|
|
||||||
(get-no-unknown-beacons-x-interval 4 (make-sensor 1 1 2 2))
|
|
||||||
;; seems right
|
|
||||||
|
|
||||||
(get-no-unknown-beacons-x-interval 2 *test-sensor*)
|
|
||||||
;; yup
|
|
||||||
|
|
||||||
;; now. start with interval '(0 4000000)
|
|
||||||
;; list of that interval
|
|
||||||
;; when working on a line
|
|
||||||
;; get 'no-unknowns' interval for each scanner
|
|
||||||
;; then for each interval in the lists -
|
|
||||||
;; take it oud and put results of subtraction instead
|
|
||||||
|
|
||||||
(defun subtract-from-all (intervals subtrahend)
|
|
||||||
(mapcan (lambda (interval) (subtract-interval interval subtrahend))
|
|
||||||
intervals))
|
|
||||||
|
|
||||||
(subtract-from-all '((1 4000000)) '(5 15)) ; yay
|
|
||||||
(subtract-from-all '((1 10) (12 17) (20 25)) '(5 23)) ; yay
|
|
||||||
(subtract-from-all '((3 10) (12 17) (20 25)) '(1 40)) ; yay
|
|
||||||
(subtract-from-all '((3 10) (12 17) (20 25)) nil) ; yay
|
|
||||||
|
|
||||||
;; now looping.
|
|
||||||
;; we fix line, then for each scanner we calculate interval and update our intervals
|
|
||||||
;; in the end - if not NIL - then some points can have "unknown beacond"
|
|
||||||
|
|
||||||
;; let's figure out inner loop first
|
|
||||||
(defun line-unknown-intervals (y scanners max-x)
|
|
||||||
(do*
|
|
||||||
((rest-scanners scanners (cdr rest-scanners))
|
|
||||||
(scanner (first rest-scanners) (first rest-scanners))
|
|
||||||
(known-interval (get-no-unknown-beacons-x-interval y scanner)
|
|
||||||
(when scanner (get-no-unknown-beacons-x-interval y scanner)))
|
|
||||||
(intervals (subtract-from-all `((0 ,max-x)) known-interval)
|
|
||||||
(subtract-from-all intervals known-interval)))
|
|
||||||
((not scanner) intervals)
|
|
||||||
;; (format t "step, ~a intervals, after removing ~a; from ~a ~%" intervals known-interval scanner)
|
|
||||||
))
|
|
||||||
|
|
||||||
(line-unknown-intervals 11 (get-sensors-list "day15-test.txt") 20)
|
|
||||||
(line-unknown-intervals 10 (get-sensors-list "day15-test.txt") 20)
|
|
||||||
;; 2: (SUBTRACT-FROM-ALL ((0 2) 14 4000000) (-3 3))
|
|
||||||
;; why is that intervals get polluted
|
|
||||||
;;
|
|
||||||
;; anothre problem we don't include last scanner?
|
|
||||||
;;
|
|
||||||
;; and another problem. do we remove too little?
|
|
||||||
;; step, ((-40 11) (13 40)) intervals, after removing (12 12); from #<SENSOR at: #<POINT x:12 y:14>, linked to: #<POINT x:10 y:16>, covering dist: 4>
|
|
||||||
;; for line y=10, dist 4, sensor at <POINT x:12 y:14>, no all ok
|
|
||||||
|
|
||||||
;; so, proposed answer is x=14, y=11
|
|
||||||
;; which sensor precludes that in my process?
|
|
||||||
;; step, ((-40 10) (14 40)) intervals, after removing (11 13); from #<SENSOR at: #<POINT x:12 y:14>, linked to: #<POINT x:10 y:16>, covering dist: 4>
|
|
||||||
;; <SENSOR at: #<POINT x:12 y:14>, linked to: #<POINT x:10 y:16>, covering dist: 4>
|
|
||||||
;; for y=11. dist is 3. so 12+-1 right?
|
|
||||||
(manh-dist (make-instance 'point :x 12 :y 14)
|
|
||||||
(make-instance 'point :x 14 :y 11))
|
|
||||||
;; so here distance is 5. wtf.
|
|
||||||
;; so. y=11
|
|
||||||
;; sensor at <POINT x:12 y:14>
|
|
||||||
;; we spend 3 12+-1 wtf
|
|
||||||
;; OOOH. it's (14 14) - meaning X is 14
|
|
||||||
;; and Y is 11
|
|
||||||
;; crap
|
|
||||||
|
|
||||||
|
|
||||||
(subtract-from-all '((1 4000000)) '(3 13)) ; yay
|
|
||||||
;; using (format t "step, ~a intervals, after removing ~a ~%" intervals known-interval)
|
|
||||||
;; inside of DO loop
|
|
||||||
(subtract-from-all '((0 10) (14 400000)) '(3 13)) ; whoa
|
|
||||||
(subtract-interval '(14 400000) '(3 13)) ; correct not changed
|
|
||||||
;; well that's because in the "all below" i return not list of list
|
|
||||||
;; hello type safety, man
|
|
||||||
|
|
||||||
|
|
||||||
(defparameter *day-15-2-ans* nil)
|
|
||||||
(setq *day-15-2-ans*
|
|
||||||
(let ((sensors (get-sensors-list "day15-input.txt")))
|
|
||||||
(loop
|
|
||||||
for y from 1 to 4000000
|
|
||||||
for y-unknown-intervals = (line-unknown-intervals y sensors 4000000)
|
|
||||||
when y-unknown-intervals collect (list y y-unknown-intervals)
|
|
||||||
when (= 0 (mod y 10000)) do (format t "in step ~a~%" y))))
|
|
||||||
(print *day-15-2-ans*)
|
|
||||||
;; well, there are lots of "possible solutions", ugh
|
|
||||||
|
|
||||||
(defparameter *day-15-2-test* nil)
|
|
||||||
(setq *day-15-2-test*
|
|
||||||
(let ((sensors (get-sensors-list "day15-test.txt")))
|
|
||||||
(loop
|
|
||||||
for y from 0 to 20
|
|
||||||
for y-unknown-intervals = (line-unknown-intervals y sensors 20)
|
|
||||||
when y-unknown-intervals collect (list y y-unknown-intervals)
|
|
||||||
when (= 0 (mod y 1000)) do (format t "in step ~a~%" y))))
|
|
||||||
*day-15-2-test*
|
|
||||||
|
|
||||||
;; so, i do find the answer, but also lots of NON ANSWERS:
|
|
||||||
'((11 ((14 14))) (12 ((3 3))) (13 ((2 4))) (14 ((1 5))) (15 ((0 6)))
|
|
||||||
(16 ((0 7))) (17 ((0 8))) (18 ((0 7))) (19 ((0 6))) (20 ((0 5))))
|
|
||||||
|
|
||||||
;; for example :x 3 :y 12
|
|
||||||
;; it should have been thrown out. why not? which scanner should have covered it
|
|
||||||
(line-unknown-intervals 12 (get-sensors-list "day15-test.txt") 20)
|
|
||||||
;; for example (3 12) and (-2 15 #7) nope, ok
|
|
||||||
;; for example (3 12) and (8 7 #9) nope, ok
|
|
||||||
|
|
||||||
;; i need to automate it. for all scanners, find what? closest?
|
|
||||||
(let ((p (make-instance 'point :x 3 :y 12)))
|
|
||||||
(loop
|
|
||||||
for scanner in (get-sensors-list "day15-test.txt")
|
|
||||||
collect (list (manh-dist (self-coord scanner) p) (covered-dist scanner))))
|
|
||||||
;; so for 1st scanner, dist 7 and covered-dist is 7.
|
|
||||||
;; UGH
|
|
||||||
;; and
|
|
||||||
;; - step, ((0 20)) intervals, after removing (1 3); from #<SENSOR at: #<POINT x:2 y:18>, linked to: #<POINT x:-2 y:15>, covering dist: 7>
|
|
||||||
;; here it was all along
|
|
||||||
|
|
||||||
(subtract-from-all '((0 20)) '(1 3 ))
|
|
||||||
;; maybe that's bug of first iteration of DO* or something
|
|
||||||
;; it would be in "non-covered interval"
|
|
||||||
|
|
||||||
|
|
||||||
;; maybe i don't remove enough?
|
|
||||||
;; i should remove interval where all points "covered by the sensor"
|
|
||||||
|
|
||||||
;; do i want to draw that shit?
|
|
||||||
'(((-40 -8) (28 40)) ((-40 -7) (27 40)) ((-40 -6) (26 40)) ((-40 -5) (25 40))
|
|
||||||
((-40 -4) (24 40)) ((-40 -3) (23 40)) ((-40 -2) (22 40)) ((-40 -1) (23 40))
|
|
||||||
((-40 -2) (24 40)) ((-40 -3) (25 40)) ((-40 -4) (14 14) (26 40))
|
|
||||||
((-40 -3) (3 3) (27 40)) ((-40 -2) (2 4) (28 40)) ((-40 -1) (1 5) (29 40))
|
|
||||||
((-40 6) (28 40)) ((-40 7) (27 40)) ((-40 8) (26 40)) ((-40 7) (25 40))
|
|
||||||
((-40 6) (24 40)) ((-40 5) (24 40)))
|
|
||||||
|
|
||||||
(defun draw-line-def (line-intervals)
|
|
||||||
(format t "!")
|
|
||||||
(do*
|
|
||||||
((intervals line-intervals (cdr intervals))
|
|
||||||
(prev-interval nil interval)
|
|
||||||
(interval (first intervals) (first intervals)))
|
|
||||||
((not interval) nil)
|
|
||||||
;; (format t "iteration int: ~a; prev: ~a" interval prev-interval)
|
|
||||||
(when (not prev-interval)
|
|
||||||
(dotimes (i (first interval))
|
|
||||||
(format t ".")))
|
|
||||||
(when prev-interval
|
|
||||||
(dotimes (i (- (first interval) (second prev-interval)))
|
|
||||||
(format t ".")))
|
|
||||||
(dotimes (i (- (second interval) (first interval)))
|
|
||||||
(format t "#"))
|
|
||||||
)
|
|
||||||
(format t "!") (terpri)
|
|
||||||
)
|
|
||||||
|
|
||||||
(draw-line-def '((-40 -8) (28 40)))
|
|
||||||
;; ok, i have 'draw-line'
|
|
||||||
(loop for line-def in *day-15-2-test* do
|
|
||||||
(draw-line-def line-def))
|
|
||||||
;;
|
|
||||||
;; let's yolo
|
|
||||||
(2175292 ((2335771 2335771)))
|
|
||||||
(+ (* 2335771) 2175292)
|
|
||||||
;; that didn't work
|
|
|
@ -1,14 +0,0 @@
|
||||||
Sensor at x=2, y=18: closest beacon is at x=-2, y=15
|
|
||||||
Sensor at x=9, y=16: closest beacon is at x=10, y=16
|
|
||||||
Sensor at x=13, y=2: closest beacon is at x=15, y=3
|
|
||||||
Sensor at x=12, y=14: closest beacon is at x=10, y=16
|
|
||||||
Sensor at x=10, y=20: closest beacon is at x=10, y=16
|
|
||||||
Sensor at x=14, y=17: closest beacon is at x=10, y=16
|
|
||||||
Sensor at x=8, y=7: closest beacon is at x=2, y=10
|
|
||||||
Sensor at x=2, y=0: closest beacon is at x=2, y=10
|
|
||||||
Sensor at x=0, y=11: closest beacon is at x=2, y=10
|
|
||||||
Sensor at x=20, y=14: closest beacon is at x=25, y=17
|
|
||||||
Sensor at x=17, y=20: closest beacon is at x=21, y=22
|
|
||||||
Sensor at x=16, y=7: closest beacon is at x=15, y=3
|
|
||||||
Sensor at x=14, y=3: closest beacon is at x=15, y=3
|
|
||||||
Sensor at x=20, y=1: closest beacon is at x=15, y=3
|
|
151
day15.lisp
151
day15.lisp
|
@ -1,151 +0,0 @@
|
||||||
;; https://adventofcode.com/2022/day/15
|
|
||||||
|
|
||||||
(ql:quickload 'cl-ppcre)
|
|
||||||
|
|
||||||
(defparameter *day15-input-file* "day15-test.txt")
|
|
||||||
|
|
||||||
(defclass point ()
|
|
||||||
((x :initarg :x :reader x)
|
|
||||||
(y :initarg :y :reader y)))
|
|
||||||
|
|
||||||
(defmethod print-object ((obj point) stream)
|
|
||||||
(print-unreadable-object (obj stream :type t)
|
|
||||||
(with-slots (x y)
|
|
||||||
obj
|
|
||||||
(format stream "x:~a y:~a" x y))))
|
|
||||||
|
|
||||||
(defmethod points-equal ((left point) (right point))
|
|
||||||
(and (= (x left) (x right))
|
|
||||||
(= (y left) (y right))))
|
|
||||||
|
|
||||||
(defmethod manh-dist ((one point) (two point))
|
|
||||||
(+ (abs (- (x one) (x two)))
|
|
||||||
(abs (- (y one) (y two)))))
|
|
||||||
|
|
||||||
|
|
||||||
(defclass sensor ()
|
|
||||||
((self-coord :initarg :self :reader self-coord)
|
|
||||||
(beacon-coord :initarg :beacon :reader beacon-coord)
|
|
||||||
(covered-dist :initarg :dist :reader covered-dist)))
|
|
||||||
|
|
||||||
(defun make-sensor (sens-x sens-y beac-x beac-y)
|
|
||||||
(let* ((sensor (make-instance 'point :x sens-x :y sens-y))
|
|
||||||
(beacon (make-instance 'point :x beac-x :y beac-y))
|
|
||||||
(dist (manh-dist sensor beacon)))
|
|
||||||
(make-instance 'sensor :self sensor :beacon beacon :dist dist)))
|
|
||||||
|
|
||||||
(defmethod print-object ((obj sensor) stream)
|
|
||||||
(print-unreadable-object (obj stream :type t)
|
|
||||||
(with-slots (self-coord beacon-coord covered-dist)
|
|
||||||
obj
|
|
||||||
(format stream "at: ~a, linked to: ~a, covering dist: ~a"
|
|
||||||
self-coord beacon-coord covered-dist))))
|
|
||||||
|
|
||||||
|
|
||||||
(defmethod can-have-unknown-beacon-p ((p point) (s sensor))
|
|
||||||
(> (manh-dist p (self-coord s))
|
|
||||||
(covered-dist s)))
|
|
||||||
|
|
||||||
(defun line-to-coords (line)
|
|
||||||
(rest (mapcar (lambda (str)
|
|
||||||
(parse-integer str :junk-allowed t))
|
|
||||||
(cl-ppcre:split "=" line))))
|
|
||||||
|
|
||||||
(defun get-sensors-list (input-file-name)
|
|
||||||
(mapcar (lambda (coords-list)
|
|
||||||
(apply #'make-sensor coords-list))
|
|
||||||
(mapcar #'line-to-coords (uiop:read-file-lines input-file-name))))
|
|
||||||
|
|
||||||
(defun get-limits (sensors-list)
|
|
||||||
(loop
|
|
||||||
for sensor in sensors-list
|
|
||||||
minimize (x (self-coord sensor)) into xs
|
|
||||||
minimize (x (beacon-coord sensor)) into xs
|
|
||||||
maximize (x (self-coord sensor)) into xm
|
|
||||||
maximize (x (beacon-coord sensor)) into xm
|
|
||||||
minimize (y (self-coord sensor)) into ys
|
|
||||||
minimize (y (beacon-coord sensor)) into ys
|
|
||||||
maximize (y (self-coord sensor)) into ym
|
|
||||||
maximize (y (beacon-coord sensor)) into ym
|
|
||||||
finally (return (list xs xm ys ym))))
|
|
||||||
|
|
||||||
(defun possible-to-have-beacon (point sensors)
|
|
||||||
(let ((all-checks
|
|
||||||
(mapcar (lambda (sensor)
|
|
||||||
(if (points-equal point (beacon-coord sensor))
|
|
||||||
'known-sensor
|
|
||||||
(can-have-unknown-beacon-p point sensor) ; single NIL means - not possible to have unknown
|
|
||||||
))
|
|
||||||
sensors)))
|
|
||||||
(or (not (position nil all-checks)) ; nil if all sensors allow (said T) presense of unknown beacons
|
|
||||||
(position 'known-sensor all-checks) ; exists known sensor
|
|
||||||
)))
|
|
||||||
|
|
||||||
(defun count-certainly-not-beacons (input-file-name)
|
|
||||||
(let ((sensors (get-sensors-list input-file-name)))
|
|
||||||
(destructuring-bind (min-x max-x min-y max-y)
|
|
||||||
(get-limits sensors)
|
|
||||||
(let ((to-add-x (abs (- max-x min-x)))
|
|
||||||
;; (to-check-y 10)
|
|
||||||
(to-check-y 2000000)
|
|
||||||
)
|
|
||||||
(loop
|
|
||||||
for x from (- min-x to-add-x) to (+ max-x to-add-x)
|
|
||||||
count (not (possible-to-have-beacon
|
|
||||||
(make-instance 'point :x x :y to-check-y)
|
|
||||||
sensors))
|
|
||||||
do (format t "iterating for x:~a y:~a~%" x to-check-y))))))
|
|
||||||
|
|
||||||
(count-certainly-not-beacons "day15-test.txt")
|
|
||||||
;; (count-certainly-not-beacons "day15-input.txt")
|
|
||||||
|
|
||||||
;; well, that's just too slow
|
|
||||||
;; how do i rewrite it to make it faster?
|
|
||||||
;; i guess i could exclude the sensors which are too far away from the list?
|
|
||||||
;;
|
|
||||||
;; well, optimization here that we move by 1 point toward or away from sensor
|
|
||||||
;; so, we can kind of calculate when we'll be in it's range?
|
|
||||||
;; * in what amount of steps
|
|
||||||
;; ** whoa, org colors
|
|
||||||
;;
|
|
||||||
;; so.
|
|
||||||
|
|
||||||
;; PART 2 - just start search overnight?
|
|
||||||
;; for 0 to 4.000.000 by x and y?
|
|
||||||
;; and collect all such possible x and y?
|
|
||||||
;; nope, even if it were 5 minutes for 16mil,
|
|
||||||
;; so 2 minutes per 4 mil, then multiply by 4M - more than a day.
|
|
||||||
;; think better
|
|
||||||
|
|
||||||
(defun subtract-interval (minuend subtrahend)
|
|
||||||
(if (not subtrahend)
|
|
||||||
(list minuend) ; list of one interval
|
|
||||||
(destructuring-bind ((m-left m-right) (s-left s-right)) (list minuend subtrahend)
|
|
||||||
(cond
|
|
||||||
((< m-right s-left)
|
|
||||||
(list (list m-left m-right))) ; minuend fully to the left
|
|
||||||
((> m-left s-right)
|
|
||||||
(list (list m-left m-right))) ; minuend fully to the right
|
|
||||||
((and (< m-left s-left)
|
|
||||||
(> m-right s-right)) ; minuend is around subtrahend
|
|
||||||
(list (list m-left (1- s-left))
|
|
||||||
(list (1+ s-right) m-right))) ; part before and after subtrahend
|
|
||||||
((and (>= m-left s-left)
|
|
||||||
(<= m-right s-right)) ; subtrahend consumes minuend
|
|
||||||
nil)
|
|
||||||
((< m-left s-left) ; minuend start to the left, but not subtrahend consumes all right part
|
|
||||||
(list (list m-left (1- s-left)))) ; list of one interval
|
|
||||||
((> m-right s-right) ; minuend has part to the right of subtrahend
|
|
||||||
(list (list (1+ s-right) m-right)))))))
|
|
||||||
|
|
||||||
|
|
||||||
(defun get-no-unknown-beacons-x-interval (line-y scanner)
|
|
||||||
(let* ((y-dist (abs (- line-y (y (self-coord scanner)))))
|
|
||||||
(x-slack (- (covered-dist scanner) y-dist))
|
|
||||||
(x-sc (x (self-coord scanner))))
|
|
||||||
(when (>= x-slack 0)
|
|
||||||
(list (- x-sc x-slack) (+ x-sc x-slack)))))
|
|
||||||
|
|
||||||
(defun subtract-from-all (intervals subtrahend)
|
|
||||||
(mapcan (lambda (interval) (subtract-interval interval subtrahend))
|
|
||||||
intervals))
|
|
Loading…
Reference in New Issue