advent of code 2025 in ts and nix
at main 51 kB view raw
1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <title>AoC 2025 Day 8 - Playground Junction Boxes</title> 7 <style> 8 * { 9 box-sizing: border-box; 10 margin: 0; 11 padding: 0; 12 } 13 body { 14 background: #1e1e2e; 15 color: #cdd6f4; 16 font-family: "Source Code Pro", monospace; 17 font-size: 14pt; 18 font-weight: 300; 19 overflow: hidden; 20 margin: 0; 21 padding: 0; 22 } 23 #container { 24 width: 100vw; 25 height: 100vh; 26 position: relative; 27 } 28 #canvas { 29 width: 100%; 30 height: 100%; 31 display: block; 32 position: absolute; 33 top: 0; 34 left: 0; 35 z-index: 0; 36 } 37 .ui { 38 position: absolute; 39 top: 0; 40 left: 0; 41 right: 0; 42 padding: 20px; 43 pointer-events: none; 44 z-index: 1; 45 } 46 .ui > * { 47 pointer-events: auto; 48 } 49 h1 { 50 color: #a6e3a1; 51 text-shadow: 0 0 2px #a6e3a1, 0 0 5px #a6e3a1; 52 margin-bottom: 10px; 53 font-size: 1em; 54 font-weight: normal; 55 text-align: center; 56 } 57 .controls { 58 background: rgba(17, 17, 27, 0.9); 59 border: 1px solid #313244; 60 padding: 15px; 61 margin: 15px auto; 62 max-width: 800px; 63 border-radius: 4px; 64 } 65 .timeline-container { 66 background: rgba(17, 17, 27, 0.9); 67 border: 1px solid #313244; 68 padding: 20px; 69 margin: 10px auto; 70 max-width: 800px; 71 border-radius: 4px; 72 } 73 .timeline-label { 74 color: #a6adc8; 75 font-size: 12px; 76 margin-bottom: 10px; 77 display: flex; 78 justify-content: space-between; 79 align-items: center; 80 } 81 .timeline-markers { 82 position: relative; 83 margin-top: 8px; 84 font-size: 11px; 85 color: #6c7086; 86 height: 30px; 87 } 88 .timeline-marker { 89 position: absolute; 90 text-align: center; 91 transform: translateX(-50%); 92 white-space: nowrap; 93 } 94 .timeline-marker.start { 95 left: 0%; 96 transform: translateX(0); 97 } 98 .timeline-marker.end { 99 right: 0%; 100 transform: translateX(0); 101 text-align: right; 102 } 103 .timeline-marker.highlight { 104 color: #a6e3a1; 105 font-weight: bold; 106 } 107 .timeline-slider { 108 width: 100% !important; 109 -webkit-appearance: none; 110 appearance: none; 111 height: 12px; 112 background: linear-gradient(to right, #313244 0%, #313244 100%); 113 outline: none; 114 border-radius: 6px; 115 cursor: pointer; 116 position: relative; 117 } 118 .timeline-slider::-webkit-slider-thumb { 119 -webkit-appearance: none; 120 appearance: none; 121 width: 24px; 122 height: 24px; 123 background: #a6e3a1; 124 cursor: grab; 125 border-radius: 50%; 126 border: 3px solid #11111b; 127 box-shadow: 0 2px 8px rgba(166, 227, 161, 0.4); 128 transition: all 0.2s ease; 129 } 130 .timeline-slider::-moz-range-thumb { 131 width: 24px; 132 height: 24px; 133 background: #a6e3a1; 134 cursor: grab; 135 border-radius: 50%; 136 border: 3px solid #11111b; 137 box-shadow: 0 2px 8px rgba(166, 227, 161, 0.4); 138 transition: all 0.2s ease; 139 } 140 .timeline-slider::-webkit-slider-thumb:hover { 141 background: #b4e7b9; 142 transform: scale(1.1); 143 box-shadow: 0 4px 12px rgba(166, 227, 161, 0.6); 144 } 145 .timeline-slider::-moz-range-thumb:hover { 146 background: #b4e7b9; 147 transform: scale(1.1); 148 box-shadow: 0 4px 12px rgba(166, 227, 161, 0.6); 149 } 150 .timeline-slider:active::-webkit-slider-thumb { 151 cursor: grabbing; 152 transform: scale(0.95); 153 } 154 .timeline-slider:active::-moz-range-thumb { 155 cursor: grabbing; 156 transform: scale(0.95); 157 } 158 .control-row { 159 display: flex; 160 gap: 15px; 161 align-items: center; 162 margin-bottom: -1rem; 163 flex-wrap: wrap; 164 justify-content: center; 165 } 166 .control-row:last-child { 167 margin-bottom: 0; 168 } 169 button { 170 background: #11111b; 171 color: #a6e3a1; 172 border: 1px solid #313244; 173 padding: 8px 16px; 174 cursor: pointer; 175 font-family: inherit; 176 font-size: 14px; 177 border-radius: 3px; 178 } 179 button:hover { 180 background: #181825; 181 } 182 button:disabled { 183 opacity: 0.5; 184 cursor: not-allowed; 185 } 186 .info { 187 color: #f9e2af; 188 font-size: 14px; 189 } 190 .stats { 191 background: rgba(17, 17, 27, 0.9); 192 border: 1px solid #313244; 193 padding: 10px 15px; 194 margin: 0 auto; 195 max-width: 800px; 196 border-radius: 4px; 197 text-align: center; 198 font-size: 13px; 199 color: #a6adc8; 200 position: fixed; 201 bottom: 20px; 202 left: 50%; 203 transform: translateX(-50%); 204 z-index: 1; 205 } 206 .legend { 207 display: flex; 208 gap: 15px; 209 margin-top: 10px; 210 flex-wrap: wrap; 211 justify-content: center; 212 } 213 .legend-item { 214 display: flex; 215 align-items: center; 216 gap: 6px; 217 font-size: 12px; 218 color: #a6adc8; 219 } 220 .legend-box { 221 width: 12px; 222 height: 12px; 223 border-radius: 50%; 224 } 225 .legend-box.junction { background: #89b4fa; } 226 .legend-box.connection { background: #a6e3a1; } 227 .legend-box.circuit { background: #f9e2af; } 228 input[type="range"] { 229 -webkit-appearance: none; 230 appearance: none; 231 width: 120px; 232 height: 6px; 233 background: #313244; 234 outline: none; 235 border: 1px solid #313244; 236 } 237 input[type="range"]::-webkit-slider-thumb { 238 -webkit-appearance: none; 239 appearance: none; 240 width: 16px; 241 height: 16px; 242 background: #a6e3a1; 243 cursor: pointer; 244 border: 1px solid #313244; 245 border-radius: 50%; 246 } 247 input[type="range"]::-moz-range-thumb { 248 width: 16px; 249 height: 16px; 250 background: #a6e3a1; 251 cursor: pointer; 252 border: 1px solid #313244; 253 border-radius: 50%; 254 } 255 label { 256 color: #a6adc8; 257 font-size: 13px; 258 } 259 a { 260 text-decoration: none; 261 color: #a6e3a1; 262 outline: 0; 263 } 264 a:hover, a:focus { 265 text-decoration: underline; 266 } 267 </style> 268</head> 269<body> 270 <div id="container"> 271 <canvas id="canvas"></canvas> 272 <div class="ui"> 273 <h1>AoC 2025 Day 8 - Playground Junction Boxes</h1> 274 275 <div class="controls"> 276 <div class="control-row"> 277 <button id="prev">← Previous</button> 278 <button id="play">▶ Play</button> 279 <button id="next">Next →</button> 280 <button id="reset">↺ Reset</button> 281 </div> 282 <div class="timeline-label"> 283 <span>Timeline</span> 284 <span id="timelineStep">Step 0 of 7845</span> 285 </div> 286 <input type="range" id="timeline" class="timeline-slider" min="0" max="7845" value="0" step="1"> 287 <div class="timeline-markers"> 288 <div class="timeline-marker start">Start<br>0</div> 289 <div class="timeline-marker highlight" style="left: 12.746972594008923%;">Part 1<br>1000</div> 290 <div class="timeline-marker highlight end">Part 2<br>7845</div> 291 </div> 292 <div class="legend"> 293 <div class="legend-item"><div class="legend-box junction"></div> Isolated Junction (small)</div> 294 <div class="legend-item"><div class="legend-box connection"></div> Connected Junction (large)</div> 295 <div class="legend-item"><div class="legend-box circuit"></div> Circuit (color-coded)</div> 296 </div> 297 </div> 298 299 <div class="stats"> 300 <div id="statsInfo">Circuits: 1000 | Largest: 0 | Part 1: 0 | Part 2: 0</div> 301 <div style="margin-top: 5px; font-size: 11px;"><a href="../index.html">[Return to Index]</a></div> 302 </div> 303 </div> 304 </div> 305 306 <script type="importmap"> 307 { 308 "imports": { 309 "three": "https://cdn.jsdelivr.net/npm/three@0.170.0/build/three.module.js", 310 "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.170.0/examples/jsm/" 311 } 312 } 313 </script> 314 315 <script type="module"> 316 import * as THREE from 'three'; 317 import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; 318 319 // Input data embedded 320 const junctions = [{"x":5161,"y":22203,"z":73169},{"x":66101,"y":34794,"z":41187},{"x":19740,"y":85581,"z":70637},{"x":64804,"y":51256,"z":2927},{"x":68224,"y":49993,"z":7867},{"x":9878,"y":97392,"z":46130},{"x":40001,"y":51521,"z":79544},{"x":45624,"y":73253,"z":74846},{"x":30230,"y":58923,"z":59531},{"x":84723,"y":58102,"z":86638},{"x":14537,"y":44841,"z":84567},{"x":41558,"y":92494,"z":89096},{"x":75012,"y":1225,"z":75685},{"x":77420,"y":67581,"z":11653},{"x":2365,"y":26154,"z":61974},{"x":80460,"y":35718,"z":17495},{"x":84603,"y":85352,"z":97745},{"x":85312,"y":81113,"z":25465},{"x":84808,"y":39686,"z":39315},{"x":78930,"y":20627,"z":23019},{"x":9138,"y":22120,"z":32917},{"x":43534,"y":38414,"z":62909},{"x":1852,"y":53657,"z":68936},{"x":42113,"y":82762,"z":91457},{"x":54027,"y":40542,"z":58053},{"x":82202,"y":42280,"z":72268},{"x":202,"y":67735,"z":80514},{"x":52305,"y":854,"z":45988},{"x":88343,"y":55523,"z":31987},{"x":28291,"y":46179,"z":65951},{"x":91364,"y":63556,"z":74551},{"x":86323,"y":53379,"z":5679},{"x":4978,"y":97691,"z":830},{"x":72221,"y":98591,"z":40848},{"x":76259,"y":31452,"z":38504},{"x":24278,"y":31745,"z":72816},{"x":43435,"y":38188,"z":12128},{"x":38931,"y":44301,"z":87982},{"x":12819,"y":90012,"z":60798},{"x":22440,"y":63786,"z":13427},{"x":72991,"y":66943,"z":5903},{"x":99694,"y":22765,"z":27658},{"x":14531,"y":64099,"z":3781},{"x":81830,"y":53305,"z":71039},{"x":16083,"y":37712,"z":94291},{"x":1861,"y":15536,"z":36482},{"x":49895,"y":20278,"z":79203},{"x":81296,"y":28469,"z":21142},{"x":18962,"y":44916,"z":45948},{"x":75556,"y":98208,"z":8719},{"x":17073,"y":99830,"z":64332},{"x":80061,"y":73938,"z":7885},{"x":84505,"y":81534,"z":49321},{"x":51314,"y":28742,"z":90563},{"x":45266,"y":91838,"z":54563},{"x":68720,"y":31965,"z":85325},{"x":17087,"y":71197,"z":81398},{"x":21515,"y":19915,"z":83771},{"x":98426,"y":60158,"z":81708},{"x":39695,"y":27980,"z":22169},{"x":74294,"y":16001,"z":70164},{"x":37834,"y":77125,"z":68205},{"x":50158,"y":66031,"z":33997},{"x":6228,"y":61768,"z":85916},{"x":18288,"y":41150,"z":22719},{"x":22002,"y":47425,"z":92208},{"x":56877,"y":4935,"z":3480},{"x":62885,"y":9582,"z":43220},{"x":40257,"y":2330,"z":33318},{"x":98759,"y":96290,"z":18372},{"x":73781,"y":23958,"z":3804},{"x":7471,"y":82734,"z":46760},{"x":35024,"y":97965,"z":71262},{"x":37867,"y":65856,"z":50384},{"x":52511,"y":81222,"z":52412},{"x":33482,"y":59673,"z":3263},{"x":5675,"y":59568,"z":35932},{"x":21251,"y":43750,"z":56819},{"x":96765,"y":7988,"z":87769},{"x":20307,"y":50290,"z":65243},{"x":17293,"y":84764,"z":12114},{"x":66302,"y":92742,"z":19412},{"x":72049,"y":98072,"z":97246},{"x":53960,"y":10572,"z":73353},{"x":17692,"y":2175,"z":43186},{"x":26181,"y":26692,"z":78570},{"x":6206,"y":68914,"z":3522},{"x":80114,"y":23493,"z":14095},{"x":35469,"y":79858,"z":91410},{"x":21464,"y":22046,"z":6372},{"x":39867,"y":59222,"z":96369},{"x":41647,"y":17493,"z":96062},{"x":21818,"y":91894,"z":75532},{"x":8309,"y":91873,"z":78553},{"x":211,"y":75084,"z":88402},{"x":70079,"y":49640,"z":88549},{"x":53250,"y":64935,"z":66594},{"x":59536,"y":22170,"z":30100},{"x":60861,"y":99105,"z":14003},{"x":61621,"y":27840,"z":90515},{"x":74639,"y":29893,"z":7322},{"x":84678,"y":40440,"z":94821},{"x":97113,"y":95314,"z":13072},{"x":68608,"y":49658,"z":91760},{"x":63585,"y":86976,"z":70868},{"x":80713,"y":2187,"z":45320},{"x":53966,"y":90337,"z":38684},{"x":12879,"y":57544,"z":67234},{"x":1808,"y":55865,"z":37081},{"x":29062,"y":1242,"z":56047},{"x":68536,"y":82413,"z":79663},{"x":82931,"y":37875,"z":80295},{"x":71837,"y":70100,"z":82856},{"x":8604,"y":29732,"z":15837},{"x":55168,"y":22932,"z":85866},{"x":7831,"y":59139,"z":11394},{"x":68246,"y":95928,"z":25366},{"x":5516,"y":88931,"z":66654},{"x":96479,"y":58400,"z":51809},{"x":21133,"y":61075,"z":29966},{"x":43770,"y":13343,"z":39028},{"x":75024,"y":25103,"z":58888},{"x":35728,"y":97042,"z":40407},{"x":93159,"y":78375,"z":73702},{"x":59258,"y":10570,"z":78625},{"x":58756,"y":87652,"z":98984},{"x":32438,"y":36234,"z":86197},{"x":42461,"y":39846,"z":29989},{"x":91102,"y":74517,"z":69917},{"x":24981,"y":69124,"z":48442},{"x":95106,"y":21901,"z":90494},{"x":52329,"y":5337,"z":48036},{"x":74828,"y":37780,"z":86916},{"x":73037,"y":37561,"z":82293},{"x":11261,"y":5900,"z":29591},{"x":47758,"y":40284,"z":70586},{"x":44437,"y":88862,"z":81499},{"x":2771,"y":47188,"z":65346},{"x":48737,"y":73833,"z":22256},{"x":6681,"y":31926,"z":14269},{"x":14890,"y":4721,"z":99568},{"x":74643,"y":59728,"z":83172},{"x":44018,"y":65177,"z":11311},{"x":28163,"y":95996,"z":55663},{"x":62284,"y":4057,"z":40282},{"x":85786,"y":8606,"z":16706},{"x":38301,"y":35943,"z":83825},{"x":93121,"y":30446,"z":83456},{"x":80709,"y":93878,"z":46043},{"x":25806,"y":35135,"z":61144},{"x":82648,"y":87205,"z":99228},{"x":81004,"y":39106,"z":48053},{"x":45717,"y":30505,"z":54773},{"x":97465,"y":49038,"z":15700},{"x":46560,"y":20959,"z":89092},{"x":41799,"y":67704,"z":577},{"x":36770,"y":96608,"z":79263},{"x":40028,"y":55549,"z":56718},{"x":14448,"y":88161,"z":97119},{"x":26854,"y":84620,"z":40111},{"x":70853,"y":7432,"z":76917},{"x":55200,"y":24264,"z":16287},{"x":59,"y":67218,"z":14635},{"x":6942,"y":65638,"z":37471},{"x":68640,"y":68354,"z":35571},{"x":40272,"y":87947,"z":27089},{"x":6692,"y":88929,"z":43004},{"x":21229,"y":45052,"z":37013},{"x":15926,"y":71370,"z":74945},{"x":92692,"y":75869,"z":34838},{"x":91181,"y":95437,"z":48530},{"x":18204,"y":12940,"z":45467},{"x":35323,"y":15520,"z":69239},{"x":82373,"y":40019,"z":86985},{"x":80756,"y":54592,"z":21710},{"x":48243,"y":31541,"z":44180},{"x":46122,"y":84026,"z":53779},{"x":39293,"y":93745,"z":62710},{"x":46031,"y":21084,"z":76780},{"x":18406,"y":22463,"z":33328},{"x":49421,"y":94086,"z":30128},{"x":76265,"y":81888,"z":38769},{"x":51061,"y":44872,"z":30360},{"x":11748,"y":24035,"z":63578},{"x":27664,"y":31317,"z":20723},{"x":41342,"y":56333,"z":80116},{"x":6524,"y":33672,"z":42019},{"x":36451,"y":16429,"z":91763},{"x":25211,"y":84537,"z":10563},{"x":57256,"y":68807,"z":87002},{"x":16992,"y":17366,"z":32886},{"x":2095,"y":66214,"z":26424},{"x":72798,"y":44489,"z":12613},{"x":72302,"y":77566,"z":22389},{"x":83839,"y":80165,"z":79968},{"x":11488,"y":5510,"z":666},{"x":13321,"y":26484,"z":91940},{"x":88598,"y":20942,"z":28033},{"x":45663,"y":93458,"z":8868},{"x":13632,"y":60855,"z":21950},{"x":69401,"y":17820,"z":15957},{"x":99693,"y":49351,"z":24797},{"x":76038,"y":24933,"z":31774},{"x":36063,"y":8828,"z":29548},{"x":91198,"y":49648,"z":72812},{"x":14950,"y":49734,"z":84990},{"x":29974,"y":24256,"z":43142},{"x":19381,"y":8237,"z":23391},{"x":22823,"y":5267,"z":23772},{"x":57408,"y":109,"z":81592},{"x":25135,"y":3341,"z":44930},{"x":22021,"y":39757,"z":75364},{"x":921,"y":25399,"z":58355},{"x":34100,"y":75425,"z":22714},{"x":49845,"y":80698,"z":15599},{"x":75078,"y":43967,"z":63211},{"x":33418,"y":70727,"z":81931},{"x":11894,"y":93560,"z":98772},{"x":18360,"y":40040,"z":11898},{"x":13341,"y":57104,"z":74958},{"x":20124,"y":85072,"z":36147},{"x":11466,"y":57461,"z":25681},{"x":4890,"y":38197,"z":35448},{"x":24857,"y":93228,"z":69880},{"x":50868,"y":43259,"z":83785},{"x":10058,"y":67418,"z":98282},{"x":14583,"y":66434,"z":53841},{"x":74869,"y":52825,"z":81807},{"x":17976,"y":7604,"z":55075},{"x":28345,"y":58341,"z":54910},{"x":23937,"y":31696,"z":20983},{"x":15299,"y":65989,"z":48101},{"x":85948,"y":89595,"z":74642},{"x":55386,"y":58983,"z":43994},{"x":99999,"y":44512,"z":37075},{"x":75074,"y":15909,"z":8571},{"x":86057,"y":69748,"z":62953},{"x":30817,"y":82342,"z":17104},{"x":90956,"y":22036,"z":54469},{"x":93486,"y":72096,"z":63425},{"x":21847,"y":61753,"z":27413},{"x":76878,"y":83913,"z":6736},{"x":47263,"y":86404,"z":11866},{"x":54473,"y":77380,"z":8133},{"x":43916,"y":77261,"z":44094},{"x":31411,"y":73190,"z":80946},{"x":57844,"y":38767,"z":42289},{"x":67832,"y":36459,"z":80545},{"x":50394,"y":7272,"z":47306},{"x":32819,"y":25545,"z":67025},{"x":69061,"y":50499,"z":87171},{"x":29321,"y":3573,"z":96393},{"x":790,"y":54881,"z":30567},{"x":10323,"y":19294,"z":61513},{"x":42390,"y":48286,"z":82826},{"x":48131,"y":42651,"z":2327},{"x":63796,"y":43817,"z":56908},{"x":28226,"y":55100,"z":69879},{"x":20961,"y":95836,"z":666},{"x":22399,"y":63924,"z":10001},{"x":8586,"y":66790,"z":40318},{"x":66927,"y":1619,"z":64174},{"x":34447,"y":39223,"z":88816},{"x":53211,"y":28305,"z":63761},{"x":59463,"y":98390,"z":3323},{"x":21005,"y":38029,"z":96138},{"x":18979,"y":86778,"z":11125},{"x":39421,"y":55489,"z":41546},{"x":66733,"y":67487,"z":21536},{"x":85741,"y":27543,"z":34114},{"x":54905,"y":19440,"z":27003},{"x":80920,"y":97553,"z":51524},{"x":64486,"y":94319,"z":16244},{"x":47427,"y":88423,"z":99263},{"x":94831,"y":59526,"z":29750},{"x":20612,"y":19198,"z":3428},{"x":36838,"y":45561,"z":55848},{"x":3739,"y":24234,"z":96805},{"x":30520,"y":80842,"z":25923},{"x":75905,"y":4527,"z":45717},{"x":57097,"y":36462,"z":29937},{"x":12449,"y":12092,"z":75382},{"x":16241,"y":91132,"z":18465},{"x":92421,"y":32601,"z":39642},{"x":94358,"y":19855,"z":92919},{"x":98029,"y":17123,"z":98277},{"x":62997,"y":9369,"z":62516},{"x":5743,"y":97599,"z":15596},{"x":55128,"y":96754,"z":63021},{"x":64749,"y":29348,"z":87579},{"x":50931,"y":49963,"z":16511},{"x":24104,"y":10431,"z":32239},{"x":85592,"y":78853,"z":55919},{"x":54462,"y":92986,"z":61923},{"x":82923,"y":98099,"z":69987},{"x":65451,"y":96563,"z":45754},{"x":56042,"y":38226,"z":27831},{"x":10024,"y":90940,"z":53047},{"x":51092,"y":54380,"z":11833},{"x":58088,"y":87728,"z":35943},{"x":71276,"y":19838,"z":71114},{"x":28525,"y":42958,"z":70906},{"x":88225,"y":61386,"z":12953},{"x":74256,"y":4303,"z":23200},{"x":49526,"y":36042,"z":15796},{"x":9153,"y":94788,"z":23665},{"x":80101,"y":23495,"z":50819},{"x":31569,"y":685,"z":20686},{"x":22964,"y":44468,"z":35471},{"x":70246,"y":98432,"z":61863},{"x":72794,"y":47183,"z":51421},{"x":6710,"y":30845,"z":79164},{"x":81930,"y":58931,"z":76876},{"x":60308,"y":77291,"z":46931},{"x":95213,"y":70380,"z":78860},{"x":39666,"y":17476,"z":7322},{"x":95063,"y":1905,"z":43670},{"x":54354,"y":12416,"z":76624},{"x":53740,"y":3491,"z":62481},{"x":12864,"y":30769,"z":52235},{"x":32045,"y":63460,"z":79567},{"x":75862,"y":90991,"z":84898},{"x":38669,"y":63989,"z":25022},{"x":7799,"y":5513,"z":46763},{"x":24068,"y":39447,"z":50344},{"x":36023,"y":279,"z":64133},{"x":5465,"y":72858,"z":7840},{"x":29160,"y":24991,"z":21515},{"x":59713,"y":27231,"z":3281},{"x":36164,"y":90203,"z":93847},{"x":75331,"y":71291,"z":86760},{"x":42565,"y":52454,"z":17080},{"x":6955,"y":23878,"z":44603},{"x":40854,"y":37169,"z":54460},{"x":5285,"y":66356,"z":26455},{"x":63058,"y":94851,"z":50037},{"x":12741,"y":4910,"z":77151},{"x":32824,"y":27982,"z":26924},{"x":47478,"y":85766,"z":35219},{"x":16457,"y":86168,"z":96792},{"x":83127,"y":34305,"z":62074},{"x":95548,"y":14535,"z":41035},{"x":88855,"y":5223,"z":94494},{"x":50146,"y":163,"z":79528},{"x":23338,"y":33348,"z":38377},{"x":4070,"y":21412,"z":15793},{"x":96775,"y":52388,"z":47999},{"x":12154,"y":63542,"z":15677},{"x":88504,"y":99262,"z":54679},{"x":12808,"y":85236,"z":5704},{"x":3906,"y":14610,"z":29712},{"x":32559,"y":83568,"z":27884},{"x":93026,"y":38658,"z":39179},{"x":14070,"y":67679,"z":15610},{"x":29713,"y":12625,"z":84667},{"x":6921,"y":19610,"z":86805},{"x":66462,"y":57191,"z":80287},{"x":60537,"y":75661,"z":4167},{"x":38067,"y":9388,"z":24090},{"x":92022,"y":81040,"z":60306},{"x":54484,"y":9192,"z":84268},{"x":36791,"y":90762,"z":60181},{"x":75947,"y":15733,"z":50393},{"x":16807,"y":86935,"z":85406},{"x":8328,"y":60108,"z":63149},{"x":71295,"y":14068,"z":96601},{"x":80613,"y":26940,"z":67177},{"x":89681,"y":62762,"z":34136},{"x":10217,"y":93743,"z":30456},{"x":73059,"y":67804,"z":71175},{"x":9005,"y":74733,"z":45169},{"x":43845,"y":10522,"z":61274},{"x":56005,"y":15428,"z":11649},{"x":83175,"y":17043,"z":59977},{"x":58911,"y":36157,"z":73078},{"x":18088,"y":79910,"z":55693},{"x":81267,"y":64100,"z":26580},{"x":56896,"y":25358,"z":96591},{"x":65687,"y":86996,"z":70012},{"x":77409,"y":95703,"z":52067},{"x":31023,"y":70310,"z":62432},{"x":47952,"y":90510,"z":54558},{"x":68213,"y":85589,"z":46380},{"x":58332,"y":90985,"z":35281},{"x":54333,"y":45220,"z":15414},{"x":94029,"y":8669,"z":19406},{"x":14313,"y":90201,"z":57318},{"x":93133,"y":35598,"z":4739},{"x":57923,"y":86809,"z":49393},{"x":96319,"y":38176,"z":37542},{"x":88108,"y":46715,"z":16554},{"x":57259,"y":86355,"z":83582},{"x":92724,"y":64865,"z":59543},{"x":21703,"y":12027,"z":77429},{"x":82537,"y":84727,"z":10231},{"x":69466,"y":70604,"z":11687},{"x":25405,"y":34281,"z":72216},{"x":13429,"y":28547,"z":21532},{"x":50561,"y":60774,"z":36501},{"x":96078,"y":21610,"z":59197},{"x":75502,"y":7393,"z":90387},{"x":84406,"y":14971,"z":69869},{"x":63056,"y":23127,"z":75447},{"x":2987,"y":35313,"z":26884},{"x":75976,"y":38124,"z":62378},{"x":50678,"y":51910,"z":64734},{"x":92897,"y":9414,"z":78851},{"x":12385,"y":9019,"z":52962},{"x":49969,"y":73736,"z":13654},{"x":85171,"y":97718,"z":94935},{"x":69860,"y":46369,"z":35285},{"x":48996,"y":47871,"z":45331},{"x":34138,"y":70912,"z":14473},{"x":81860,"y":631,"z":53276},{"x":94452,"y":580,"z":73549},{"x":62698,"y":2127,"z":79924},{"x":25326,"y":51241,"z":35453},{"x":96322,"y":9704,"z":66070},{"x":18980,"y":34897,"z":88148},{"x":43690,"y":93420,"z":6598},{"x":74205,"y":53286,"z":67674},{"x":3254,"y":30109,"z":93966},{"x":57779,"y":91666,"z":11952},{"x":72134,"y":40940,"z":44488},{"x":99873,"y":83052,"z":1126},{"x":97309,"y":37450,"z":91956},{"x":55829,"y":40306,"z":91718},{"x":78390,"y":46731,"z":20057},{"x":91883,"y":47744,"z":85866},{"x":78125,"y":3512,"z":78114},{"x":54410,"y":61872,"z":96284},{"x":11630,"y":4634,"z":48245},{"x":583,"y":97186,"z":63568},{"x":50298,"y":62275,"z":77450},{"x":46247,"y":70570,"z":70214},{"x":94826,"y":69412,"z":5578},{"x":78568,"y":78523,"z":95664},{"x":36379,"y":91084,"z":3661},{"x":11137,"y":95017,"z":38825},{"x":71379,"y":44935,"z":23389},{"x":22116,"y":10182,"z":19393},{"x":26631,"y":14386,"z":8913},{"x":90244,"y":18267,"z":36040},{"x":53393,"y":4365,"z":99048},{"x":4079,"y":95272,"z":99036},{"x":59709,"y":84380,"z":53915},{"x":65569,"y":42790,"z":12489},{"x":61765,"y":46485,"z":97361},{"x":82601,"y":59377,"z":69738},{"x":59108,"y":17968,"z":28167},{"x":6237,"y":47107,"z":46872},{"x":93572,"y":74166,"z":87007},{"x":92142,"y":17034,"z":81637},{"x":11605,"y":97185,"z":26640},{"x":69469,"y":6432,"z":23789},{"x":69985,"y":80520,"z":26503},{"x":65480,"y":41448,"z":77875},{"x":16205,"y":81692,"z":74363},{"x":69176,"y":87344,"z":11992},{"x":57385,"y":71058,"z":8987},{"x":23453,"y":46306,"z":89249},{"x":9957,"y":58219,"z":86932},{"x":64935,"y":2339,"z":20205},{"x":31980,"y":85097,"z":77988},{"x":90690,"y":42666,"z":7944},{"x":74914,"y":20830,"z":82559},{"x":68530,"y":35265,"z":76156},{"x":82762,"y":4040,"z":99880},{"x":23472,"y":30526,"z":42857},{"x":87759,"y":55861,"z":81598},{"x":1957,"y":63841,"z":57021},{"x":44944,"y":18845,"z":90230},{"x":54251,"y":38708,"z":38260},{"x":8870,"y":753,"z":71611},{"x":81423,"y":5959,"z":45753},{"x":94142,"y":43274,"z":37696},{"x":86379,"y":70304,"z":7891},{"x":44515,"y":72191,"z":1194},{"x":6205,"y":77653,"z":33542},{"x":92967,"y":18453,"z":48577},{"x":7678,"y":67117,"z":32246},{"x":32575,"y":51952,"z":80296},{"x":22384,"y":73600,"z":14490},{"x":52711,"y":30082,"z":25106},{"x":57480,"y":42599,"z":8822},{"x":43114,"y":59009,"z":65318},{"x":15762,"y":17130,"z":11220},{"x":70564,"y":47248,"z":83517},{"x":2121,"y":75358,"z":38760},{"x":35749,"y":33046,"z":52462},{"x":75238,"y":37380,"z":60124},{"x":96192,"y":97611,"z":49292},{"x":97758,"y":97953,"z":72104},{"x":58423,"y":34477,"z":87667},{"x":38902,"y":67350,"z":99834},{"x":42943,"y":30562,"z":94103},{"x":87924,"y":51390,"z":54745},{"x":81506,"y":4822,"z":81958},{"x":53178,"y":12282,"z":19647},{"x":85139,"y":63746,"z":27671},{"x":81487,"y":89072,"z":36336},{"x":6253,"y":25748,"z":86215},{"x":48027,"y":49098,"z":56556},{"x":43576,"y":68684,"z":55894},{"x":18254,"y":6493,"z":84642},{"x":52909,"y":84771,"z":72402},{"x":65560,"y":53513,"z":82375},{"x":81009,"y":57728,"z":62936},{"x":3688,"y":11379,"z":22586},{"x":26035,"y":72184,"z":18309},{"x":35242,"y":7329,"z":55693},{"x":71894,"y":92384,"z":38569},{"x":14615,"y":55929,"z":26218},{"x":26019,"y":15150,"z":17171},{"x":66669,"y":33277,"z":40758},{"x":24931,"y":4862,"z":27660},{"x":75483,"y":86544,"z":67579},{"x":5083,"y":12873,"z":65276},{"x":1313,"y":87524,"z":29121},{"x":286,"y":17310,"z":28052},{"x":31431,"y":78066,"z":80220},{"x":97016,"y":30080,"z":85033},{"x":55036,"y":47034,"z":83591},{"x":29322,"y":15017,"z":27875},{"x":74140,"y":43294,"z":70313},{"x":11167,"y":98589,"z":17524},{"x":98795,"y":81059,"z":18560},{"x":12125,"y":50747,"z":94693},{"x":29937,"y":96225,"z":94110},{"x":35740,"y":63048,"z":74201},{"x":60963,"y":97471,"z":54331},{"x":25085,"y":26113,"z":87315},{"x":79011,"y":55630,"z":79771},{"x":42718,"y":62834,"z":7988},{"x":66051,"y":65078,"z":5058},{"x":69214,"y":22915,"z":92689},{"x":49908,"y":23340,"z":39297},{"x":69887,"y":84399,"z":92649},{"x":78657,"y":85796,"z":70300},{"x":93483,"y":74898,"z":95070},{"x":46907,"y":50571,"z":41782},{"x":70877,"y":41047,"z":48729},{"x":41524,"y":75771,"z":99337},{"x":53466,"y":47701,"z":38633},{"x":12762,"y":44499,"z":22350},{"x":44688,"y":9488,"z":25293},{"x":71430,"y":21562,"z":52514},{"x":66810,"y":36914,"z":96406},{"x":99100,"y":39368,"z":50027},{"x":3160,"y":44565,"z":15249},{"x":63424,"y":89275,"z":68274},{"x":97623,"y":53617,"z":59825},{"x":2322,"y":2086,"z":37512},{"x":40230,"y":51063,"z":69967},{"x":13255,"y":99386,"z":61085},{"x":76434,"y":51331,"z":71427},{"x":20341,"y":71310,"z":18982},{"x":43964,"y":43210,"z":37969},{"x":36453,"y":34957,"z":99037},{"x":33461,"y":99489,"z":89885},{"x":47027,"y":40641,"z":91396},{"x":90242,"y":14775,"z":6617},{"x":77782,"y":57333,"z":73540},{"x":98828,"y":75818,"z":59586},{"x":25833,"y":94734,"z":11049},{"x":23932,"y":92894,"z":49069},{"x":82190,"y":13166,"z":17162},{"x":96342,"y":7060,"z":51505},{"x":31207,"y":39374,"z":141},{"x":63816,"y":76588,"z":17759},{"x":59091,"y":83198,"z":27627},{"x":15102,"y":8698,"z":84051},{"x":13417,"y":49225,"z":56704},{"x":9458,"y":71311,"z":45454},{"x":46120,"y":10697,"z":75585},{"x":78524,"y":87896,"z":27662},{"x":99544,"y":44501,"z":37210},{"x":77089,"y":31087,"z":11164},{"x":19136,"y":55656,"z":28658},{"x":96836,"y":89792,"z":77233},{"x":1573,"y":69768,"z":70774},{"x":34548,"y":4159,"z":64615},{"x":97621,"y":88974,"z":97672},{"x":16412,"y":95340,"z":19485},{"x":6842,"y":70744,"z":21696},{"x":27216,"y":62222,"z":95880},{"x":54156,"y":26578,"z":79466},{"x":40425,"y":6222,"z":41375},{"x":96958,"y":27155,"z":62281},{"x":69478,"y":3232,"z":61554},{"x":12529,"y":31863,"z":2982},{"x":31439,"y":47831,"z":1305},{"x":27766,"y":33929,"z":62205},{"x":28107,"y":15467,"z":47852},{"x":82990,"y":80468,"z":96872},{"x":66036,"y":57413,"z":76555},{"x":12420,"y":63388,"z":22307},{"x":55157,"y":75636,"z":36508},{"x":51115,"y":58706,"z":29691},{"x":49857,"y":40192,"z":53190},{"x":51028,"y":36248,"z":72849},{"x":96395,"y":20052,"z":57260},{"x":94013,"y":71425,"z":47753},{"x":46776,"y":76728,"z":4429},{"x":52826,"y":60416,"z":51781},{"x":82089,"y":73840,"z":90552},{"x":67515,"y":19072,"z":62369},{"x":93647,"y":14133,"z":12132},{"x":86372,"y":9775,"z":77886},{"x":65032,"y":18651,"z":36941},{"x":29189,"y":6126,"z":46728},{"x":91647,"y":15409,"z":23234},{"x":11242,"y":36242,"z":45807},{"x":53248,"y":16864,"z":60107},{"x":71327,"y":27046,"z":9222},{"x":50402,"y":75876,"z":44510},{"x":33404,"y":96699,"z":84855},{"x":45579,"y":83811,"z":17786},{"x":39497,"y":27697,"z":84681},{"x":36596,"y":86508,"z":9225},{"x":58008,"y":26663,"z":48254},{"x":44342,"y":7399,"z":9660},{"x":1899,"y":94854,"z":78032},{"x":55241,"y":41264,"z":65612},{"x":14171,"y":61023,"z":83439},{"x":15896,"y":85118,"z":19571},{"x":26262,"y":92097,"z":60999},{"x":90827,"y":51591,"z":55977},{"x":2986,"y":30523,"z":93726},{"x":46290,"y":64597,"z":98545},{"x":69550,"y":43907,"z":46248},{"x":14666,"y":65895,"z":65914},{"x":83466,"y":3766,"z":45688},{"x":92475,"y":98128,"z":98120},{"x":14468,"y":1300,"z":83791},{"x":42359,"y":56603,"z":13864},{"x":1998,"y":87292,"z":30935},{"x":30636,"y":21447,"z":4608},{"x":10281,"y":80457,"z":60591},{"x":5927,"y":61652,"z":33198},{"x":84792,"y":90194,"z":23668},{"x":21375,"y":39200,"z":63981},{"x":26148,"y":2563,"z":59453},{"x":3878,"y":71863,"z":32303},{"x":24688,"y":40615,"z":21628},{"x":39305,"y":95887,"z":5211},{"x":77164,"y":28994,"z":894},{"x":60900,"y":79225,"z":35865},{"x":83313,"y":55862,"z":45365},{"x":93289,"y":62769,"z":33883},{"x":78270,"y":54992,"z":59444},{"x":78875,"y":24007,"z":44581},{"x":6586,"y":98225,"z":43721},{"x":7609,"y":14475,"z":55643},{"x":52655,"y":19354,"z":1554},{"x":90896,"y":48830,"z":55935},{"x":79908,"y":38414,"z":98854},{"x":56763,"y":69447,"z":14243},{"x":20261,"y":3353,"z":28051},{"x":48847,"y":25039,"z":69183},{"x":73095,"y":27262,"z":96065},{"x":83789,"y":46377,"z":66387},{"x":28015,"y":18283,"z":30259},{"x":92510,"y":84207,"z":68258},{"x":68858,"y":44507,"z":25847},{"x":51411,"y":84735,"z":80122},{"x":24991,"y":5280,"z":32444},{"x":47479,"y":24448,"z":5575},{"x":9688,"y":93891,"z":63995},{"x":93516,"y":32229,"z":95595},{"x":49792,"y":8956,"z":75349},{"x":82466,"y":2659,"z":42943},{"x":84831,"y":76883,"z":60572},{"x":17885,"y":26212,"z":32434},{"x":72426,"y":43039,"z":45242},{"x":38540,"y":73027,"z":74988},{"x":75250,"y":83395,"z":25528},{"x":60282,"y":63543,"z":61072},{"x":16881,"y":25850,"z":35010},{"x":4519,"y":87097,"z":63686},{"x":47418,"y":98765,"z":14632},{"x":82891,"y":70986,"z":16303},{"x":1366,"y":54258,"z":91108},{"x":46829,"y":42539,"z":81531},{"x":54600,"y":7812,"z":3535},{"x":7137,"y":68680,"z":1136},{"x":88358,"y":8124,"z":599},{"x":69247,"y":88524,"z":96202},{"x":92311,"y":35169,"z":68307},{"x":91805,"y":96856,"z":32492},{"x":27952,"y":60153,"z":4739},{"x":30620,"y":3652,"z":43088},{"x":73324,"y":88130,"z":7501},{"x":86253,"y":9120,"z":62975},{"x":85991,"y":90883,"z":11260},{"x":26466,"y":18263,"z":33451},{"x":39237,"y":61569,"z":79497},{"x":37689,"y":90031,"z":38342},{"x":34696,"y":18264,"z":9226},{"x":45350,"y":47447,"z":78459},{"x":62677,"y":45853,"z":74744},{"x":57411,"y":67900,"z":45868},{"x":7048,"y":66892,"z":23560},{"x":87734,"y":35737,"z":27665},{"x":61109,"y":48318,"z":39804},{"x":36411,"y":27,"z":28578},{"x":6227,"y":24921,"z":9488},{"x":53477,"y":26195,"z":86182},{"x":77449,"y":71240,"z":84188},{"x":38630,"y":98127,"z":69702},{"x":99055,"y":60171,"z":99999},{"x":83349,"y":97372,"z":85844},{"x":39341,"y":86407,"z":75472},{"x":47680,"y":96358,"z":89076},{"x":2527,"y":71367,"z":872},{"x":30127,"y":11915,"z":92875},{"x":27824,"y":89266,"z":39931},{"x":38712,"y":86498,"z":96990},{"x":81776,"y":27828,"z":54759},{"x":63372,"y":15940,"z":11399},{"x":6071,"y":66057,"z":84756},{"x":11294,"y":44057,"z":62574},{"x":35475,"y":49648,"z":234},{"x":24252,"y":10872,"z":63749},{"x":63614,"y":91455,"z":75505},{"x":98426,"y":38129,"z":43879},{"x":31629,"y":13292,"z":31049},{"x":17440,"y":64268,"z":44872},{"x":55257,"y":18709,"z":72695},{"x":96667,"y":64655,"z":65603},{"x":16652,"y":52245,"z":63140},{"x":54593,"y":16042,"z":75859},{"x":62373,"y":68010,"z":91287},{"x":14761,"y":50102,"z":47525},{"x":48995,"y":93258,"z":52452},{"x":35039,"y":36326,"z":85135},{"x":53151,"y":19858,"z":18208},{"x":66066,"y":14395,"z":2972},{"x":69065,"y":88336,"z":55024},{"x":94201,"y":5660,"z":82690},{"x":16758,"y":45854,"z":30312},{"x":86733,"y":56045,"z":24153},{"x":60422,"y":75296,"z":63216},{"x":55152,"y":16869,"z":38967},{"x":40203,"y":10071,"z":52315},{"x":24979,"y":79489,"z":22106},{"x":62418,"y":36395,"z":28813},{"x":36002,"y":25787,"z":36541},{"x":5398,"y":67134,"z":19608},{"x":45567,"y":29666,"z":99903},{"x":10198,"y":53619,"z":78720},{"x":48266,"y":94275,"z":32975},{"x":44723,"y":73473,"z":86109},{"x":71654,"y":10515,"z":46265},{"x":96533,"y":99156,"z":95256},{"x":20173,"y":16315,"z":46171},{"x":55137,"y":67991,"z":2808},{"x":3277,"y":59718,"z":20458},{"x":24998,"y":86919,"z":72481},{"x":31496,"y":67973,"z":16417},{"x":96712,"y":1737,"z":48781},{"x":74575,"y":64801,"z":96462},{"x":87339,"y":2057,"z":43083},{"x":47263,"y":89361,"z":36045},{"x":45953,"y":81799,"z":84544},{"x":85626,"y":35456,"z":62954},{"x":69021,"y":66867,"z":67040},{"x":68578,"y":93277,"z":41488},{"x":2494,"y":14008,"z":27502},{"x":94737,"y":79155,"z":20947},{"x":8300,"y":95363,"z":14661},{"x":4261,"y":1566,"z":36906},{"x":61289,"y":70259,"z":4340},{"x":12951,"y":58498,"z":60371},{"x":97025,"y":16001,"z":79457},{"x":98406,"y":60266,"z":21369},{"x":23175,"y":202,"z":97114},{"x":63765,"y":71722,"z":25127},{"x":80262,"y":89066,"z":48532},{"x":10178,"y":50750,"z":60284},{"x":73012,"y":51122,"z":73821},{"x":71962,"y":85888,"z":29954},{"x":49604,"y":27436,"z":3498},{"x":33824,"y":41959,"z":18841},{"x":65525,"y":44351,"z":33838},{"x":19647,"y":44807,"z":75944},{"x":18365,"y":17396,"z":48109},{"x":12342,"y":62941,"z":32471},{"x":19433,"y":88248,"z":31068},{"x":53830,"y":61194,"z":20751},{"x":50327,"y":80044,"z":70438},{"x":47479,"y":82735,"z":53545},{"x":86533,"y":36374,"z":88149},{"x":76215,"y":10963,"z":7959},{"x":95856,"y":68203,"z":69083},{"x":44406,"y":82301,"z":90909},{"x":75945,"y":41115,"z":32836},{"x":75323,"y":64386,"z":3301},{"x":76595,"y":43267,"z":62186},{"x":71018,"y":80419,"z":60598},{"x":36152,"y":87027,"z":46004},{"x":82895,"y":60201,"z":73317},{"x":21221,"y":20024,"z":32799},{"x":30839,"y":36544,"z":19137},{"x":50665,"y":7076,"z":16737},{"x":85144,"y":25721,"z":53984},{"x":77746,"y":44861,"z":87239},{"x":29612,"y":18252,"z":73085},{"x":63340,"y":8179,"z":74011},{"x":94270,"y":58535,"z":51866},{"x":63687,"y":25565,"z":45329},{"x":42012,"y":17325,"z":65275},{"x":79074,"y":21032,"z":39506},{"x":97103,"y":92135,"z":77620},{"x":42475,"y":76269,"z":40353},{"x":79254,"y":74928,"z":93712},{"x":24498,"y":82815,"z":95878},{"x":24267,"y":44573,"z":4849},{"x":80452,"y":22788,"z":84351},{"x":86115,"y":97837,"z":17072},{"x":6138,"y":63056,"z":38463},{"x":21903,"y":56589,"z":68556},{"x":14741,"y":63246,"z":33703},{"x":22351,"y":52367,"z":5528},{"x":53539,"y":47613,"z":94853},{"x":44785,"y":38786,"z":14171},{"x":88087,"y":94500,"z":56183},{"x":73700,"y":2726,"z":3842},{"x":16250,"y":73010,"z":1209},{"x":55705,"y":14057,"z":73268},{"x":59932,"y":40685,"z":24530},{"x":92494,"y":20475,"z":37609},{"x":91863,"y":64924,"z":42834},{"x":46489,"y":61374,"z":49425},{"x":94363,"y":39872,"z":55202},{"x":13410,"y":98087,"z":45172},{"x":22051,"y":11324,"z":45962},{"x":44849,"y":25662,"z":88491},{"x":75769,"y":63796,"z":1104},{"x":65563,"y":73886,"z":19426},{"x":71046,"y":47690,"z":95322},{"x":74551,"y":83083,"z":69651},{"x":8615,"y":4078,"z":32306},{"x":77226,"y":21601,"z":16840},{"x":92787,"y":80265,"z":48396},{"x":65273,"y":45058,"z":4977},{"x":42226,"y":7234,"z":80530},{"x":32766,"y":81532,"z":34163},{"x":83798,"y":3241,"z":84369},{"x":38469,"y":67001,"z":76815},{"x":1894,"y":88267,"z":7920},{"x":45806,"y":45132,"z":89732},{"x":30945,"y":91180,"z":87272},{"x":1006,"y":55022,"z":65523},{"x":46291,"y":77146,"z":7658},{"x":60054,"y":55561,"z":86698},{"x":19915,"y":80670,"z":65432},{"x":56270,"y":14003,"z":18444},{"x":30490,"y":99328,"z":26538},{"x":37477,"y":78725,"z":5663},{"x":85532,"y":9745,"z":63388},{"x":57982,"y":50202,"z":93462},{"x":15320,"y":29847,"z":5357},{"x":49269,"y":86040,"z":48487},{"x":57114,"y":68294,"z":82371},{"x":95011,"y":61493,"z":60676},{"x":32850,"y":78313,"z":74952},{"x":12425,"y":24856,"z":59986},{"x":61739,"y":94986,"z":51353},{"x":25916,"y":38678,"z":93921},{"x":14719,"y":91750,"z":8822},{"x":70751,"y":25157,"z":31902},{"x":17034,"y":9440,"z":41006},{"x":18664,"y":82908,"z":58921},{"x":36354,"y":22416,"z":73832},{"x":64615,"y":82081,"z":20657},{"x":2180,"y":53837,"z":43929},{"x":71746,"y":26827,"z":47862},{"x":35313,"y":46818,"z":29867},{"x":63995,"y":83312,"z":62542},{"x":26389,"y":18027,"z":38909},{"x":89290,"y":58554,"z":65877},{"x":72755,"y":9306,"z":67463},{"x":34796,"y":76540,"z":91702},{"x":28031,"y":92356,"z":38544},{"x":24223,"y":56569,"z":15528},{"x":76978,"y":72802,"z":49103},{"x":33532,"y":12892,"z":20891},{"x":4541,"y":85088,"z":8174},{"x":1527,"y":12502,"z":12337},{"x":15927,"y":71127,"z":5248},{"x":96299,"y":18029,"z":68425},{"x":52808,"y":90723,"z":37783},{"x":92606,"y":60196,"z":77969},{"x":55899,"y":73686,"z":52560},{"x":23919,"y":13265,"z":86545},{"x":58996,"y":69280,"z":19651},{"x":51013,"y":16113,"z":1727},{"x":71789,"y":30209,"z":56287},{"x":71296,"y":92980,"z":91882},{"x":33408,"y":92160,"z":76319},{"x":42048,"y":10919,"z":83857},{"x":28792,"y":74297,"z":86478},{"x":5389,"y":75937,"z":81049},{"x":79159,"y":44718,"z":95910},{"x":77812,"y":6109,"z":6903},{"x":11429,"y":2081,"z":46678},{"x":28728,"y":57702,"z":40446},{"x":85490,"y":69973,"z":11074},{"x":18985,"y":5870,"z":9670},{"x":41900,"y":64465,"z":86223},{"x":64031,"y":20749,"z":69030},{"x":19968,"y":63958,"z":89442},{"x":7769,"y":52832,"z":45916},{"x":95865,"y":7808,"z":98612},{"x":39867,"y":62263,"z":12449},{"x":83497,"y":47866,"z":75410},{"x":82557,"y":53917,"z":16242},{"x":9807,"y":26078,"z":60255},{"x":15042,"y":22029,"z":69166},{"x":30024,"y":51812,"z":46565},{"x":92338,"y":60566,"z":9364},{"x":57715,"y":22310,"z":11197},{"x":97140,"y":46213,"z":37849},{"x":74647,"y":55761,"z":78801},{"x":6299,"y":96259,"z":38989},{"x":40357,"y":37111,"z":41316},{"x":30968,"y":92364,"z":46696},{"x":76414,"y":51273,"z":99009},{"x":7118,"y":39225,"z":38640},{"x":17737,"y":14009,"z":58457},{"x":39944,"y":3341,"z":30639},{"x":84410,"y":19567,"z":41648},{"x":15931,"y":44298,"z":65121},{"x":79307,"y":94793,"z":80987},{"x":952,"y":58766,"z":5923},{"x":69268,"y":84830,"z":19869},{"x":51994,"y":80483,"z":45526},{"x":32711,"y":76202,"z":36436},{"x":71893,"y":59114,"z":79883},{"x":99066,"y":65336,"z":68361},{"x":41506,"y":31715,"z":45108},{"x":82661,"y":73919,"z":50362},{"x":86802,"y":61113,"z":87896},{"x":80840,"y":25948,"z":71017},{"x":37009,"y":56980,"z":26364},{"x":75120,"y":7694,"z":92969},{"x":64429,"y":15686,"z":26000},{"x":46498,"y":72376,"z":35606},{"x":86689,"y":27004,"z":55646},{"x":4210,"y":73749,"z":54409},{"x":98698,"y":23473,"z":57220},{"x":10744,"y":80544,"z":68264},{"x":87968,"y":61897,"z":73680},{"x":52729,"y":8385,"z":35266},{"x":18864,"y":31204,"z":87105},{"x":86199,"y":81893,"z":5053},{"x":24062,"y":50963,"z":68619},{"x":61890,"y":58242,"z":84398},{"x":20147,"y":67830,"z":14430},{"x":98776,"y":33533,"z":40129},{"x":12323,"y":27694,"z":64221},{"x":72068,"y":17313,"z":20441},{"x":7514,"y":65746,"z":67963},{"x":52487,"y":28248,"z":54826},{"x":71958,"y":4904,"z":93581},{"x":98092,"y":16710,"z":97076},{"x":54744,"y":77145,"z":9758},{"x":44623,"y":43540,"z":95666},{"x":9774,"y":88326,"z":80075},{"x":12941,"y":63893,"z":95040},{"x":94286,"y":36626,"z":59162},{"x":51358,"y":17484,"z":86901},{"x":40056,"y":64515,"z":77119},{"x":87783,"y":80188,"z":43564},{"x":98201,"y":84610,"z":75208},{"x":61098,"y":97658,"z":6479},{"x":86959,"y":5239,"z":38368},{"x":73286,"y":38785,"z":89091},{"x":23913,"y":59499,"z":26416},{"x":25602,"y":57654,"z":72854},{"x":63260,"y":85932,"z":86084},{"x":13537,"y":48315,"z":73193},{"x":19335,"y":11368,"z":43913},{"x":83423,"y":60937,"z":37261},{"x":9313,"y":47305,"z":36979},{"x":723,"y":518,"z":67639},{"x":46040,"y":85305,"z":22039},{"x":31475,"y":33436,"z":47686},{"x":31640,"y":79385,"z":76978},{"x":27354,"y":39004,"z":31931},{"x":62329,"y":20080,"z":37076},{"x":81285,"y":85346,"z":48141},{"x":12914,"y":98357,"z":15867},{"x":97984,"y":34251,"z":11049},{"x":12225,"y":26767,"z":39580},{"x":88412,"y":31758,"z":79197},{"x":14614,"y":36309,"z":35051},{"x":84857,"y":60361,"z":669},{"x":51578,"y":50383,"z":82234}]; 321 322 // Normalize coordinates to fit in view 323 const maxCoord = Math.max(...junctions.flatMap(j => [j.x, j.y, j.z])); 324 const scale = 20 / maxCoord; 325 326 // Calculate all pairwise distances 327 function distance(a, b) { 328 return Math.sqrt( 329 (a.x - b.x) ** 2 + 330 (a.y - b.y) ** 2 + 331 (a.z - b.z) ** 2 332 ); 333 } 334 335 const pairs = []; 336 for (let i = 0; i < junctions.length; i++) { 337 for (let j = i + 1; j < junctions.length; j++) { 338 pairs.push({ 339 i, 340 j, 341 distance: distance(junctions[i], junctions[j]) 342 }); 343 } 344 } 345 346 // Sort by distance 347 pairs.sort((a, b) => a.distance - b.distance); 348 349 // Union-Find for circuit tracking 350 class UnionFind { 351 constructor(n) { 352 this.parent = Array.from({ length: n }, (_, i) => i); 353 this.size = Array(n).fill(1); 354 } 355 356 find(x) { 357 if (this.parent[x] !== x) { 358 this.parent[x] = this.find(this.parent[x]); 359 } 360 return this.parent[x]; 361 } 362 363 union(x, y) { 364 const rootX = this.find(x); 365 const rootY = this.find(y); 366 367 if (rootX === rootY) return false; 368 369 if (this.size[rootX] < this.size[rootY]) { 370 this.parent[rootX] = rootY; 371 this.size[rootY] += this.size[rootX]; 372 } else { 373 this.parent[rootY] = rootX; 374 this.size[rootX] += this.size[rootY]; 375 } 376 377 return true; 378 } 379 380 getCircuitSizes() { 381 const circuits = new Map(); 382 for (let i = 0; i < this.parent.length; i++) { 383 const root = this.find(i); 384 circuits.set(root, this.size[root]); 385 } 386 return Array.from(circuits.values()).sort((a, b) => b - a); 387 } 388 389 getCircuitCount() { 390 const roots = new Set(); 391 for (let i = 0; i < this.parent.length; i++) { 392 roots.add(this.find(i)); 393 } 394 return roots.size; 395 } 396 } 397 398 // Build animation stages for Part 1 (first 1000 connections) and Part 2 (until single circuit) 399 const stages = []; 400 const uf = new UnionFind(junctions.length); 401 const connections = []; 402 let part2ConnectionIndex = -1; 403 let part2Product = 0; 404 405 let step = 0; 406 while (true) { 407 const circuitSizes = uf.getCircuitSizes(); 408 const top3 = circuitSizes.slice(0, 3); 409 const product = top3.length >= 3 ? top3[0] * top3[1] * top3[2] : 0; 410 const circuitCount = uf.getCircuitCount(); 411 412 stages.push({ 413 connections: [...connections], 414 circuits: circuitCount, 415 largest: circuitSizes[0] || 1, 416 product, 417 circuitSizes: [...circuitSizes], 418 part2Product: part2Product 419 }); 420 421 // Check if we've reached a single circuit (Part 2 complete) 422 if (circuitCount === 1 && part2ConnectionIndex === -1) { 423 part2ConnectionIndex = step - 1; // The previous connection completed it 424 if (part2ConnectionIndex >= 0) { 425 const lastPair = pairs[part2ConnectionIndex]; 426 part2Product = junctions[lastPair.i].x * junctions[lastPair.j].x; 427 } 428 // Update the current stage with the part2Product 429 stages[stages.length - 1].part2Product = part2Product; 430 } 431 432 // Stop after reaching single circuit, or if we've exhausted pairs 433 if (circuitCount === 1 || step >= pairs.length) { 434 break; 435 } 436 437 const pair = pairs[step]; 438 uf.union(pair.i, pair.j); 439 connections.push(pair); 440 step++; 441 } 442 443 console.log('Part 1: After 1000 connections, product =', stages[Math.min(1000, stages.length - 1)].product); 444 console.log('Part 2: Single circuit at connection', part2ConnectionIndex, ', product =', part2Product); 445 446 // Three.js setup 447 const scene = new THREE.Scene(); 448 scene.background = new THREE.Color(0x0d0d15); 449 450 const camera = new THREE.PerspectiveCamera( 451 75, 452 window.innerWidth / window.innerHeight, 453 0.1, 454 1000 455 ); 456 camera.position.set(15, 15, 15); 457 458 const renderer = new THREE.WebGLRenderer({ 459 canvas: document.getElementById('canvas'), 460 antialias: true 461 }); 462 renderer.setSize(window.innerWidth, window.innerHeight); 463 renderer.setPixelRatio(window.devicePixelRatio); 464 465 const controls = new OrbitControls(camera, renderer.domElement); 466 controls.enableDamping = true; 467 controls.dampingFactor = 0.05; 468 controls.target.set(0, 3, 0); // Shift the view down by 3 units 469 controls.autoRotate = true; 470 controls.autoRotateSpeed = 0.5; // Slow rotation (0.5 degrees per frame at 60fps = 30 seconds per rotation) 471 controls.update(); 472 473 // Lighting 474 const ambientLight = new THREE.AmbientLight(0xffffff, 0.4); 475 scene.add(ambientLight); 476 477 const pointLight1 = new THREE.PointLight(0xffffff, 0.6); 478 pointLight1.position.set(10, 10, 10); 479 scene.add(pointLight1); 480 481 const pointLight2 = new THREE.PointLight(0xffffff, 0.4); 482 pointLight2.position.set(-10, -10, -10); 483 scene.add(pointLight2); 484 485 // Create junction boxes (smaller) 486 const junctionGeometry = new THREE.SphereGeometry(0.1, 12, 12); 487 const junctionMaterial = new THREE.MeshPhongMaterial({ 488 color: 0x89b4fa, 489 emissive: 0x89b4fa, 490 emissiveIntensity: 0.2 491 }); 492 493 const junctionMeshes = junctions.map((j, idx) => { 494 const mesh = new THREE.Mesh(junctionGeometry, junctionMaterial); 495 mesh.position.set( 496 (j.x * scale) - 10, 497 (j.y * scale) - 10, 498 (j.z * scale) - 10 499 ); 500 mesh.userData.index = idx; 501 scene.add(mesh); 502 return mesh; 503 }); 504 505 // Connection lines - pre-render all cylinders (enough to reach single circuit) 506 let connectionCylinders = []; 507 508 // Determine how many connections we need (until single circuit) 509 const maxConnections = Math.min(pairs.length, stages[stages.length - 1].connections.length); 510 511 // Pre-create all connection cylinders 512 console.log('Pre-rendering', maxConnections, 'connections...'); 513 pairs.slice(0, maxConnections).forEach((pair, idx) => { 514 const j1 = junctions[pair.i]; 515 const j2 = junctions[pair.j]; 516 517 const p1 = new THREE.Vector3( 518 (j1.x * scale) - 10, 519 (j1.y * scale) - 10, 520 (j1.z * scale) - 10 521 ); 522 const p2 = new THREE.Vector3( 523 (j2.x * scale) - 10, 524 (j2.y * scale) - 10, 525 (j2.z * scale) - 10 526 ); 527 528 // Create cylinder between points 529 const direction = new THREE.Vector3().subVectors(p2, p1); 530 const length = direction.length(); 531 const cylinderGeometry = new THREE.CylinderGeometry(0.015, 0.015, length, 4); 532 const cylinderMaterial = new THREE.MeshBasicMaterial({ 533 transparent: true, 534 opacity: 0.8 535 }); 536 537 const cylinder = new THREE.Mesh(cylinderGeometry, cylinderMaterial); 538 539 // Position at midpoint 540 cylinder.position.copy(p1).add(direction.multiplyScalar(0.5)); 541 542 // Orient cylinder to connect the two points 543 cylinder.quaternion.setFromUnitVectors( 544 new THREE.Vector3(0, 1, 0), 545 direction.normalize() 546 ); 547 548 // Initially invisible 549 cylinder.visible = false; 550 cylinder.userData.pairIndex = idx; 551 cylinder.userData.i = pair.i; 552 cylinder.userData.j = pair.j; 553 554 scene.add(cylinder); 555 connectionCylinders.push(cylinder); 556 }); 557 console.log('Pre-rendering complete!'); 558 559 // Pre-generate stable colors for each junction based on their index 560 const junctionColors = []; 561 const hues = []; 562 for (let i = 0; i < junctions.length; i++) { 563 const hue = (i * 137.508) % 360; // Golden angle for good distribution 564 junctionColors.push(new THREE.Color().setHSL(hue / 360, 0.8, 0.55)); 565 } 566 567 function updateConnections(stage) { 568 const numConnections = stage.connections.length; 569 570 if (numConnections === 0) { 571 // No connections yet - make all junctions small and hide all cylinders 572 junctionMeshes.forEach(mesh => { 573 mesh.scale.set(0.33, 0.33, 0.33); 574 mesh.material = new THREE.MeshPhongMaterial({ 575 color: 0x89b4fa, 576 emissive: 0x89b4fa, 577 emissiveIntensity: 0.2 578 }); 579 }); 580 connectionCylinders.forEach(cyl => cyl.visible = false); 581 return; 582 } 583 584 // Color junctions by circuit - use lowest junction index as stable color 585 const uf = new UnionFind(junctions.length); 586 stage.connections.forEach(conn => uf.union(conn.i, conn.j)); 587 588 // Map each root to the lowest junction index in that circuit for stable colors 589 const circuitColors = new Map(); 590 for (let i = 0; i < junctions.length; i++) { 591 const root = uf.find(i); 592 if (!circuitColors.has(root)) { 593 // Find the lowest index in this circuit 594 let lowestInCircuit = i; 595 for (let j = 0; j < i; j++) { 596 if (uf.find(j) === root) { 597 lowestInCircuit = j; 598 break; 599 } 600 } 601 circuitColors.set(root, junctionColors[lowestInCircuit]); 602 } 603 } 604 605 // Track which junctions are connected 606 const connectedJunctions = new Set(); 607 stage.connections.forEach(conn => { 608 connectedJunctions.add(conn.i); 609 connectedJunctions.add(conn.j); 610 }); 611 612 junctionMeshes.forEach((mesh, idx) => { 613 const root = uf.find(idx); 614 const color = circuitColors.get(root); 615 616 mesh.material = new THREE.MeshPhongMaterial({ 617 color: color, 618 emissive: color, 619 emissiveIntensity: 0.4 620 }); 621 622 // Make unconnected junctions smaller 623 if (connectedJunctions.has(idx)) { 624 mesh.scale.set(1, 1, 1); 625 } else { 626 mesh.scale.set(0.33, 0.33, 0.33); 627 } 628 }); 629 630 // Show/hide cylinders and update their colors based on current stage 631 connectionCylinders.forEach((cylinder, idx) => { 632 if (idx < numConnections) { 633 cylinder.visible = true; 634 // Update color to match circuit 635 const root = uf.find(cylinder.userData.i); 636 const lineColor = circuitColors.get(root); 637 cylinder.material.color = lineColor; 638 } else { 639 cylinder.visible = false; 640 } 641 }); 642 } 643 644 // Animation state 645 let currentStage = 0; 646 let isPlaying = false; 647 let lastTime = 0; 648 649 const playBtn = document.getElementById('play'); 650 const prevBtn = document.getElementById('prev'); 651 const nextBtn = document.getElementById('next'); 652 const resetBtn = document.getElementById('reset'); 653 const timelineSlider = document.getElementById('timeline'); 654 const timelineStep = document.getElementById('timelineStep'); 655 const statsInfo = document.getElementById('statsInfo'); 656 657 function updateUI() { 658 const stage = stages[currentStage]; 659 timelineStep.textContent = `Step ${currentStage} of ${stages.length - 1}`; 660 661 const part1Result = stages[Math.min(1000, stages.length - 1)].product; 662 const part2Result = stage.part2Product || 0; 663 664 statsInfo.textContent = `Circuits: ${stage.circuits} | Largest: ${stage.largest} | Part 1: ${part1Result.toLocaleString()} | Part 2: ${part2Result.toLocaleString()}`; 665 666 prevBtn.disabled = currentStage === 0; 667 nextBtn.disabled = currentStage === stages.length - 1; 668 669 // Update timeline slider and gradient 670 timelineSlider.value = currentStage; 671 const percent = (currentStage / (stages.length - 1)) * 100; 672 timelineSlider.style.background = `linear-gradient(to right, #a6e3a1 0%, #a6e3a1 ${percent}%, #313244 ${percent}%, #313244 100%)`; 673 674 updateConnections(stage); 675 } 676 677 function goToStage(index) { 678 currentStage = Math.max(0, Math.min(stages.length - 1, index)); 679 updateUI(); 680 } 681 682 prevBtn.addEventListener('click', () => goToStage(currentStage - 1)); 683 nextBtn.addEventListener('click', () => goToStage(currentStage + 1)); 684 resetBtn.addEventListener('click', () => goToStage(0)); 685 686 // Timeline slider scrubbing 687 timelineSlider.addEventListener('input', (e) => { 688 goToStage(parseInt(e.target.value)); 689 }); 690 691 playBtn.addEventListener('click', () => { 692 isPlaying = !isPlaying; 693 playBtn.textContent = isPlaying ? '⏸ Pause' : '▶ Play'; 694 if (isPlaying && currentStage === stages.length - 1) { 695 goToStage(0); 696 } 697 }); 698 699 document.addEventListener('keydown', (e) => { 700 if (e.key === 'ArrowLeft') prevBtn.click(); 701 if (e.key === 'ArrowRight') nextBtn.click(); 702 if (e.key === ' ') { 703 e.preventDefault(); 704 playBtn.click(); 705 } 706 if (e.key === 'r' || e.key === 'R') resetBtn.click(); 707 }); 708 709 window.addEventListener('resize', () => { 710 camera.aspect = window.innerWidth / window.innerHeight; 711 camera.updateProjectionMatrix(); 712 renderer.setSize(window.innerWidth, window.innerHeight); 713 }); 714 715 // Animation loop 716 function animate(time) { 717 requestAnimationFrame(animate); 718 719 // Auto-advance if playing (zero delay - advance every frame) 720 if (isPlaying) { 721 if (currentStage < stages.length - 1) { 722 goToStage(currentStage + 1); 723 } else { 724 isPlaying = false; 725 playBtn.textContent = '▶ Play'; 726 } 727 } 728 729 controls.update(); 730 renderer.render(scene, camera); 731 } 732 733 // Initialize - start at step 0 734 currentStage = 0; 735 updateUI(); 736 animate(0); 737 </script> 738</body> 739</html>