Make a beautiful binary string

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











up vote
11
down vote

favorite
3












This is the "Beautiful Binary String" problem at HackerRank:




Alice has a binary string. She thinks a binary string is beautiful if and only if it doesn't contain the substring 010.



In one step, Alice can change a 0 to a 1 or vice versa. Count and print the minimum number of steps needed to make Alice see the string as beautiful.



For example, if Alice's string is 010 she can change any one element and have a beautiful string.




This is my Python code:



def beautifulBinaryString(b):
temp = list(b)
count,i = 0,0
if len(b) == 3 and b == "010": count += 1
elif len(b) == 3 and b != "010": count = count
else:
while (i+3 <= len(temp)):
if temp[i:i+3] == ['0','1','0']:
count += 1
del temp[i:i+3]
else: i += 1
return count


It seems to me as having too many conditionals (though readable, I guess). Is there a more concise way to accomplish this?



Some test cases:



0101010 
01100

2
0









share|improve this question



























    up vote
    11
    down vote

    favorite
    3












    This is the "Beautiful Binary String" problem at HackerRank:




    Alice has a binary string. She thinks a binary string is beautiful if and only if it doesn't contain the substring 010.



    In one step, Alice can change a 0 to a 1 or vice versa. Count and print the minimum number of steps needed to make Alice see the string as beautiful.



    For example, if Alice's string is 010 she can change any one element and have a beautiful string.




    This is my Python code:



    def beautifulBinaryString(b):
    temp = list(b)
    count,i = 0,0
    if len(b) == 3 and b == "010": count += 1
    elif len(b) == 3 and b != "010": count = count
    else:
    while (i+3 <= len(temp)):
    if temp[i:i+3] == ['0','1','0']:
    count += 1
    del temp[i:i+3]
    else: i += 1
    return count


    It seems to me as having too many conditionals (though readable, I guess). Is there a more concise way to accomplish this?



    Some test cases:



    0101010 
    01100

    2
    0









    share|improve this question

























      up vote
      11
      down vote

      favorite
      3









      up vote
      11
      down vote

      favorite
      3






      3





      This is the "Beautiful Binary String" problem at HackerRank:




      Alice has a binary string. She thinks a binary string is beautiful if and only if it doesn't contain the substring 010.



      In one step, Alice can change a 0 to a 1 or vice versa. Count and print the minimum number of steps needed to make Alice see the string as beautiful.



      For example, if Alice's string is 010 she can change any one element and have a beautiful string.




      This is my Python code:



      def beautifulBinaryString(b):
      temp = list(b)
      count,i = 0,0
      if len(b) == 3 and b == "010": count += 1
      elif len(b) == 3 and b != "010": count = count
      else:
      while (i+3 <= len(temp)):
      if temp[i:i+3] == ['0','1','0']:
      count += 1
      del temp[i:i+3]
      else: i += 1
      return count


      It seems to me as having too many conditionals (though readable, I guess). Is there a more concise way to accomplish this?



      Some test cases:



      0101010 
      01100

      2
      0









      share|improve this question















      This is the "Beautiful Binary String" problem at HackerRank:




      Alice has a binary string. She thinks a binary string is beautiful if and only if it doesn't contain the substring 010.



      In one step, Alice can change a 0 to a 1 or vice versa. Count and print the minimum number of steps needed to make Alice see the string as beautiful.



      For example, if Alice's string is 010 she can change any one element and have a beautiful string.




      This is my Python code:



      def beautifulBinaryString(b):
      temp = list(b)
      count,i = 0,0
      if len(b) == 3 and b == "010": count += 1
      elif len(b) == 3 and b != "010": count = count
      else:
      while (i+3 <= len(temp)):
      if temp[i:i+3] == ['0','1','0']:
      count += 1
      del temp[i:i+3]
      else: i += 1
      return count


      It seems to me as having too many conditionals (though readable, I guess). Is there a more concise way to accomplish this?



      Some test cases:



      0101010 
      01100

      2
      0






      python strings programming-challenge






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Oct 1 at 14:26









      Gareth Rees

      43.2k394173




      43.2k394173










      asked Oct 1 at 14:19









      db18

      13716




      13716




















          2 Answers
          2






          active

          oldest

          votes

















          up vote
          17
          down vote



          accepted










          Style




          • Read the PEP8 style guide!



            1. Functions and variables should be snake_case

            2. Conditions should be on the next line if a: ... is bad style

            3. Conditions don't need parenthesis while (a) is the same as while a:

            4. Avoid temp variables


          Algorithm




          • Your first 2 guard clauses seem very unnecessary



            When I remove them, the code still works.



          • Consider writing docstring/tests or both with the doctest module


          Alternative Code



          You could use re.findall(substring, string) for counting the occurrence,



          OR string.count(substring) making this practically a one-line



          import doctest

          def beautiful_binary_string(b):
          """
          Returns the steps to make a binary string beautiful

          >>> beautiful_binary_string("0101010")
          2

          >>> beautiful_binary_string("01100")
          0

          >>> beautiful_binary_string("0100101010100010110100100110110100011100111110101001011001110111110000101011011111011001111100011101")
          10
          """
          return b.count("010")

          if __name__ == '__main__':
          doctest.testmod()





          share|improve this answer


















          • 1




            @Tyberius: It seems to work fine because count doesn't count overlapping substrings. 'aaa'.count('aa') is just 1
            – Eric Duminil
            Oct 2 at 6:56






          • 2




            Now, that's some anticlimactic solution :D.
            – Eric Duminil
            Oct 2 at 6:57






          • 1




            @EricDuminil Yes somehow this feels more like a hack then an actual solution :)
            – Ludisposed
            Oct 2 at 8:05






          • 2




            Indeed, as you answer the question without doing the steps; A non-constructive solution is fine, but 1. you didn't show that doing a step to fix one occurrence doesn't create another one, 2. you didn't show that two overlapping occurrences can be fixed using a single step.
            – maaartinus
            Oct 2 at 10:24










          • @maaartinus You are right, I will edit to add more clarification when I have the time.
            – Ludisposed
            Oct 2 at 10:29

















          up vote
          10
          down vote














          Is there a more concise way to accomplish this?




          Certainly.



          For a start, the special cases are unnecessary. (They make me think that the code has been refactored from a recursive version).



          Secondly, the expensive del temp[i:i+3] could be replaced with i += 3, and since the processing is no longer destructive temp is unnecessary. This simplifies the code to



          def beautifulBinaryString(b):
          count, i = 0, 0
          while (i+3 <= len(b)):
          if b[i:i+3] == "010":
          count, i = count+1, i+3
          else: i += 1
          return count





          share|improve this answer




















          • I have some very strong reservations about performing two assignments on a single line unnecessarily (and lack of PEP8 compliance). Apart from that, very nice answer.
            – Konrad Rudolph
            Oct 2 at 12:42







          • 1




            @KonradRudolph, OP explicitly prioritised concision, and I don't think that a multiple assignment crosses the line into golfing. But I take your point that it's not uncontroversial.
            – Peter Taylor
            Oct 2 at 12:48










          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%2f204702%2fmake-a-beautiful-binary-string%23new-answer', 'question_page');

          );

          Post as a guest






























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          17
          down vote



          accepted










          Style




          • Read the PEP8 style guide!



            1. Functions and variables should be snake_case

            2. Conditions should be on the next line if a: ... is bad style

            3. Conditions don't need parenthesis while (a) is the same as while a:

            4. Avoid temp variables


          Algorithm




          • Your first 2 guard clauses seem very unnecessary



            When I remove them, the code still works.



          • Consider writing docstring/tests or both with the doctest module


          Alternative Code



          You could use re.findall(substring, string) for counting the occurrence,



          OR string.count(substring) making this practically a one-line



          import doctest

          def beautiful_binary_string(b):
          """
          Returns the steps to make a binary string beautiful

          >>> beautiful_binary_string("0101010")
          2

          >>> beautiful_binary_string("01100")
          0

          >>> beautiful_binary_string("0100101010100010110100100110110100011100111110101001011001110111110000101011011111011001111100011101")
          10
          """
          return b.count("010")

          if __name__ == '__main__':
          doctest.testmod()





          share|improve this answer


















          • 1




            @Tyberius: It seems to work fine because count doesn't count overlapping substrings. 'aaa'.count('aa') is just 1
            – Eric Duminil
            Oct 2 at 6:56






          • 2




            Now, that's some anticlimactic solution :D.
            – Eric Duminil
            Oct 2 at 6:57






          • 1




            @EricDuminil Yes somehow this feels more like a hack then an actual solution :)
            – Ludisposed
            Oct 2 at 8:05






          • 2




            Indeed, as you answer the question without doing the steps; A non-constructive solution is fine, but 1. you didn't show that doing a step to fix one occurrence doesn't create another one, 2. you didn't show that two overlapping occurrences can be fixed using a single step.
            – maaartinus
            Oct 2 at 10:24










          • @maaartinus You are right, I will edit to add more clarification when I have the time.
            – Ludisposed
            Oct 2 at 10:29














          up vote
          17
          down vote



          accepted










          Style




          • Read the PEP8 style guide!



            1. Functions and variables should be snake_case

            2. Conditions should be on the next line if a: ... is bad style

            3. Conditions don't need parenthesis while (a) is the same as while a:

            4. Avoid temp variables


          Algorithm




          • Your first 2 guard clauses seem very unnecessary



            When I remove them, the code still works.



          • Consider writing docstring/tests or both with the doctest module


          Alternative Code



          You could use re.findall(substring, string) for counting the occurrence,



          OR string.count(substring) making this practically a one-line



          import doctest

          def beautiful_binary_string(b):
          """
          Returns the steps to make a binary string beautiful

          >>> beautiful_binary_string("0101010")
          2

          >>> beautiful_binary_string("01100")
          0

          >>> beautiful_binary_string("0100101010100010110100100110110100011100111110101001011001110111110000101011011111011001111100011101")
          10
          """
          return b.count("010")

          if __name__ == '__main__':
          doctest.testmod()





          share|improve this answer


















          • 1




            @Tyberius: It seems to work fine because count doesn't count overlapping substrings. 'aaa'.count('aa') is just 1
            – Eric Duminil
            Oct 2 at 6:56






          • 2




            Now, that's some anticlimactic solution :D.
            – Eric Duminil
            Oct 2 at 6:57






          • 1




            @EricDuminil Yes somehow this feels more like a hack then an actual solution :)
            – Ludisposed
            Oct 2 at 8:05






          • 2




            Indeed, as you answer the question without doing the steps; A non-constructive solution is fine, but 1. you didn't show that doing a step to fix one occurrence doesn't create another one, 2. you didn't show that two overlapping occurrences can be fixed using a single step.
            – maaartinus
            Oct 2 at 10:24










          • @maaartinus You are right, I will edit to add more clarification when I have the time.
            – Ludisposed
            Oct 2 at 10:29












          up vote
          17
          down vote



          accepted







          up vote
          17
          down vote



          accepted






          Style




          • Read the PEP8 style guide!



            1. Functions and variables should be snake_case

            2. Conditions should be on the next line if a: ... is bad style

            3. Conditions don't need parenthesis while (a) is the same as while a:

            4. Avoid temp variables


          Algorithm




          • Your first 2 guard clauses seem very unnecessary



            When I remove them, the code still works.



          • Consider writing docstring/tests or both with the doctest module


          Alternative Code



          You could use re.findall(substring, string) for counting the occurrence,



          OR string.count(substring) making this practically a one-line



          import doctest

          def beautiful_binary_string(b):
          """
          Returns the steps to make a binary string beautiful

          >>> beautiful_binary_string("0101010")
          2

          >>> beautiful_binary_string("01100")
          0

          >>> beautiful_binary_string("0100101010100010110100100110110100011100111110101001011001110111110000101011011111011001111100011101")
          10
          """
          return b.count("010")

          if __name__ == '__main__':
          doctest.testmod()





          share|improve this answer














          Style




          • Read the PEP8 style guide!



            1. Functions and variables should be snake_case

            2. Conditions should be on the next line if a: ... is bad style

            3. Conditions don't need parenthesis while (a) is the same as while a:

            4. Avoid temp variables


          Algorithm




          • Your first 2 guard clauses seem very unnecessary



            When I remove them, the code still works.



          • Consider writing docstring/tests or both with the doctest module


          Alternative Code



          You could use re.findall(substring, string) for counting the occurrence,



          OR string.count(substring) making this practically a one-line



          import doctest

          def beautiful_binary_string(b):
          """
          Returns the steps to make a binary string beautiful

          >>> beautiful_binary_string("0101010")
          2

          >>> beautiful_binary_string("01100")
          0

          >>> beautiful_binary_string("0100101010100010110100100110110100011100111110101001011001110111110000101011011111011001111100011101")
          10
          """
          return b.count("010")

          if __name__ == '__main__':
          doctest.testmod()






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Oct 1 at 14:58

























          answered Oct 1 at 14:50









          Ludisposed

          6,56821959




          6,56821959







          • 1




            @Tyberius: It seems to work fine because count doesn't count overlapping substrings. 'aaa'.count('aa') is just 1
            – Eric Duminil
            Oct 2 at 6:56






          • 2




            Now, that's some anticlimactic solution :D.
            – Eric Duminil
            Oct 2 at 6:57






          • 1




            @EricDuminil Yes somehow this feels more like a hack then an actual solution :)
            – Ludisposed
            Oct 2 at 8:05






          • 2




            Indeed, as you answer the question without doing the steps; A non-constructive solution is fine, but 1. you didn't show that doing a step to fix one occurrence doesn't create another one, 2. you didn't show that two overlapping occurrences can be fixed using a single step.
            – maaartinus
            Oct 2 at 10:24










          • @maaartinus You are right, I will edit to add more clarification when I have the time.
            – Ludisposed
            Oct 2 at 10:29












          • 1




            @Tyberius: It seems to work fine because count doesn't count overlapping substrings. 'aaa'.count('aa') is just 1
            – Eric Duminil
            Oct 2 at 6:56






          • 2




            Now, that's some anticlimactic solution :D.
            – Eric Duminil
            Oct 2 at 6:57






          • 1




            @EricDuminil Yes somehow this feels more like a hack then an actual solution :)
            – Ludisposed
            Oct 2 at 8:05






          • 2




            Indeed, as you answer the question without doing the steps; A non-constructive solution is fine, but 1. you didn't show that doing a step to fix one occurrence doesn't create another one, 2. you didn't show that two overlapping occurrences can be fixed using a single step.
            – maaartinus
            Oct 2 at 10:24










          • @maaartinus You are right, I will edit to add more clarification when I have the time.
            – Ludisposed
            Oct 2 at 10:29







          1




          1




          @Tyberius: It seems to work fine because count doesn't count overlapping substrings. 'aaa'.count('aa') is just 1
          – Eric Duminil
          Oct 2 at 6:56




          @Tyberius: It seems to work fine because count doesn't count overlapping substrings. 'aaa'.count('aa') is just 1
          – Eric Duminil
          Oct 2 at 6:56




          2




          2




          Now, that's some anticlimactic solution :D.
          – Eric Duminil
          Oct 2 at 6:57




          Now, that's some anticlimactic solution :D.
          – Eric Duminil
          Oct 2 at 6:57




          1




          1




          @EricDuminil Yes somehow this feels more like a hack then an actual solution :)
          – Ludisposed
          Oct 2 at 8:05




          @EricDuminil Yes somehow this feels more like a hack then an actual solution :)
          – Ludisposed
          Oct 2 at 8:05




          2




          2




          Indeed, as you answer the question without doing the steps; A non-constructive solution is fine, but 1. you didn't show that doing a step to fix one occurrence doesn't create another one, 2. you didn't show that two overlapping occurrences can be fixed using a single step.
          – maaartinus
          Oct 2 at 10:24




          Indeed, as you answer the question without doing the steps; A non-constructive solution is fine, but 1. you didn't show that doing a step to fix one occurrence doesn't create another one, 2. you didn't show that two overlapping occurrences can be fixed using a single step.
          – maaartinus
          Oct 2 at 10:24












          @maaartinus You are right, I will edit to add more clarification when I have the time.
          – Ludisposed
          Oct 2 at 10:29




          @maaartinus You are right, I will edit to add more clarification when I have the time.
          – Ludisposed
          Oct 2 at 10:29












          up vote
          10
          down vote














          Is there a more concise way to accomplish this?




          Certainly.



          For a start, the special cases are unnecessary. (They make me think that the code has been refactored from a recursive version).



          Secondly, the expensive del temp[i:i+3] could be replaced with i += 3, and since the processing is no longer destructive temp is unnecessary. This simplifies the code to



          def beautifulBinaryString(b):
          count, i = 0, 0
          while (i+3 <= len(b)):
          if b[i:i+3] == "010":
          count, i = count+1, i+3
          else: i += 1
          return count





          share|improve this answer




















          • I have some very strong reservations about performing two assignments on a single line unnecessarily (and lack of PEP8 compliance). Apart from that, very nice answer.
            – Konrad Rudolph
            Oct 2 at 12:42







          • 1




            @KonradRudolph, OP explicitly prioritised concision, and I don't think that a multiple assignment crosses the line into golfing. But I take your point that it's not uncontroversial.
            – Peter Taylor
            Oct 2 at 12:48














          up vote
          10
          down vote














          Is there a more concise way to accomplish this?




          Certainly.



          For a start, the special cases are unnecessary. (They make me think that the code has been refactored from a recursive version).



          Secondly, the expensive del temp[i:i+3] could be replaced with i += 3, and since the processing is no longer destructive temp is unnecessary. This simplifies the code to



          def beautifulBinaryString(b):
          count, i = 0, 0
          while (i+3 <= len(b)):
          if b[i:i+3] == "010":
          count, i = count+1, i+3
          else: i += 1
          return count





          share|improve this answer




















          • I have some very strong reservations about performing two assignments on a single line unnecessarily (and lack of PEP8 compliance). Apart from that, very nice answer.
            – Konrad Rudolph
            Oct 2 at 12:42







          • 1




            @KonradRudolph, OP explicitly prioritised concision, and I don't think that a multiple assignment crosses the line into golfing. But I take your point that it's not uncontroversial.
            – Peter Taylor
            Oct 2 at 12:48












          up vote
          10
          down vote










          up vote
          10
          down vote










          Is there a more concise way to accomplish this?




          Certainly.



          For a start, the special cases are unnecessary. (They make me think that the code has been refactored from a recursive version).



          Secondly, the expensive del temp[i:i+3] could be replaced with i += 3, and since the processing is no longer destructive temp is unnecessary. This simplifies the code to



          def beautifulBinaryString(b):
          count, i = 0, 0
          while (i+3 <= len(b)):
          if b[i:i+3] == "010":
          count, i = count+1, i+3
          else: i += 1
          return count





          share|improve this answer













          Is there a more concise way to accomplish this?




          Certainly.



          For a start, the special cases are unnecessary. (They make me think that the code has been refactored from a recursive version).



          Secondly, the expensive del temp[i:i+3] could be replaced with i += 3, and since the processing is no longer destructive temp is unnecessary. This simplifies the code to



          def beautifulBinaryString(b):
          count, i = 0, 0
          while (i+3 <= len(b)):
          if b[i:i+3] == "010":
          count, i = count+1, i+3
          else: i += 1
          return count






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Oct 1 at 14:55









          Peter Taylor

          14.7k2455




          14.7k2455











          • I have some very strong reservations about performing two assignments on a single line unnecessarily (and lack of PEP8 compliance). Apart from that, very nice answer.
            – Konrad Rudolph
            Oct 2 at 12:42







          • 1




            @KonradRudolph, OP explicitly prioritised concision, and I don't think that a multiple assignment crosses the line into golfing. But I take your point that it's not uncontroversial.
            – Peter Taylor
            Oct 2 at 12:48
















          • I have some very strong reservations about performing two assignments on a single line unnecessarily (and lack of PEP8 compliance). Apart from that, very nice answer.
            – Konrad Rudolph
            Oct 2 at 12:42







          • 1




            @KonradRudolph, OP explicitly prioritised concision, and I don't think that a multiple assignment crosses the line into golfing. But I take your point that it's not uncontroversial.
            – Peter Taylor
            Oct 2 at 12:48















          I have some very strong reservations about performing two assignments on a single line unnecessarily (and lack of PEP8 compliance). Apart from that, very nice answer.
          – Konrad Rudolph
          Oct 2 at 12:42





          I have some very strong reservations about performing two assignments on a single line unnecessarily (and lack of PEP8 compliance). Apart from that, very nice answer.
          – Konrad Rudolph
          Oct 2 at 12:42





          1




          1




          @KonradRudolph, OP explicitly prioritised concision, and I don't think that a multiple assignment crosses the line into golfing. But I take your point that it's not uncontroversial.
          – Peter Taylor
          Oct 2 at 12:48




          @KonradRudolph, OP explicitly prioritised concision, and I don't think that a multiple assignment crosses the line into golfing. But I take your point that it's not uncontroversial.
          – Peter Taylor
          Oct 2 at 12:48

















           

          draft saved


          draft discarded















































           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f204702%2fmake-a-beautiful-binary-string%23new-answer', 'question_page');

          );

          Post as a guest













































































          Popular posts from this blog

          How to check contact read email or not when send email to Individual?

          Bahrain

          Postfix configuration issue with fips on centos 7; mailgun relay