/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Packing problem. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ :- use_module(library(clpb)). :- use_module(library(clpfd)). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - R-tetromino - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ tile([[1,1,1,1]], r). tile([[1], [1], [1], [1]], r). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - S-tetromino - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ tile([[1,1], [1,1]], s). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - T-tetromino - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ tile([[0,1,0], [1,1,1]], t). tile([[1,0], [1,1], [1,0]], t). tile([[1,1,1], [0,1,0]], t). tile([[0,1], [1,1], [0,1]], t). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - L-tetromino - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ tile([[1,0,0], [1,1,1]], l). tile([[0,0,1], [1,1,1]], l). tile([[1,1], [1,0], [1,0]], l). tile([[1,1,1], [0,0,1]], l). tile([[0,1], [0,1], [1,1]], l). tile([[1,1], [0,1], [0,1]], l). tile([[1,0], [1,0], [1,1]], l). tile([[1,1,1], [1,0,0]], l). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Basic consistency check: No tile accidentally defined twice. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ %?- findall(Tile-Type, tile(Tile,Type), TTs), \+ ( select(T, TTs, TTs1), memberchk(T, TTs1)). %?- main. main :- matrix(4, 4, RowsTypes), pairs_keys_values(RowsTypes, Rows, Types), same_length(Rows, Vs), pairs_keys_values(TypesVs0, Types, Vs), keysort(TypesVs0, TypesVs), group_pairs_by_key(TypesVs, Groups), transpose(Rows, Cols), phrase((groups_numbers(Groups), all_cardinalities(Cols, Vs)), Cs), ( maplist(sat, Cs) -> writeln('yes.') ; writeln('no.') ). groups_numbers([]) --> []. groups_numbers([Group-Vs|GVs]) --> { call(Group, N) }, [card([N], Vs)], groups_numbers(GVs). all_cardinalities([], _) --> []. all_cardinalities([Col|Cols], Vs) --> { pairs_keys_values(Pairs0, Col, Vs), include(key_one, Pairs0, Pairs), pairs_values(Pairs, Cs) }, [card([1], Cs)], all_cardinalities(Cols, Vs). key_one(1-_). matrix(M, N, Ms) :- Squares #= M*N, length(Ls, Squares), findall(Ls-Type, line(N,Ls,Type), Ms0), sort(Ms0, Ms). line(N, Ls, Type) :- tile(Ts, Type), length(Ls, Max), phrase((zeros(0,P0),tile_(Ts,N,Max,P0,P1),zeros(P1,_)), Ls). %?- line(4, Ls). %?- matrix(4,4,Ms), maplist(writeln, Ms). tile_([], _, _, P, P) --> []. tile_([T|Ts], N, Max, P0, P) --> tile_part(T, N, P0, P1), { (P1 - 1) mod N #>= P0 mod N, P2 #= min(P0 + N, Max) }, zeros(P1, P2), tile_(Ts, N, Max, P2, P). tile_part([], _, P, P) --> []. tile_part([L|Ls], N, P0, P) --> [L], { P1 #= P0 + 1 }, tile_part(Ls, N, P1, P). zeros(P, P) --> []. zeros(P0, P) --> [0], { P1 #= P0 + 1 }, zeros(P1, P). %?- matrix(4, 4, Ms), maplist(writeln, Ms).