52 lines
1.8 KiB
Plaintext
52 lines
1.8 KiB
Plaintext
import util, sat.
|
|
|
|
main =>
|
|
Hr = "E BCB BEA BH BEK AABAF ABAC BAA BFB OD JH BADCF Q Q R AN AAN EI H G",
|
|
Hc = "E CB BAB AAA AAA AC BB ACC ACCA AGB AIA AJ AJ ACE AH BAF CAG DAG FAH FJ GJ ADK ABK BL CM",
|
|
Lr = [token_to_hints(Token) : Token in split(Hr)],
|
|
Lc = [token_to_hints(Token) : Token in split(Hc)],
|
|
MaxR = len(Lr),
|
|
MaxC = len(Lc),
|
|
foreach (Hints in Lr)
|
|
constrain_starts(Hints,MaxC)
|
|
end,
|
|
foreach (Hints in Lc)
|
|
constrain_starts(Hints,MaxR)
|
|
end,
|
|
M = new_array(MaxR,MaxC),
|
|
M :: 0..1,
|
|
foreach ({R,Hints} in zip(1..MaxR, Lr))
|
|
sum([M[R,C] : C in 1..MaxC]) #= sum([Num : (Num,_) in Hints])
|
|
end,
|
|
foreach ({R,Hints} in zip(1..MaxR, Lr), (Num,Start) in Hints, C in 1..MaxC-Num+1)
|
|
Start #= C #=> sum([M[R,C+I] : I in 0..Num-1]) #= Num
|
|
end,
|
|
%
|
|
foreach ({C,Hints} in zip(1..MaxC, Lc))
|
|
sum([M[R,C] : R in 1..MaxR]) #= sum([Num : (Num,_) in Hints])
|
|
end,
|
|
foreach ({C,Hints} in zip(1..MaxC, Lc), (Num,Start) in Hints, R in 1..MaxR-Num+1)
|
|
Start #= R #=> sum([M[R+I,C] : I in 0..Num-1]) #= Num
|
|
end,
|
|
solve((Lr,Lc,M)),
|
|
foreach (R in 1..MaxR)
|
|
foreach (C in 1..MaxC)
|
|
printf("%2c", cond(M[R,C] == 1, '#', '.'))
|
|
end,
|
|
nl
|
|
end.
|
|
|
|
% convert "BCB" to [(2,_),(3,_),(2,_)]
|
|
% a hint is a pair (Num,Start), where Num is the length of the 1 segment and Start is the starting row number or column number
|
|
token_to_hints([]) = [].
|
|
token_to_hints([C|Cs]) = [(ord(C)-ord('A')+1, _)|token_to_hints(Cs)].
|
|
|
|
% there must be a gap between two neighboring segments
|
|
constrain_starts([(Num,Start)],Max) =>
|
|
Start :: 1..Max,
|
|
Start+Num-1 #<= Max.
|
|
constrain_starts([(Num1,Start1),(Num2,Start2)|L],Max) =>
|
|
Start1 :: 1..Max,
|
|
Start1+Num1 #< Start2,
|
|
constrain_starts([(Num2,Start2)|L],Max).
|