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).