• + 13 comments

    Hmmm.. I made a completely different algorithm than the proposed one on the Editorial.

    First, I check if there is an odd number of odds, because the way I understood it, when you give an odd a loaf, you "push the odd forward"... So it needs to reach another odd number so that both become even.

    When I realised that, all that was left, after checking there was an even number of odds (so every odd could be pushed into another one), was to get the distances between odd numbers and multiply them by 2, because on every "push" you give 2 loaves of bread.

    It's a real simple algorithm and isn't a greedy one.

    • + 1 comment

      +1. Also, you can do this in one pass with O(1) space, just keeping track of "where was the last unmatched odd we saw?"

      • + 0 comments

        my solution in Javascript:

        if the count of odd numbers are odd it should return 'NO', and...

        function fairRations(B) {
            let count = 0;
            if (B.filter((v) => v % 2 == 1).length % 2 == 1) {
                return "NO";
            } else {
                B.forEach((v, i) => {
                    if (v % 2 == 1) {
                        B[i]++;
                        B[i + 1]++;
                        count += 2;
                    }
                });
            }
            return count;
        }
        
    • + 0 comments

      this is a clever move :)

    • + 4 comments

      It's simpler than that.

      Use a carry value initialized to 0. When you see carry+input is odd, you count 2 loaves and set the carry to 1. If carry+input is instead even, set carry to 0.

      After all the input is read, if the carry value from the last input is 1, the problem is insoluble, so you output NO, otherwise output the number of loaves counted.

      int loaves = 0;
      int carry = 0;
      while ( N-- ) {
          int i;
          cin >> i;
          if ( (carry + i)%2 ) {
              loaves += 2;
              carry = 1;
          } else
              carry = 0;
      }
      if ( carry )
          cout << "NO" << endl;
      else
          cout << loaves << endl;
      

      or simpler still:

      while ( N-- ) {
          int i;
          cin >> i;
          carry = (carry + i)%2;
          loaves += 2*carry;
      }
      
      • + 1 comment

        Could you please tell me how did you get to this idea??? I mean thought process can you share... Idea is very good!!!

        • + 3 comments

          I'd like to know too. Great code! I'm guessing that since you propogate loves distributed through the array, that ensures an even number for each element is the result until you reach the end and if the difference is 1 there then it is not possible. Am I correct? My Python3 version:

          n = int(input().strip())
          b = [int(B_temp) for B_temp in input().strip().split(' ')]
          
          sum = 0
          carry = False
          for x in b:
             
              carry = (carry + x) % 2
              sum += carry * 2
          
          if carry:
              print("NO")
          else:
              print (sum)
          
          • + 1 comment

            It's basically just following the rules as written.

            As you check, you find intervals that start with an odd value, have even values in between, and end in an odd value. The process is symmetrical, so for any unhandled interval it doesn't matter whether you start at the leftward odd number or the rightward one, and you will never have to reverse course. And it can only be unbalanced when there is an interval that doesn't get balanced when it reaches the end.

            You disturb two values each time you have to give out any loaves. So if an odd number is followed by an even one, adding loaves makes an even number followed by an odd one, which shortens the interval. When the odd value slides far enough to be next to another odd one, adding loaves closes the interval and you just look for the next one.

            If you reach the end without an open interval, you're done, but if you're still handing out carried loaves, the solution can't be found.

            • + 1 comment

              Thanks alot for detailed explaination!!!

              • + 0 comments

                Thanks!

          • + 0 comments

            Here's similar Python3 code in modern HackerRank, where one defines a function.

            def fairRations(B):
            
                output, M = 0, len(B)-1
                for i in range(M):
                    if B[i]%2 : output += 2 ; B[i+1] += 1
                return "NO" if B[M]%2 else output
            
      • + 0 comments

        If we're going for minimal code, embrace the ternary!

        cout << (carry ? "NO" : loaves) << endl;
        
      • + 0 comments

        if there will be only 2 elements having one element odd other even then fair distribution can't possible.

      • + 0 comments

        ming blowing!

    • + 0 comments

      +1 Simple solution

    • + 1 comment

      Hi! I came up with same solution. If someone is having a hard time to understand it, here's some examples to help:

      First, notice that we need an even amount of odd numbers. Because the problem says that if we increase i by one we need to increase i+1 or i-1. So we need a even amount of odd numbers to get as result an array with only even numbers.

      Example: B = 2 3 5 6 this array has two odd numbers. To make 3 became even we add 1 to it. Luckly, it has an neighbor with odd number. So we add to it too, like this B = 2 4 6 6 . Now the array has only even number.

      But if there's even numbers between the the odd numbers? It will require more loaves.

      Example: B = 2 3 4 5 6 this array has two odd numbers. To make 3 became even we add 1 to and it's neighbor, like this B = 2 4 5 5 6 . Now the odd number was pushed do the left, so we need to increse it and its neighbor too, like this B = 2 4 6 6 6 . Finally the array has only even number.

      Example: B = 2 3 4 4 4 5 6 this array has two odd numbers. To make 3 became even we add 1 to and it's neighbor, like this B = 2 4 5 4 4 5 6 . Now the odd number was pushed do the left, so we need to increse it and its neighbor too, like this B = 2 4 6 5 4 5 6 . If we continue with this process we will end up with B = 2 4 6 6 6 6 6

      Now notice that on the last two examples the amount of loaf increased by one 1 were it was odd and by two on the numbers between the odd ones. With that in mind, we can calculate the amout of loaves

      amountLoaves = 1 + 2.evenNumbersBetweenOddOnes + 1;

      And we repeat this for every two odd numbers in the original array;

      Example: B = 3 5 3 4 4 5 this array has four odd numbers on indexes 0, 1, 2, 5. So we calculate on indexes 0 and 1 which results in 2. And we calculate on indexes 2 and 5, which results in 1 + 2.2 + 1 = 6. And 2 + 6 = 8 is the result.

      Here's my code: https://www.hackerrank.com/challenges/fair-rations/submissions/code/130803395

      • + 0 comments

        It is a good solution :)

    • + 0 comments

      This is pretty much the same solution I came up with:

      def fairRations(B):  
          counting = False
          count = 0
          for b in B:
              if counting:
                  count += 2
              if b % 2:
                  counting = not counting
          else:
              if counting:
                  return "NO"
      
          return count
      
    • + 0 comments

      yes I had the same thought

    • + 0 comments

      yeah ! I did it same ...

    • + 0 comments

      Thanks , i tried to implement your idea .

       public static String fairRations(List<Integer> B) {
      Integer pub[]= new Integer [B.size()];
      pub=B.toArray(pub);
      int count_odd=0,count=0,l=-1,r=-1;
      
      for(int i=0;i<pub.length;i++)
      {
          if(pub[i]%2!=0)
          count_odd++;;
      
      
      }
      if(count_odd%2!=0)
      return "NO";
      else
       {
         for(int i=0;i<pub.length;i++)
         {
             if(pub[i]%2!=0)
             {
               if(l==-1 )
               {
                   l=i;
               }
               else if(l!=-1 && r==-1)
               {
                   r=i;
               }
               if(l!=-1 && r!=-1)
               {
                   count+=(r-l);
      
                   l=-1;
                   r=-1;
               } 
             }
         }
      }
      count*=2;
      

      return count+"";

      }
      
    • + 0 comments

      here is my solution as per your approach in C++. Thanks for this explanation that you have given

      string fairRations(vector<int> B) {
       int count =0,lastodd=-1,ans=0;
      for(int i=0;i<B.size();i++)
      {
          
          
          if(lastodd==-1 && B[i]%2 != 0)
          lastodd = i;
          
          else if(B[i]%2 !=0)
          { int diff = i -lastodd;
          ans += diff*2;
          lastodd =-1;
           }
          
      }
      
      if(lastodd != -1)
      return "NO";
      else return to_string(ans);
      }
      
    • + 0 comments

      my solution in Javascript:

      if the count of odd numbers are odd it should return 'NO', and...

      function fairRations(B) {
          let count = 0;
          if (B.filter((v) => v % 2 == 1).length % 2 == 1) {
              return "NO";
          } else {
              B.forEach((v, i) => {
                  if (v % 2 == 1) {
                      B[i]++;
                      B[i + 1]++;
                      count += 2;
                  }
              });
          }
          return count;
      }