<< problem 577 - Counting hexagons | Concave triangle - problem 587 >> |
Problem 581: 47-smooth triangular numbers
(see projecteuler.net/problem=581)
A number is p-smooth if it has no prime factors larger than p.
Let T be the sequence of triangular numbers, ie T(n)=n(n+1)/2.
Find the sum of all indices n such that T(n) is 47-smooth.
My Algorithm
If a triangular number T(n) = n (n+1) / 2 is 47-smooth then n and n+1 must be 47-smooth, too.
In order to solve the problem I have to find all consecutive 47-smooth numbers n and n+1.
After having solved problem 563, I suddenly realized that a similar approach works for this problem, too:
- generate all 47-smooth numbers 2^a * 3^b * 5^c * 7^d * 11^e * 13^f * 17^g * 19^h * 23^i * 29^j * 31^k * 37^l * 41^m * 43^n * 47^o
- store them in a min-heap and always retrieve the smallest one
- if it's the successor of the value previously picked from the min-heap then another triangular number T(n-1) was found (same as T(last))
I have no clue what the largest 47-smooth triangular number is.
Within less than 3 seconds my program extracts more than 1500 triangular 47-smooth numbers - and then it seems there are no more such numbers.
After a while I aborted the search and hoped for the best ... and I was right, there are no more numbers.
In the code below you find two manually added constants:
- the program "knows" that it must stop after it analyzed the 10 millionth 47-smooth number (see
iterations
) - the program "knows" that there are no solutions beyond 1111111111111 (see
if (todo < 1111111111111ULL) next.push(todo)
)
There are slightly more optimal values but I decided to go for "nice looking" ones.
Alternative Approaches
I never heard of Størmer's theorem (see en.wikipedia.org/wiki/StÃ¸rmer's_theorem) but it can be used to solve this problem.
Moreover, OEIS A117581 contains the limits for various primes - the 15th entry on the list is 1109496723126 (47 is the 15th prime).
Interactive test
You can submit your own input to my program and it will be instantly processed at my server:
This is equivalent toecho 3 | ./581
Output:
Note: the original problem's input 47
cannot be entered
because just copying results is a soft skill reserved for idiots.
(this interactive test is still under development, computations will be aborted after one second)
My code
… was written in C++11 and can be compiled with G++, Clang++, Visual C++. You can download it, too.
#include <iostream>
#include <vector>
#include <deque>
#include <queue>
#include <functional>
int main()
{
unsigned int limit = 47;
std::cin >> limit;
// primes <= 47 in descending order
std::vector<unsigned int> primes = { 47,43,41,37,31,29,23,19,17,13,11,7,5,3,2 };
// remove large prime depending on user input
while (!primes.empty() && primes.front() > limit)
primes.erase(primes.begin());
// min-heap
std::priority_queue<unsigned long long, std::vector<unsigned long long>, std::greater<unsigned long long>> next;
// "seed" value
next.push(1);
// will store the final result
unsigned long long sum = 0;
// 47-smooth number from previous iteration
unsigned long long last = 1; // must not be zero, any other value is fine
// I saw in my first runs that no solutions were found beyond the 10 millionth 47-smooth number
for (unsigned int iteration = 0; iteration < 10000000; iteration++)
{
// fetch next 47-smooth number
auto current = next.top();
next.pop();
// two consecutive 47-smooth numbers ? => T(last) is 47-smooth, too
if (last + 1 == current)
{
sum += last;
//std::cout << "T(" << last << "), sum=" << sum << " @ iteration " << iterations << " " << next.size() << std::endl;
}
// remember for next iteration
last = current;
// find further 47-smooth numbers
for (auto p : primes)
{
auto todo = current * p;
// heuristic: ignore numbers beyond the largest 47-smooth T(n)
if (todo < 1111111111111ULL)
next.push(todo);
// any prime smaller than the largest prime yields a number already found in "next"
if (current % p == 0)
break;
}
}
std::cout << sum << std::endl;
return 0;
}
This solution contains 12 empty lines, 14 comments and 5 preprocessor commands.
Benchmark
The correct solution to the original Project Euler problem was found in 2.7 seconds on an Intel® Core™ i7-2600K CPU @ 3.40GHz.
Peak memory usage was about 68 MByte.
(compiled for x86_64 / Linux, GCC flags: -O3 -march=native -fno-exceptions -fno-rtti -std=gnu++11 -DORIGINAL
)
See here for a comparison of all solutions.
Note: interactive tests run on a weaker (=slower) computer. Some interactive tests are compiled without -DORIGINAL
.
Changelog
October 12, 2017 submitted solution
October 12, 2017 added comments
Difficulty
Project Euler ranks this problem at 25% (out of 100%).
Links
projecteuler.net/thread=581 - the best forum on the subject (note: you have to submit the correct solution first)
Code in various languages:
Python github.com/smacke/project-euler/blob/master/python/581.py (written by Stephen Macke)
C++ github.com/evilmucedin/project-euler/blob/master/euler581/581.cpp (written by Den Raskovalov)
C++ github.com/roosephu/project-euler/blob/master/581.cpp (written by Yuping Luo)
Those links are just an unordered selection of source code I found with a semi-automatic search script on Google/Bing/GitHub/whatever.
You will probably stumble upon better solutions when searching on your own. Maybe not all linked resources produce the correct result and/or exceed time/memory limits.
Heatmap
Please click on a problem's number to open my solution to that problem:
green | solutions solve the original Project Euler problem and have a perfect score of 100% at Hackerrank, too | |
yellow | solutions score less than 100% at Hackerrank (but still solve the original problem easily) | |
gray | problems are already solved but I haven't published my solution yet | |
blue | solutions are relevant for Project Euler only: there wasn't a Hackerrank version of it (at the time I solved it) or it differed too much | |
orange | problems are solved but exceed the time limit of one minute or the memory limit of 256 MByte | |
red | problems are not solved yet but I wrote a simulation to approximate the result or verified at least the given example - usually I sketched a few ideas, too | |
black | problems are solved but access to the solution is blocked for a few days until the next problem is published | |
[new] | the flashing problem is the one I solved most recently |
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 |
51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 |
76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 |
101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 |
126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 |
151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 |
176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 |
201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 |
226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 |
251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 |
276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 |
301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 |
326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 |
351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 |
376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 |
401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 |
426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 |
451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 |
476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 |
501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 |
526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 |
551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 |
576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 |
601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 |
626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 |
I scored 13526 points (out of 15700 possible points, top rank was 17 out of ≈60000 in August 2017) at Hackerrank's Project Euler+.
My username at Project Euler is stephanbrumme while it's stbrumme at Hackerrank.
Look at my progress and performance pages to get more details.
Copyright
I hope you enjoy my code and learn something - or give me feedback how I can improve my solutions.
All of my solutions can be used for any purpose and I am in no way liable for any damages caused.
You can even remove my name and claim it's yours. But then you shall burn in hell.
The problems and most of the problems' images were created by Project Euler.
Thanks for all their endless effort !!!
<< problem 577 - Counting hexagons | Concave triangle - problem 587 >> |