Thread: burmuda triangle strikes again

  1. #1
    Registered User
    Join Date
    Apr 2019
    Posts
    808

    burmuda triangle strikes again

    given that every other triangular number starting from 1 is a hexagonal number and every pentagonal number is 1/3 of a triangular number it follows that if a number is both hexagonal and pentagonal it must be triangular. I have the following to find the first triangular number other than 1 that is pentagonal and hexagonal as well
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    int isPentagonal( unsigned long );
    
    int main()
    {
        for ( unsigned long hex, i = 2; ; i++ )
        {
            hex = ( i * ( 2 * i - 1) );
            printf("%lu = %lu\n ", i , hex);
    
            if ( isPentagonal( hex ) )
            {
                printf("%lu\n", i);
                break;
            }
        }
    
        return 0;
    }
    
    int isPentagonal( unsigned long n )
    {
        int sq = sqrt( 1 + 24 * n);
        return sq*sq == ( 1 + 24 * n ) && ( 1 + sq ) % 6 == 0;
    }
    it works i get the answer 143 which is correct

    However, it then goes into an infinite loop if i is greater than 143 rather than find the next one

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,665
    So what is the next correct answer?

    As it stands, you're laying yourself open to problems with rounding in your use of sqrt, and numeric overflow.

    Also, it's time you learnt how to use a debugger.
    Writing code then posting it online when it doesn't work is not a long term strategy.

    Eg
    Code:
    # Compile with debug enabled
    $ gcc -g -Wall foo.c -lm
    # Run the debugger
    $ gdb -q ./a.out
    Reading symbols from ./a.out...
    # Set a breakpoint on line 14 for when i is equal to 100
    (gdb) b 14 if i == 100
    Breakpoint 1 at 0x11b3: file foo.c, line 14.
    (gdb) run
    Starting program: ./a.out 
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
    2 = 6
     3 = 15
     4 = 28
     5 = 45
     6 = 66
     7 = 91
     8 = 120
     9 = 153
     10 = 190
    <<snipped>>
     95 = 17955
     96 = 18336
     97 = 18721
     98 = 19110
     99 = 19503
     100 = 19900
    
    Breakpoint 1, main () at foo.c:14
    14	        if ( isPentagonal( hex ) )
    # Step into the function
    (gdb) s
    isPentagonal (n=19900) at foo.c:26
    26	    int sq = sqrt( 1 + 24 * n);
    # Step over calling sqrt
    (gdb) n
    27	    return sq*sq == ( 1 + 24 * n ) && ( 1 + sq ) % 6 == 0;
    # Print some things
    (gdb) p sq
    $1 = 691
    (gdb) p sq*sq
    $2 = 477481
    (gdb) p 1 + 24 * n
    $3 = 477601
    (gdb)

    > it works i get the answer 143 which is correct
    I don't see 143 on this list.
    A001318 - OEIS
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Dec 2017
    Posts
    1,644
    143 is not triangular, square, pentagonal, hexagonal, heptagonal, or octagonal.
    40755 is the lowest number I could find that is triangular, pentagonal, and hexagonal.
    A little inaccuracy saves tons of explanation. - H.H. Munro

  4. #4
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    143 hexagonal is 40755

  5. #5
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    the rounding error is deliberate unless sq is a perfect number (whole number) then n isnt a pentagonal number the check to see if sq * sq = 1 + 24 * n is to test for the rounding error

  6. #6
    Registered User
    Join Date
    Dec 2017
    Posts
    1,644
    Quote Originally Posted by cooper1200 View Post
    143 hexagonal is 40755
    Oh, I see. Salem was confused by this, too. You are very bad at describing your problems, although if I read the code I guess I could have seen what 143 meant.
    In that case, maybe it is the only value that satisfies the conditions within the range of your calculations. For example, I could not find another number that satisfies the conditions below a quarter billion (the actual number, not the hexagonal index of it, which is a very strange way to indicate a value). I looked no further as I hit overflow problems (like Salem mentioned) and I didn't feel like fixing them.
    A little inaccuracy saves tons of explanation. - H.H. Munro

  7. #7
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    sorry i take your point. I was testing for the value of i as that was the example case i was given ie Tn285 = Pn165 Hn143 = 40755. I tried changing the int sq to unsigned long sq and it now works however i don't understand why that makes a difference

  8. #8
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    scratch that i just done the calculations. once int sq overflows sq * sq is never = to 1 + 24 * n hence the number is never a pentagonal number

  9. #9
    Registered User
    Join Date
    Dec 2017
    Posts
    1,644
    A very straightforward way of doing it:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
     
    #define LIMIT 10000000000000000000u // ten quintillion
     
    int main() {
        unsigned long a[20];
        unsigned n = 0, size = sizeof a / sizeof *a;
     
        unsigned long tri  = 1, tri_add  = 2, tri_delta  = 1,
                      pent = 1, pent_add = 4, pent_delta = 3;
        unsigned tri_ind = 1, pent_ind = 1;
    
        printf("triangular and pentagonal:\n");
     
        while (pent < LIMIT) {
            while (tri < pent) {
                tri += tri_add; tri_add += tri_delta; ++tri_ind;
            }
     
            if (tri == pent) {
                printf("%19lu (%10u, %10u)\n", tri, tri_ind, pent_ind);
                if (n >= size) { printf("array overflow\n"); exit(1); }
                a[n++] = tri;
                tri += tri_add; tri_add += tri_delta; ++tri_ind;
            }
     
            while (pent < tri) {
                pent += pent_add; pent_add += pent_delta; ++pent_ind;
            }
     
            if (tri == pent) {
                printf("%19lu (%10u, %10u)\n", tri, tri_ind, pent_ind);
                if (n >= size) { printf("array overflow\n"); exit(1); }
                a[n++] = tri;
                pent += pent_add; pent_add += pent_delta; ++pent_ind;
            }
        }
     
        printf("\nalso hexagonal:\n");
     
        unsigned long hex = 1, hex_add = 5, hex_delta = 4;
        unsigned hex_ind = 1;
     
        for (unsigned i = 0; i < n; ) {
            while (hex < a[i]) {
                hex += hex_add; hex_add += hex_delta; ++hex_ind;
            }
            if (hex == a[i]) printf("%19lu (%10u)\n", hex, hex_ind);
            ++i;
            hex += hex_add; hex_add += hex_delta; ++hex_ind;
        }
     
        return 0;
    }
    
    Output:
    
    triangular and pentagonal:
                      1 (         1,          1)
                    210 (        20,         12)
                  40755 (       285,        165)
                7906276 (      3976,       2296)
             1533776805 (     55385,      31977)
           297544793910 (    771420,     445380)
         57722156241751 (  10744501,    6203341)
      11197800766105800 ( 149651600,   86401392)
    2172315626468283465 (2084377905, 1203416145)
    
    also hexagonal:
                      1 (         1)
                  40755 (       143)
             1533776805 (     27693)
         57722156241751 (   5372251)
    2172315626468283465 (1042188953)
    So every second number that is both triangular and pentagonal is also hexagonal.
    Last edited by john.c; 06-10-2023 at 12:11 PM.
    A little inaccuracy saves tons of explanation. - H.H. Munro

  10. #10
    Registered User
    Join Date
    Dec 2017
    Posts
    1,644
    Forget this. It's a weird double-post accident....

    A very straightforward way of doing it:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
     
    #define LIMIT 10000000000000000000u // ten quintillion
     
    int main() {
        unsigned long a[20];
        unsigned n = 0, size = sizeof a / sizeof *a;
     
        unsigned long tri  = 1, tri_add  = 2, tri_delta  = 1,
                      pent = 1, pent_add = 4, pent_delta = 3;
        unsigned tri_ind = 1, pent_ind = 1;
    
        printf("triangular and pentagonal:\n");
     
        while (pent < LIMIT) {
            while (tri < pent) {
                tri += tri_add; tri_add += tri_delta; ++tri_ind;
            }
     
            if (tri == pent) {
                printf("%19lu (%10u, %10u)\n", tri, tri_ind, pent_ind);
                if (n >= size) { printf("array overflow\n"); exit(1); }
                a[n++] = tri;
                tri += tri_add; tri_add += tri_delta; ++tri_ind;
            }
     
            while (pent < tri) {
                pent += pent_add; pent_add += pent_delta; ++pent_ind;
            }
     
            if (tri == pent) {
                printf("%19lu (%10u, %10u)\n", tri, tri_ind, pent_ind);
                if (n >= size) { printf("array overflow\n"); exit(1); }
                a[n++] = tri;
                pent += pent_add; pent_add += pent_delta; ++pent_ind;
            }
        }
     
        printf("\nalso hexagonal:\n");
     
        unsigned long hex = 1, hex_add = 5, hex_delta = 4;
        unsigned hex_ind = 1;
     
        for (unsigned i = 0; i < n; ) {
            while (hex < a[i]) {
                hex += hex_add; hex_add += hex_delta; ++hex_ind;
            }
            if (hex == a[i]) printf("%19lu (%10u)\n", hex, hex_ind);
            ++i;
            hex += hex_add; hex_add += hex_delta; ++hex_ind;
        }
     
        return 0;
    }
    
    Output:
    
    triangular and pentagonal:
                      1 (         1,          1)
                    210 (        20,         12)
                  40755 (       285,        165)
                7906276 (      3976,       2296)
             1533776805 (     55385,      31977)
           297544793910 (    771420,     445380)
         57722156241751 (  10744501,    6203341)
      11197800766105800 ( 149651600,   86401392)
    2172315626468283465 (2084377905, 1203416145)
    
    also hexagonal:
                      1 (         1)
                  40755 (       143)
             1533776805 (     27693)
         57722156241751 (   5372251)
    2172315626468283465 (1042188953)
    So every second number that is both triangular and pentagonal is also hexagonal.
    Last edited by john.c; 06-10-2023 at 12:11 PM.
    A little inaccuracy saves tons of explanation. - H.H. Munro

  11. #11
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    this is what i don't understand it seams to me that sometimes you can overflow an unsigned int and sometimes you cant. in the above you declared your variables as unsigned long yet have values upto 2,172,315,626,468,283,465 when the limit for unsigned int is 4,294,967,295

  12. #12
    Registered User
    Join Date
    Dec 2017
    Posts
    1,644
    Your question makes no sense. unsigned long is obviously not the same as unsigned int.
    On my system, long is 64 bits whereas int is 32 bits.
    A little inaccuracy saves tons of explanation. - H.H. Munro

  13. #13
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    sorry meant unsigned long is 4,294,967,295

  14. #14
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    so do the max values depend on weather the machine is a 64 bit machine or a 32 and is that only for the long and long long types

  15. #15
    Registered User
    Join Date
    Dec 2017
    Posts
    1,644
    A 64-bit machine can still have 32-bit longs. Microsoft apparently does this (i.e., they have the LLP64 data model - see 64-bit computing - Wikipedia ).
    So you need to use long long to ensure a 64-bit data type. I should've done that in my program.
    A little inaccuracy saves tons of explanation. - H.H. Munro

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. codeblocks strikes again
    By cooper1200 in forum C Programming
    Replies: 25
    Last Post: 06-17-2019, 02:01 AM
  2. MS STL strikes again
    By VirtualAce in forum C++ Programming
    Replies: 2
    Last Post: 07-11-2008, 04:56 PM

Tags for this Thread