#include <vector>
 
// The logical approach is correct, but this is fucking stupid. This implementation is over-engineered piece of shit.
 
class Solution {
public:
    std::vector<int> productExceptSelf(std::vector<int>& nums) {
        int product = 1;
        std::vector<int> zeroIndices;
        std::vector<int> prefixProduct(nums.size(), 1);
        std::vector<int> suffixProduct(nums.size(), 1);
 
        bool skipMultiply = false;
        
        for (int i = 0; i < nums.size(); i++) {
            if (nums[i] == 0) {
                zeroIndices.push_back(i);
                skipMultiply = true;
            }
            prefixProduct[i] = product;
 
            if (skipMultiply) {
                skipMultiply = false;
                continue;
            }
 
            product *= nums[i];
 
        }
 
        std::vector<int> answer(nums.size(), 0);
 
        // Zeroes are present
        if (zeroIndices.size() >= 1) {
            // only one zero in the entire vector
            if (zeroIndices.size() == 1) {
                answer[zeroIndices[0]] = product;
                return answer;
            }
            // more than one zeroes are present so every product will be zero
            // since at a time we only exclude one zero, the other zero(s) is
            // still included in the product
            return answer;
        }
 
        product = 1;
        for (int i = nums.size() - 1; i >= 0; i--) {
            suffixProduct[i] = product;
            product *= nums[i];
            answer[i] = prefixProduct[i] * suffixProduct[i];
        }
 
        return answer;
    }
};