Trying to solve a puzzle

The most important, what I failed to understand, is that isCovered is in the function of houses. I was thinking about the grid that one antenna can cover, but I should think about which houses antenna(s) can cover instead.

Here is the model:

using JuMP, Cbc, XLSX

mat  = XLSX.readdata("data/input.xlsx", "sheet1", "A1:J10")

M = size(mat, 1)
N = size(mat, 2)
ratio = 0.7

houses = []
for i = 1 : M
  for j = 1 : N
    if mat[i,j] == 1
      push!(houses, (i,j))
    end
  end
end

model = Model(Cbc.Optimizer)

@variable(model, 
            isCovered[houses], 
            Bin)

@variable(model, 
            isAntenna[1:M, 1:N], 
            Bin)

@objective(
    model,
    Min,
    sum(isAntenna)
)

@constraint(
    model,
    sum(isCovered) >= length(houses) * ratio
)

@constraint(
    model, 
    [h in houses],
    isCovered[h] <=
    sum(
        isAntenna[r, c]
        for r in h[1]-1:h[1]+1, c in h[2]-1:h[2]+1
        if 1 <= r <= M && 1 <= c <= N
    ) 
)

optimize!(model)

res = primal_status(model)

if res == MOI.FEASIBLE_POINT
    val = value.(isAntenna)
    open("out/result.txt","w") do io
        for i in 1:M
            for j in 1:N
                print(io, floor(Int, val[i,j]))
                print(io, '\t')
            end
            print(io, "\n")
        end
    end
end