alphabet_cake
 
% 2017 Round 1A, Problem A, in Picat, by Afa Zhou
% https://code.google.com/codejam/contest/5304486/dashboard#s=p0&a=1
% Alphabet Cake

import util,sat.

main =>
    T = read_line().to_int(),
    foreach (TC in 1..T)
        [NR,NC] = [to_int(Token) : Token in read_line().split()],
        dc(TC,NR,NC)
    end.

dc(TC,NR,NC) =>
    A = new_array(NR),
        foreach (R in 1..NR)
        A[R] = {E : L in read_line(), E = cond(L=='?',_,L)}
    end,
    Dom = [A[R,C] : R in 1..NR, C in 1..NC, nonvar(A[R,C])].sort_remove_dups(),
    Frames = [],           % for each letter, build a frame
    Map = new_map(),
    foreach (E in Dom)
        B = new_array(NR,NC),
        B :: 0..1,
        [R1,R2] :: 1..NR, [C1,C2] :: 1..NC,
        Frame = {E,B,R1,C1,R2,C2},          % (R1,C1) - upper-left corner, (R2,C2) lower-right corner
        Map.put(E,Frame),
        Frames := [Frame|Frames],
        foreach (R in 1..NR, C in 1..NC)
            (R #>= R1 #/\ C #>= C1 #/\ R #=< R2 #/\ C #=< C2) #<=> B[R,C]
        end
    end,
    foreach (R in 1..NR, C in 1..NC)   % pre-filled
        if nonvar(A[R,C]) then
            Frame = Map.get(A[R,C]),
            Frame = {_,B,_,_,_,_},
            B[R,C] = 1
        end
    end,
    foreach (R in 1..NR, C in 1..NC)
        sum([B[R,C] : {_,B,_,_,_,_} in Frames]) #= 1
    end,
    solve(Frames),
    foreach ({L,B,R1,C1,R2,C2} in Frames, R in R1..R2, C in C1..C2)
        A[R,C] = L
    end,
    printf("Case #%w:\n", TC),
    foreach (R in 1..NR)
        foreach (C in 1..NC)
            print(A[R,C])
        end,
        nl
    end.