% Busy Bugs Puzzle

% The board is represented by 4 cells:
%
% 1 1 1   2 2 2
% 1 1 1   2 2 2
% 1 1 1   2 2 2
% 
% 3 3 3   4 4 4
% 3 3 3   4 4 4
% 3 3 3   4 4 4
%
% In one cell the squares are in the following order:
%
% 1 2 3
% 4 5 6
% 7 8 9

board([[red, nothing, white,
        black, pink, black,
        yellow, white, red],
       [pink, nothing, white,
        nothing, black, red,
        white, yellow, pink],
       [yellow, red, black,
        pink, nothing, pink,
        white, nothing, yellow],
       [nothing, nothing, nothing,
        nothing, yellow, white,
        pink, red, black]]).

% (Yes, "black" is more like purple, but purple bugs are normally
%  called black.)

% Default rotation of pieces:
%
% apple:    [the apple is in the top-right corner]
%   x x x
%   . x x
%   x x .
%
% c:        [looks like the letter C]
%   x x x
%   x . .
%   x x x
%
% can:      [in the online version there is a can in the top-right corner]
%   . x x
%   x x x
%   x . .
%
% h:        [looks like the letter H]
%   x . x
%   x x x
%   x . x

% piece(Name, Rotations) shows the empty squares for all rotations
piece(apple, [[4,9],[2,7],[1,6],[3,8]]).
piece(c, [[5,6],[5,8],[4,5],[2,5]]).
piece(can, [[1,8,9],[3,4,7],[1,2,9],[3,6,7]]).
piece(h, [[2,8],[4,6]]).

% Some puzzles for testing
puzzle(1, [red-5]).                                  % can-2, h-1, c-3, apple-3
puzzle(24, [red-1,yellow-2,pink-1]).                 % apple-1, h-0, c-3, can-1
puzzle(48, [white-1,red-3,yellow-1,black-1,pink-2]). % can-0, c-1, h-1, apple-3

% Solution is a list of pieces to place in each cell
solve(Bugs, Solution) :-
    board(Board),
    findall(Name, piece(Name, _), Names),
    maplist(rotated, Names, Pieces),
    permutation(Pieces, Solution),
    check(Board, Solution, Bugs).

rotated(Name, Name-N) :- between(0, 3, N).

check([], [], []).
check([Cell|Board], [Name-Rotation|Pieces], Bugs) :-
    \+ member(Name-_, Pieces),
    piece(Name, Rotations),
    nth0(Rotation, Rotations, Visible),
    maplist(choose(Cell), Visible, Found),
    check_bugs(Found, Bugs, Bugs1),
    check(Board, Pieces, Bugs1).

choose(Cell, Index, Bug) :- nth1(Index, Cell, Bug).

check_bugs([], Bugs, Bugs).
check_bugs([nothing|Rest], Bugs, Bugs1) :-
    check_bugs(Rest, Bugs, Bugs1).
check_bugs([Bug|Rest], Bugs, Bugs1) :-
    select(Bug-N, Bugs, Bugs0),
    ( N =:= 1 -> check_bugs(Rest, Bugs0, Bugs1)
    ; N1 is N - 1, check_bugs(Rest, [Bug-N1|Bugs0], Bugs1)
    ).

% Try:
% ?- puzzle(N, P), solve(P, S).

% Total number of variations: 4! * 4^3 * 2 = 3072
% But how many of these are actually different?

% Maximum number of bugs in each color:
maximum([red-5,white-6,black-5,pink-6,yellow-5]).

% The maximum number of puzzles is
%   6^3 * 7^2 = 10584
% so maybe every puzzle is different. Let's see if it is true!

ambiguous(Puzzle, All) :-
    maximum(Max),
    maplist(take_some, Max, Bugs),
    remove_zeros(Bugs, Puzzle),
    findall(Solution, solve(Puzzle, Solution), All),
    All = [_,_|_].

take_some(Name-N, Name-K) :- between(0, N, K).

remove_zeros([], []).
remove_zeros([_-0|Bugs], Bugs1) :- remove_zeros(Bugs, Bugs1).
remove_zeros([Name-N|Bugs], [Name-N|Bugs1]) :-
    N > 0, remove_zeros(Bugs, Bugs1).

% ?- ambiguous(P, All).
% P = [yellow-5],
% All = [[apple-1, h-0, can-0, c-2], [apple-1, h-0, can-0, c-3]] 

% So there are ambiguous cases. How many unambiguous cases are there?

unambiguous(Puzzle-Solution) :-
    maximum(Max),
    maplist(take_some, Max, Bugs),
    remove_zeros(Bugs, Puzzle),
    findall(S, solve(Puzzle, S), [Solution]),
    write(puzzle(Puzzle, Solution)), nl. % just to see something while we wait

% This needs to look through ~ 10 million cases, takes a few minutes.
% ?- findall(P, unambiguous(P), All), length(All, N).
% puzzle([pink-1,yellow-2],[apple-1,h-0,c-1,can-1])
% puzzle([pink-2,yellow-3],[c-3,h-0,can-0,apple-1])
% puzzle([pink-5],[c-3,apple-0,h-1,can-1])
% puzzle([pink-6],[c-3,can-2,h-1,apple-1])
% puzzle([pink-6,yellow-1],[c-3,can-0,h-1,apple-1])
% puzzle([black-1,yellow-2],[apple-1,h-0,c-1,can-2])
% puzzle([black-1,pink-1,yellow-3],[c-3,h-0,can-0,apple-0])
% puzzle([black-1,pink-2,yellow-1],[c-3,h-0,apple-3,can-1])
% puzzle([black-1,pink-4],[c-3,apple-0,h-1,can-2])
% puzzle([black-1,pink-5,yellow-1],[c-3,can-0,h-1,apple-0])
% puzzle([black-2,pink-1,yellow-1],[c-3,h-0,apple-3,can-2])
% puzzle([black-2,pink-2],[h-1,apple-0,c-1,can-1])
% puzzle([black-2,pink-3,yellow-1],[h-1,can-0,c-1,apple-1])
% puzzle([black-3,pink-1],[h-1,apple-0,c-1,can-2])
% puzzle([black-3,pink-1,yellow-3],[h-1,c-1,can-0,apple-1])
% puzzle([black-4,yellow-3],[h-1,c-1,can-0,apple-0])
% puzzle([black-5,yellow-1],[h-1,c-1,apple-3,can-2])
% puzzle([white-1,yellow-5],[apple-1,h-0,can-0,c-0])
% puzzle([white-1,pink-1,yellow-2],[apple-1,h-0,c-1,can-3])
% puzzle([white-1,pink-2],[h-0,apple-0,c-1,can-1])
% puzzle([white-1,pink-2,yellow-1],[apple-1,can-2,c-1,h-1])
% puzzle([white-1,pink-2,yellow-3],[c-1,h-0,can-0,apple-1])
% puzzle([white-1,pink-4,yellow-3],[apple-1,can-0,h-1,c-0])
% puzzle([white-1,pink-5,yellow-1],[c-3,can-0,h-1,apple-2])
% puzzle([white-1,pink-6],[c-1,can-2,h-1,apple-1])
% puzzle([white-1,pink-6,yellow-1],[c-1,can-0,h-1,apple-1])
% puzzle([white-1,black-1,yellow-4],[apple-1,c-1,can-0,h-1])
% puzzle([white-1,black-1,pink-1],[h-0,apple-0,c-1,can-2])
% puzzle([white-1,black-2,pink-1,yellow-3],[h-1,apple-0,can-0,c-0])
% puzzle([white-1,black-3,yellow-3],[h-1,c-1,can-0,apple-2])
% puzzle([white-1,black-4,pink-1,yellow-1],[h-1,c-1,apple-3,can-3])
% puzzle([white-2,pink-1],[h-0,apple-1,c-1,can-1])
% puzzle([white-2,pink-1,yellow-2],[c-3,apple-1,can-0,h-1])
% puzzle([white-2,pink-5,yellow-1],[c-1,can-0,h-1,apple-2])
% puzzle([white-2,black-1],[h-0,apple-1,c-1,can-2])
% puzzle([white-2,black-1,yellow-3],[h-0,c-1,can-0,apple-2])
% puzzle([white-2,black-2,yellow-4],[h-1,apple-3,can-0,c-0])
% puzzle([white-2,black-3],[h-1,can-1,c-1,apple-0])
% puzzle([white-3,yellow-1],[apple-1,can-1,c-1,h-1])
% puzzle([white-3,yellow-3],[h-0,apple-1,can-0,c-0])
% puzzle([white-3,pink-1,yellow-3],[c-1,apple-3,can-0,h-1])
% puzzle([white-3,pink-2,yellow-2],[apple-1,can-1,h-1,c-0])
% puzzle([white-3,pink-4,yellow-2],[apple-3,can-0,h-1,c-0])
% puzzle([white-3,black-1],[h-0,can-1,c-1,apple-0])
% puzzle([white-3,black-1,yellow-3],[apple-3,c-1,can-0,h-1])
% puzzle([white-3,black-1,pink-3,yellow-1],[apple-3,c-1,h-1,can-3])
% puzzle([white-3,black-2],[h-1,can-1,c-1,apple-2])
% puzzle([white-3,black-3,yellow-1],[h-1,can-1,apple-3,c-0])
% puzzle([white-4],[h-0,can-1,c-1,apple-2])
% puzzle([white-4,pink-3],[c-1,can-1,h-1,apple-2])
% puzzle([white-4,black-1,yellow-1],[h-0,can-1,apple-3,c-0])
% puzzle([white-4,black-1,pink-1],[c-1,can-1,apple-3,h-1])
% puzzle([white-5],[apple-3,can-1,c-1,h-1])
% puzzle([white-5,pink-2,yellow-1],[apple-3,can-1,h-1,c-0])
% puzzle([red-1,pink-1,yellow-1],[apple-1,h-1,c-1,can-1])
% puzzle([red-1,pink-1,yellow-2],[apple-1,h-0,c-3,can-1])
% puzzle([red-1,pink-1,yellow-3],[c-3,h-0,can-0,apple-3])
% puzzle([red-1,pink-3],[c-3,apple-0,h-0,can-1])
% puzzle([red-1,pink-4],[c-3,can-2,h-0,apple-1])
% puzzle([red-1,pink-4,yellow-3],[apple-1,can-0,h-1,c-1])
% puzzle([red-1,pink-5,yellow-1],[c-3,can-0,h-1,apple-3])
% puzzle([red-1,black-1,yellow-1],[apple-1,h-1,c-1,can-2])
% puzzle([red-1,black-2,yellow-2],[apple-1,c-1,h-0,can-2])
% puzzle([red-1,black-2,pink-1],[c-3,h-1,apple-3,can-2])
% puzzle([red-1,black-3,yellow-3],[h-1,c-1,can-0,apple-3])
% puzzle([red-1,black-3,pink-1,yellow-3],[h-1,c-1,can-2,apple-1])
% puzzle([red-1,black-3,pink-2,yellow-2],[h-1,can-0,apple-3,c-1])
% puzzle([red-1,black-4,yellow-3],[h-1,c-1,can-2,apple-0])
% puzzle([red-1,black-4,pink-1],[h-1,c-0,apple-3,can-1])
% puzzle([red-1,black-5,yellow-1],[h-1,c-1,apple-3,can-0])
% puzzle([red-1,white-1,yellow-4],[apple-1,h-1,can-0,c-0])
% puzzle([red-1,white-1,yellow-5],[apple-1,h-0,can-2,c-0])
% puzzle([red-1,white-1,pink-1,yellow-1],[apple-1,h-1,c-1,can-3])
% puzzle([red-1,white-1,pink-4],[c-1,can-2,h-0,apple-1])
% puzzle([red-1,white-1,pink-5,yellow-1],[c-1,can-0,h-1,apple-3])
% puzzle([red-1,white-1,black-3,yellow-3],[h-1,c-1,can-2,apple-2])
% puzzle([red-1,white-1,black-4,yellow-1],[h-1,c-1,apple-1,can-2])
% puzzle([red-1,white-2,yellow-1],[apple-1,can-1,c-1,h-0])
% puzzle([red-1,white-2,pink-4],[c-3,can-3,h-1,apple-1])
% puzzle([red-1,white-2,pink-4,yellow-1],[apple-3,can-2,h-1,c-1])
% puzzle([red-1,white-2,pink-4,yellow-2],[apple-3,can-0,h-1,c-1])
% puzzle([red-1,white-2,pink-5],[c-1,apple-2,h-1,can-3])
% puzzle([red-1,white-2,black-2,yellow-3],[h-1,apple-1,can-2,c-0])
% puzzle([red-1,white-2,black-2,yellow-4],[h-1,apple-3,can-2,c-0])
% puzzle([red-1,white-2,black-2,pink-2,yellow-2],[h-1,can-0,apple-1,c-0])
% puzzle([red-1,white-3],[h-0,can-1,c-1,apple-3])
% puzzle([red-1,white-3,yellow-2],[apple-1,can-1,h-0,c-0])
% puzzle([red-1,white-3,pink-1,yellow-3],[c-1,apple-3,can-2,h-1])
% puzzle([red-1,white-3,pink-3,yellow-1],[c-1,can-0,apple-1,h-1])
% puzzle([red-1,white-3,pink-4],[c-1,can-3,h-1,apple-1])
% puzzle([red-1,white-3,black-3,yellow-1],[h-1,can-3,apple-3,c-0])
% puzzle([red-1,white-4,pink-3],[c-1,can-3,h-1,apple-2])
% puzzle([red-1,white-4,black-1,yellow-1],[h-0,can-3,apple-3,c-0])
% puzzle([red-1,white-4,black-2,yellow-1],[h-1,can-1,apple-1,c-0])
% puzzle([red-1,white-5,pink-2,yellow-1],[apple-3,can-3,h-1,c-0])
% puzzle([red-2,yellow-5],[apple-1,h-0,can-2,c-1])
% puzzle([red-2,pink-1,yellow-2],[c-3,h-1,can-0,apple-3])
% puzzle([red-2,pink-2,yellow-3],[apple-1,can-0,h-0,c-1])
% puzzle([red-2,black-1,pink-4],[c-3,apple-2,h-1,can-0])
% puzzle([red-2,black-3,yellow-3],[h-1,c-1,can-2,apple-3])
% puzzle([red-2,black-3,pink-1,yellow-2],[h-1,c-0,can-2,apple-1])
% puzzle([red-2,black-4,yellow-2],[h-1,c-0,can-2,apple-0])
% puzzle([red-2,black-5],[h-1,c-0,apple-3,can-0])
% puzzle([red-2,white-1,yellow-1],[can-2,h-0,c-1,apple-2])
% puzzle([red-2,white-1,yellow-4],[apple-1,h-1,can-2,c-0])
% puzzle([red-2,white-1,pink-1],[can-2,apple-0,c-1,h-1])
% puzzle([red-2,white-1,black-1,pink-4],[c-1,apple-2,h-1,can-0])
% puzzle([red-2,white-1,black-2,yellow-4],[h-1,apple-3,can-2,c-1])
% puzzle([red-2,white-1,black-2,pink-1,yellow-3],[h-1,apple-2,can-2,c-0])
% puzzle([red-2,white-1,black-2,pink-2,yellow-2],[h-1,can-0,apple-1,c-1])
% puzzle([red-2,white-1,black-3,yellow-2],[h-1,c-0,can-2,apple-2])
% puzzle([red-2,white-1,black-4,yellow-1],[h-1,c-1,apple-1,can-0])
% puzzle([red-2,white-2],[can-2,apple-1,c-1,h-1])
% puzzle([red-2,white-2,black-2,pink-2],[apple-3,c-0,h-1,can-0])
% puzzle([red-2,white-2,black-3],[h-1,can-3,c-3,apple-0])
% puzzle([red-2,white-2,black-3,yellow-1],[h-1,can-3,apple-3,c-1])
% puzzle([red-2,white-3,yellow-2],[apple-1,can-3,h-0,c-0])
% puzzle([red-2,white-3,yellow-3],[apple-3,h-1,can-2,c-0])
% puzzle([red-2,white-3,pink-2,yellow-2],[can-0,apple-3,h-1,c-0])
% puzzle([red-2,white-3,pink-3],[c-1,can-3,h-1,apple-3])
% puzzle([red-2,white-3,black-2],[h-1,can-3,c-3,apple-2])
% puzzle([red-2,white-4,pink-2,yellow-1],[apple-3,can-3,h-1,c-1])
% puzzle([red-2,white-4,black-2,yellow-1],[h-1,can-3,apple-1,c-0])
% puzzle([red-2,white-5],[apple-3,can-3,c-3,h-1])
% puzzle([red-2,white-5,pink-1],[c-1,can-3,apple-1,h-1])
% puzzle([red-3,yellow-1],[can-2,h-0,c-1,apple-3])
% puzzle([red-3,yellow-4],[apple-1,h-1,can-2,c-1])
% puzzle([red-3,pink-2,yellow-2],[c-3,apple-2,can-2,h-0])
% puzzle([red-3,black-1],[can-2,h-1,c-1,apple-0])
% puzzle([red-3,black-1,yellow-2],[can-2,h-0,apple-3,c-1])
% puzzle([red-3,black-1,pink-3],[can-2,c-0,h-1,apple-1])
% puzzle([red-3,black-2,pink-1,yellow-3],[h-1,apple-2,can-2,c-1])
% puzzle([red-3,black-3,yellow-2],[h-1,c-0,can-2,apple-3])
% puzzle([red-3,black-3,pink-1],[h-1,apple-2,c-3,can-0])
% puzzle([red-3,white-1,pink-2,yellow-1],[can-2,apple-1,h-1,c-1])
% puzzle([red-3,white-1,black-1,pink-2,yellow-1],[can-0,c-1,h-1,apple-3])
% puzzle([red-3,white-1,black-1,pink-3],[can-0,c-0,h-1,apple-1])
% puzzle([red-3,white-1,black-2,pink-2],[can-0,c-0,h-1,apple-0])
% puzzle([red-3,white-1,black-4],[h-1,c-0,apple-1,can-0])
% puzzle([red-3,white-2,yellow-3],[apple-3,h-1,can-2,c-1])
% puzzle([red-3,white-2,pink-2,yellow-1],[can-0,apple-1,h-1,c-1])
% puzzle([red-3,white-2,pink-2,yellow-2],[can-0,apple-3,h-1,c-1])
% puzzle([red-3,white-2,pink-3,yellow-1],[can-0,apple-2,h-1,c-0])
% puzzle([red-3,white-2,black-1,pink-2],[can-0,c-0,h-1,apple-2])
% puzzle([red-3,white-3,black-2,yellow-1],[h-1,can-3,apple-1,c-1])
% puzzle([red-3,white-4],[apple-3,can-3,c-3,h-0])
% puzzle([red-3,white-4,pink-1],[c-1,can-3,apple-1,h-0])
% puzzle([red-4],[can-2,h-1,c-1,apple-3])
% puzzle([red-4,yellow-1],[can-2,h-0,c-3,apple-3])
% puzzle([red-4,pink-3,yellow-1],[can-2,apple-2,h-1,c-1])
% puzzle([red-4,black-1,pink-1],[can-2,c-0,h-0,apple-1])
% puzzle([red-4,black-1,pink-2],[can-2,c-0,h-1,apple-3])
% puzzle([red-4,white-1,pink-3,yellow-1],[can-0,apple-2,h-1,c-1])
% puzzle([red-4,white-1,black-1,pink-1],[can-0,c-0,h-0,apple-1])
% puzzle([red-4,white-1,black-1,pink-2],[can-0,c-0,h-1,apple-3])
% puzzle([red-4,white-2,pink-1],[can-0,apple-2,c-3,h-1])
% puzzle([red-4,white-2,pink-1,yellow-1],[can-0,apple-2,h-0,c-0])
% puzzle([red-4,white-3,yellow-1],[can-0,h-1,apple-1,c-0])
% puzzle([red-4,white-3,black-1],[can-0,c-0,apple-1,h-1])
% puzzle([red-5],[can-2,h-1,c-3,apple-3])
% puzzle([red-5,pink-1],[can-2,apple-2,c-3,h-0])
% puzzle([red-5,pink-1,yellow-1],[can-2,apple-2,h-0,c-1])
% puzzle([red-5,black-1],[can-2,c-0,h-0,apple-3])
% puzzle([red-5,white-1],[can-0,h-1,c-3,apple-3])
% puzzle([red-5,white-1,yellow-1],[can-2,h-1,apple-1,c-1])
% puzzle([red-5,white-1,pink-1],[can-0,apple-2,c-3,h-0])
% puzzle([red-5,white-1,pink-1,yellow-1],[can-0,apple-2,h-0,c-1])
% puzzle([red-5,white-2,yellow-1],[can-0,h-1,apple-1,c-1])
% puzzle([red-5,white-2,black-1],[can-0,c-0,apple-1,h-0])
% N = 169

% What are the puzzles using the least number of bugs?
% There are several "official" puzzles with 3 bugs.
% Is there (an unambiguous) one with less?

n_bugs(N, Puzzle-Solution) :-
    maximum(Max),
    maplist(take_some, Max, Bugs),
    remove_zeros(Bugs, Puzzle),
    bug_count(Puzzle, N),
    findall(S, solve(Puzzle, S), [Solution]).

bug_count([], 0).
bug_count([_-K|Bugs], N) :- bug_count(Bugs, N0), N is N0 + K.

% ?- n_bugs(2, P-S).
% false.

% ?- findall(P, n_bugs(3,P-_), Puzzles), length(Puzzles, N).
% Puzzles = [[pink-1,yellow-2],            N/A
%            [black-1,yellow-2],           N/A
%            [white-1,pink-2],             #11
%            [white-1,black-1,pink-1],     #20
%            [white-2,pink-1],             N/A
%            [white-2,black-1],            N/A
%            [red-1,pink-1,yellow-1],      #18
%            [red-1,black-1,yellow-1]]     #22
% N = 8

% How about puzzles with all bug types?
% And preferably with a small number of bugs
% (so it may be more "difficult"...?)

k_types(K, N, Puzzle-Solution) :-
    maximum(Max),
    maplist(take_some, Max, Bugs),
    remove_zeros(Bugs, Puzzle),
    length(Puzzle, K),
    bug_count(Puzzle, N),
    findall(S, solve(Puzzle, S), [Solution]).

% ?- between(5, 9, N), k_types(5, N, P).
% N = 8,
% P = [red-3, white-1, black-1, pink-2, yellow-1]-[can-0, c-1, h-1, apple-3] ; #48
% N = 9,
% P = [red-1, white-2, black-2, pink-2, yellow-2]-[h-1, can-0, apple-1, c-0] ; N/A
% N = 9,
% P = [red-2, white-1, black-2, pink-1, yellow-3]-[h-1, apple-2, can-2, c-0] ; #37
% N = 9,
% P = [red-2, white-1, black-2, pink-2, yellow-2]-[h-1, can-0, apple-1, c-1] ; N/A
% false.

% So yes, it seems that this is a good definition of difficulty.
% Let's see those with 4 different bug types:

% ?- between(4, 7, N), k_types(4, N, P).
% N = 4,
% P = [red-1, white-1, pink-1, yellow-1]-[apple-1, h-1, c-1, can-3] ;   N/A
% N = 7,
% P = [white-1, black-2, pink-1, yellow-3]-[h-1, apple-0, can-0, c-0] ; N/A
% N = 7,
% P = [white-1, black-4, pink-1, yellow-1]-[h-1, c-1, apple-3, can-3] ; N/A
% N = 7,
% P = [red-1, white-1, black-4, yellow-1]-[h-1, c-1, apple-1, can-2] ;  N/A
% N = 7,
% P = [red-1, white-4, black-1, yellow-1]-[h-0, can-3, apple-3, c-0] ;  #46
% N = 7,
% P = [red-3, white-1, pink-2, yellow-1]-[can-2, apple-1, h-1, c-1] ;   N/A
% N = 7,
% P = [red-4, white-1, black-1, pink-1]-[can-0, c-0, h-0, apple-1] ;    N/A
% false.

% For N = 8 there are 24 good puzzles, including #45.
% A low bug count (like the first solution above) would be easy,
% but 7-8 bugs should be complex enough.

% Let's see the statistics for some of the "master" puzzles:
% |----------+-----------+-----------|
% | Puzzle # | Bug types | Bug count |
% |----------+-----------+-----------|
% |       37 |         5 |         9 |
% |       38 |         3 |         6 |
% |       39 |         3 |         7 |
% |       40 |         3 |         6 |
% |       41 |         3 |         7 |
% |       42 |         3 |         6 |
% |       43 |         3 |         7 |
% |       44 |         3 |         7 |
% |       45 |         4 |         8 |
% |       46 |         4 |         7 |
% |       47 |         3 |         7 |
% |       48 |         5 |         8 |
% |----------+-----------+-----------|

% So difficult puzzles have 3-5 types with 6-8 bugs (or 9 with 5 types).
% How many such puzzles are there?

% ?- findall(P, (between(3, 4, K),
%                between(6, 8, N),
%                k_types(K, N, P)),
%            All),
%    length(All, N).
% N = 93.

% That's a bit too many, let's restrict it to K = 3, N = 7.
% This covers #39, #41, #43, #44, and #47,
% as well as #27, #32 - but none of the simple puzzles,
% so these should be considered hard.

% ?- findall(P, k_types(3, 7, P), All), length(All, N).
% N = 27.

% Puzzles with only one bug type are simple. Let's see the variations!
% All = [[white-4]-[h-0,can-1,c-1,apple-2],  #3
%        [red-4]-[can-2,h-1,c-1,apple-3],    N/A
%        [pink-5]-[c-3,apple-0,h-1,can-1],   #2
%        [white-5]-[apple-3,can-1,c-1,h-1],  N/A
%        [red-5]-[can-2,h-1,c-3,apple-3],    #1
%        [pink-6]-[c-3,can-2,h-1,apple-1]]   N/A

% So there is no valid (unambiguous) puzzle with only black or yellow!

% One last question: how many valid puzzle has 9 bugs?
% ?- findall(P, n_bugs(9, P), All), length(All, N).
% All = [[white-3, pink-4, yellow-2]-[apple-3, can-0, h-1, c-0],
%        [red-1,white-2,pink-4,yellow-2]-[apple-3,can-0,h-1,c-1],
%        [red-1,white-2,black-2,yellow-4]-[h-1,apple-3,can-2,c-0],
%        [red-1,white-2,black-2,pink-2,yellow-2]-[h-1,can-0,apple-1,c-0],
%        [red-1,white-5,pink-2,yellow-1]-[apple-3,can-3,h-1,c-0],
%        [red-2,white-1,black-2,yellow-4]-[h-1,apple-3,can-2,c-1],
%        [red-2,white-1,black-2,pink-1,yellow-3]-[h-1,apple-2,can-2,c-0],   #37
%        [red-2,white-1,black-2,pink-2,yellow-2]-[h-1,can-0,apple-1,c-1],
%        [red-2,white-3,pink-2,yellow-2]-[can-0,apple-3,h-1,c-0],           #17
%        [red-2,white-4,pink-2,yellow-1]-[apple-3,can-3,h-1,c-1],
%        [red-2,white-4,black-2,yellow-1]-[h-1,can-3,apple-1,c-0],
%        [red-3,black-2,pink-1,yellow-3]-[h-1,apple-2,can-2,c-1],
%        [red-3,white-2,pink-2,yellow-2]-[can-0,apple-3,h-1,c-1],
%        [red-3,white-2,pink-3,yellow-1]-[can-0,apple-2,h-1,c-0],
%        [red-3,white-3,black-2,yellow-1]-[h-1,can-3,apple-1,c-1],          #21
%        [red-4,white-1,pink-3,yellow-1]-[can-0,apple-2,h-1,c-1]]
% N = 16.

% In conclusion, I would consider adding as new:
%
% - "simple" puzzles:
% [red-4]   (1/4)
% [white-5] (1/5)
% [pink-6]  (1/6)
%
% - "9-bug" puzzles with no bug appearing 4 times:
% [red-1,white-2,black-2,pink-2,yellow-2] (5/9)
% [red-2,white-1,black-2,pink-2,yellow-2] (5/9)
% [red-3,black-2,pink-1,yellow-3] (4/9)
% [red-3,white-2,pink-2,yellow-2] (4/9)
% [red-3,white-2,pink-3,yellow-1] (4/9)
%
% - other "difficult" puzzles:
% [red-1,white-1,pink-1,yellow-1]   (4/7)
% [white-1,black-2,pink-1,yellow-3] (4/7)
% [white-1,black-4,pink-1,yellow-1] (4/7)
% [red-1,white-1,black-4,yellow-1]  (4/7)
% [red-3,white-1,pink-2,yellow-1]   (4/7)
% [red-4,white-1,black-1,pink-1]    (4/7)