Finding the position in a triangle for the given challenge

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
0
down vote

favorite












The LAMBCHOP doomsday device takes up much of the interior of Commander Lambda's space station, and as a result
the prison blocks have an unusual layout. They are stacked in a triangular shape, and the bunny prisoners are given
numerical IDs starting from the corner, as follows:



| 7



| 4 8



| 2 5 9



| 1 3 6 10



Each cell can be represented as points (x, y), with x being the distance from the vertical wall, and y being the height from the ground.



For example, the bunny prisoner at (1, 1) has ID 1, the bunny prisoner at (3, 2) has ID 9, and the bunny prisoner at (2,3) has ID 8. This pattern of numbering continues indefinitely (Commander Lambda has been taking a LOT of prisoners).



Write a function answer(x, y) which returns the prisoner ID of the bunny at location (x, y). Each value of x and y will be at least 1 and no greater than 100,000. Since the prisoner ID can be very large, return your answer as a string representation of the number.



Here is my solution:



y = int(input())
x = int(input())
sum_in_x = 1
for i in range(x):
sum_in_x = sum_in_x + range(x)[i]
in_sum =i + 2
sum_in_y = sum_in_x
for j in range(y - 1):
sum_in_y = sum_in_y + in_sum
in_sum += 1
print(sum_in_y)


It works and generates the needed solutions, but I am trying to understand if there are better ways of doing this.







share|improve this question

























    up vote
    0
    down vote

    favorite












    The LAMBCHOP doomsday device takes up much of the interior of Commander Lambda's space station, and as a result
    the prison blocks have an unusual layout. They are stacked in a triangular shape, and the bunny prisoners are given
    numerical IDs starting from the corner, as follows:



    | 7



    | 4 8



    | 2 5 9



    | 1 3 6 10



    Each cell can be represented as points (x, y), with x being the distance from the vertical wall, and y being the height from the ground.



    For example, the bunny prisoner at (1, 1) has ID 1, the bunny prisoner at (3, 2) has ID 9, and the bunny prisoner at (2,3) has ID 8. This pattern of numbering continues indefinitely (Commander Lambda has been taking a LOT of prisoners).



    Write a function answer(x, y) which returns the prisoner ID of the bunny at location (x, y). Each value of x and y will be at least 1 and no greater than 100,000. Since the prisoner ID can be very large, return your answer as a string representation of the number.



    Here is my solution:



    y = int(input())
    x = int(input())
    sum_in_x = 1
    for i in range(x):
    sum_in_x = sum_in_x + range(x)[i]
    in_sum =i + 2
    sum_in_y = sum_in_x
    for j in range(y - 1):
    sum_in_y = sum_in_y + in_sum
    in_sum += 1
    print(sum_in_y)


    It works and generates the needed solutions, but I am trying to understand if there are better ways of doing this.







    share|improve this question





















      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      The LAMBCHOP doomsday device takes up much of the interior of Commander Lambda's space station, and as a result
      the prison blocks have an unusual layout. They are stacked in a triangular shape, and the bunny prisoners are given
      numerical IDs starting from the corner, as follows:



      | 7



      | 4 8



      | 2 5 9



      | 1 3 6 10



      Each cell can be represented as points (x, y), with x being the distance from the vertical wall, and y being the height from the ground.



      For example, the bunny prisoner at (1, 1) has ID 1, the bunny prisoner at (3, 2) has ID 9, and the bunny prisoner at (2,3) has ID 8. This pattern of numbering continues indefinitely (Commander Lambda has been taking a LOT of prisoners).



      Write a function answer(x, y) which returns the prisoner ID of the bunny at location (x, y). Each value of x and y will be at least 1 and no greater than 100,000. Since the prisoner ID can be very large, return your answer as a string representation of the number.



      Here is my solution:



      y = int(input())
      x = int(input())
      sum_in_x = 1
      for i in range(x):
      sum_in_x = sum_in_x + range(x)[i]
      in_sum =i + 2
      sum_in_y = sum_in_x
      for j in range(y - 1):
      sum_in_y = sum_in_y + in_sum
      in_sum += 1
      print(sum_in_y)


      It works and generates the needed solutions, but I am trying to understand if there are better ways of doing this.







      share|improve this question











      The LAMBCHOP doomsday device takes up much of the interior of Commander Lambda's space station, and as a result
      the prison blocks have an unusual layout. They are stacked in a triangular shape, and the bunny prisoners are given
      numerical IDs starting from the corner, as follows:



      | 7



      | 4 8



      | 2 5 9



      | 1 3 6 10



      Each cell can be represented as points (x, y), with x being the distance from the vertical wall, and y being the height from the ground.



      For example, the bunny prisoner at (1, 1) has ID 1, the bunny prisoner at (3, 2) has ID 9, and the bunny prisoner at (2,3) has ID 8. This pattern of numbering continues indefinitely (Commander Lambda has been taking a LOT of prisoners).



      Write a function answer(x, y) which returns the prisoner ID of the bunny at location (x, y). Each value of x and y will be at least 1 and no greater than 100,000. Since the prisoner ID can be very large, return your answer as a string representation of the number.



      Here is my solution:



      y = int(input())
      x = int(input())
      sum_in_x = 1
      for i in range(x):
      sum_in_x = sum_in_x + range(x)[i]
      in_sum =i + 2
      sum_in_y = sum_in_x
      for j in range(y - 1):
      sum_in_y = sum_in_y + in_sum
      in_sum += 1
      print(sum_in_y)


      It works and generates the needed solutions, but I am trying to understand if there are better ways of doing this.









      share|improve this question










      share|improve this question




      share|improve this question









      asked Jul 29 at 17:48









      user40929

      434




      434




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          2
          down vote



          accepted










          Your current algorithm is very inefficient. I would use the following algorithmic approach:



          def answer(x, y):
          y_diff = y - 1
          corner = x + y_diff
          id = corner * (corner + 1) // 2
          id -= y_diff
          return str(id)


          This method takes advantage of basic algebra. It uses the sum of the arithmetic progression of x to calculate the id of the bottom right corner, and then subtracts the difference of the input coordinate from the bottom right corner. The reason it take the y difference is because moving 45 degrees diagonally down right is equivalent to moving down (y-1) units and moving right (y-1) units. Is is much more efficient than your current method: instead of an increasing numbering of iterations through range, it does one multiplication.



          Benchmark



          Testing your code compared to mine, mine runs about 10,000 to 100,000 times faster for random values of x and y between 1 and 100000. This is a very significant performance difference.



          Additionally, in benchmarking, I discovered a slight bug in your current implementation. I didn't analyze your implementation deeply to understand it, but it seems that your current implementation returns an output corresponding to the reversed inputs (so for example, if I input (3, 2), the output is correct for (2, 3).) I suspect this may have been missed in your personal testing because the input is reversed of traditional coordinate order, i.e. you ask for y coordinate input before you ask for x coordinate input. I fixed this in my testing by switching all occurrences of x (and related variables) with y and vice versa.



          Some notes




          Write a function answer(x, y) which returns the prisoner ID of the bunny at location (x, y).




          So it seems your answer should be in the form:



          def answer(x, y):
          # ... algorithm
          return str(output)


          Also, use consistent spacing:




          • in_sum =i + 2 to in_sum = i + 2

          And take advantage of +=:




          • sum_in_x = sum_in_x + range(x)[i] to sum_in_x += range(x)[i]


          • sum_in_y = sum_in_y + in_sum to sum_in_y += in_sum





          share|improve this answer























            Your Answer




            StackExchange.ifUsing("editor", function ()
            return StackExchange.using("mathjaxEditing", function ()
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
            );
            );
            , "mathjax-editing");

            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "196"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: false,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );








             

            draft saved


            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f200535%2ffinding-the-position-in-a-triangle-for-the-given-challenge%23new-answer', 'question_page');

            );

            Post as a guest






























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            2
            down vote



            accepted










            Your current algorithm is very inefficient. I would use the following algorithmic approach:



            def answer(x, y):
            y_diff = y - 1
            corner = x + y_diff
            id = corner * (corner + 1) // 2
            id -= y_diff
            return str(id)


            This method takes advantage of basic algebra. It uses the sum of the arithmetic progression of x to calculate the id of the bottom right corner, and then subtracts the difference of the input coordinate from the bottom right corner. The reason it take the y difference is because moving 45 degrees diagonally down right is equivalent to moving down (y-1) units and moving right (y-1) units. Is is much more efficient than your current method: instead of an increasing numbering of iterations through range, it does one multiplication.



            Benchmark



            Testing your code compared to mine, mine runs about 10,000 to 100,000 times faster for random values of x and y between 1 and 100000. This is a very significant performance difference.



            Additionally, in benchmarking, I discovered a slight bug in your current implementation. I didn't analyze your implementation deeply to understand it, but it seems that your current implementation returns an output corresponding to the reversed inputs (so for example, if I input (3, 2), the output is correct for (2, 3).) I suspect this may have been missed in your personal testing because the input is reversed of traditional coordinate order, i.e. you ask for y coordinate input before you ask for x coordinate input. I fixed this in my testing by switching all occurrences of x (and related variables) with y and vice versa.



            Some notes




            Write a function answer(x, y) which returns the prisoner ID of the bunny at location (x, y).




            So it seems your answer should be in the form:



            def answer(x, y):
            # ... algorithm
            return str(output)


            Also, use consistent spacing:




            • in_sum =i + 2 to in_sum = i + 2

            And take advantage of +=:




            • sum_in_x = sum_in_x + range(x)[i] to sum_in_x += range(x)[i]


            • sum_in_y = sum_in_y + in_sum to sum_in_y += in_sum





            share|improve this answer



























              up vote
              2
              down vote



              accepted










              Your current algorithm is very inefficient. I would use the following algorithmic approach:



              def answer(x, y):
              y_diff = y - 1
              corner = x + y_diff
              id = corner * (corner + 1) // 2
              id -= y_diff
              return str(id)


              This method takes advantage of basic algebra. It uses the sum of the arithmetic progression of x to calculate the id of the bottom right corner, and then subtracts the difference of the input coordinate from the bottom right corner. The reason it take the y difference is because moving 45 degrees diagonally down right is equivalent to moving down (y-1) units and moving right (y-1) units. Is is much more efficient than your current method: instead of an increasing numbering of iterations through range, it does one multiplication.



              Benchmark



              Testing your code compared to mine, mine runs about 10,000 to 100,000 times faster for random values of x and y between 1 and 100000. This is a very significant performance difference.



              Additionally, in benchmarking, I discovered a slight bug in your current implementation. I didn't analyze your implementation deeply to understand it, but it seems that your current implementation returns an output corresponding to the reversed inputs (so for example, if I input (3, 2), the output is correct for (2, 3).) I suspect this may have been missed in your personal testing because the input is reversed of traditional coordinate order, i.e. you ask for y coordinate input before you ask for x coordinate input. I fixed this in my testing by switching all occurrences of x (and related variables) with y and vice versa.



              Some notes




              Write a function answer(x, y) which returns the prisoner ID of the bunny at location (x, y).




              So it seems your answer should be in the form:



              def answer(x, y):
              # ... algorithm
              return str(output)


              Also, use consistent spacing:




              • in_sum =i + 2 to in_sum = i + 2

              And take advantage of +=:




              • sum_in_x = sum_in_x + range(x)[i] to sum_in_x += range(x)[i]


              • sum_in_y = sum_in_y + in_sum to sum_in_y += in_sum





              share|improve this answer

























                up vote
                2
                down vote



                accepted







                up vote
                2
                down vote



                accepted






                Your current algorithm is very inefficient. I would use the following algorithmic approach:



                def answer(x, y):
                y_diff = y - 1
                corner = x + y_diff
                id = corner * (corner + 1) // 2
                id -= y_diff
                return str(id)


                This method takes advantage of basic algebra. It uses the sum of the arithmetic progression of x to calculate the id of the bottom right corner, and then subtracts the difference of the input coordinate from the bottom right corner. The reason it take the y difference is because moving 45 degrees diagonally down right is equivalent to moving down (y-1) units and moving right (y-1) units. Is is much more efficient than your current method: instead of an increasing numbering of iterations through range, it does one multiplication.



                Benchmark



                Testing your code compared to mine, mine runs about 10,000 to 100,000 times faster for random values of x and y between 1 and 100000. This is a very significant performance difference.



                Additionally, in benchmarking, I discovered a slight bug in your current implementation. I didn't analyze your implementation deeply to understand it, but it seems that your current implementation returns an output corresponding to the reversed inputs (so for example, if I input (3, 2), the output is correct for (2, 3).) I suspect this may have been missed in your personal testing because the input is reversed of traditional coordinate order, i.e. you ask for y coordinate input before you ask for x coordinate input. I fixed this in my testing by switching all occurrences of x (and related variables) with y and vice versa.



                Some notes




                Write a function answer(x, y) which returns the prisoner ID of the bunny at location (x, y).




                So it seems your answer should be in the form:



                def answer(x, y):
                # ... algorithm
                return str(output)


                Also, use consistent spacing:




                • in_sum =i + 2 to in_sum = i + 2

                And take advantage of +=:




                • sum_in_x = sum_in_x + range(x)[i] to sum_in_x += range(x)[i]


                • sum_in_y = sum_in_y + in_sum to sum_in_y += in_sum





                share|improve this answer















                Your current algorithm is very inefficient. I would use the following algorithmic approach:



                def answer(x, y):
                y_diff = y - 1
                corner = x + y_diff
                id = corner * (corner + 1) // 2
                id -= y_diff
                return str(id)


                This method takes advantage of basic algebra. It uses the sum of the arithmetic progression of x to calculate the id of the bottom right corner, and then subtracts the difference of the input coordinate from the bottom right corner. The reason it take the y difference is because moving 45 degrees diagonally down right is equivalent to moving down (y-1) units and moving right (y-1) units. Is is much more efficient than your current method: instead of an increasing numbering of iterations through range, it does one multiplication.



                Benchmark



                Testing your code compared to mine, mine runs about 10,000 to 100,000 times faster for random values of x and y between 1 and 100000. This is a very significant performance difference.



                Additionally, in benchmarking, I discovered a slight bug in your current implementation. I didn't analyze your implementation deeply to understand it, but it seems that your current implementation returns an output corresponding to the reversed inputs (so for example, if I input (3, 2), the output is correct for (2, 3).) I suspect this may have been missed in your personal testing because the input is reversed of traditional coordinate order, i.e. you ask for y coordinate input before you ask for x coordinate input. I fixed this in my testing by switching all occurrences of x (and related variables) with y and vice versa.



                Some notes




                Write a function answer(x, y) which returns the prisoner ID of the bunny at location (x, y).




                So it seems your answer should be in the form:



                def answer(x, y):
                # ... algorithm
                return str(output)


                Also, use consistent spacing:




                • in_sum =i + 2 to in_sum = i + 2

                And take advantage of +=:




                • sum_in_x = sum_in_x + range(x)[i] to sum_in_x += range(x)[i]


                • sum_in_y = sum_in_y + in_sum to sum_in_y += in_sum






                share|improve this answer















                share|improve this answer



                share|improve this answer








                edited Jul 29 at 20:37


























                answered Jul 29 at 19:52









                Graham

                1739




                1739






















                     

                    draft saved


                    draft discarded


























                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f200535%2ffinding-the-position-in-a-triangle-for-the-given-challenge%23new-answer', 'question_page');

                    );

                    Post as a guest













































































                    Popular posts from this blog

                    Greedy Best First Search implementation in Rust

                    Function to Return a JSON Like Objects Using VBA Collections and Arrays

                    C++11 CLH Lock Implementation