Problem: Minimum Number of Buckets Required to Collect Rainwater from Houses

You are given a 0-indexed string `hamsters` where `hamsters[i]` is either:

* `'H'` indicating that there is a hamster at index `i`, or
* `'.'` indicating that index `i` is empty.

You will add some number of food buckets at the empty indices in order to feed
the hamsters. A hamster can be fed if there is at least one food bucket to its
left or to its right. More formally, a hamster at index `i` can be fed if you
place a food bucket at index `i - 1` and/or at index `i + 1`.

Return the minimum number of food buckets you should place at empty indices to
feed all the hamsters or `-1` if it is impossible to feed all of them.


Python solution:
import math
import itertools
import bisect
import collections
import string
import heapq
import functools
import sortedcontainers
from typing import List, Dict, Tuple, Iterator

class Solution:
  def minimumBuckets(self, street: str) -> int:
    A = list(street)

    for i, c in enumerate(A):
      if c == 'H':
        if i > 0 and A[i - 1] == 'B':
          continue
        if i + 1 < len(A) and A[i + 1] == '.':
          A[i + 1] = 'B'
        elif i > 0 and A[i - 1] == '.':
          A[i - 1] = 'B'
        else:
          return -1

    return A.count('B')


Java solution:
class Solution {
  public int minimumBuckets(String street) {
    final char[] A = street.toCharArray();

    for (int i = 0; i < A.length; ++i)
      if (A[i] == 'H') {
        if (i > 0 && A[i - 1] == 'B')
          continue;
        if (i + 1 < A.length && A[i + 1] == '.')
          // Always prefer place a bucket in (i + 1) because it enhances the
          // possibility to collect the upcoming houses.
          A[i + 1] = 'B';
        else if (i > 0 && A[i - 1] == '.')
          A[i - 1] = 'B';
        else
          return -1;
      }

    return (int) new String(A).chars().filter(a -> a == 'B').count();
  }
}


C++ solution:
class Solution {
 public:
  int minimumBuckets(string street) {
    for (int i = 0; i < street.length(); ++i)
      if (street[i] == 'H') {
        if (i > 0 && street[i - 1] == 'B')
          continue;
        if (i + 1 < street.length() && street[i + 1] == '.')
          // Always prefer place a bucket in (i + 1) because it enhances the
          // possibility to collect the upcoming houses.
          street[i + 1] = 'B';
        else if (i > 0 && street[i - 1] == '.')
          street[i - 1] = 'B';
        else
          return -1;
      }

    return ranges::count(street, 'B');
  }
};