import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

final class Combinacoes {

    private static final class Volante {
        private final Set<Integer> numeros;

        public Volante(int... valores) {
            this.numeros = IntStream.of(valores).boxed().collect(Collectors.toCollection(TreeSet::new));
        }

        public int dissimilaridade(Volante outro) {
            List<Integer> interseccao = new ArrayList<>(numeros);
            interseccao.removeAll(outro.numeros);
            return interseccao.size();
        }

        @Override
        public String toString() {
            return numeros.toString();
        }
    }

    public static List<Volante> busca(int quantidade, int numeros) {
    	List<Volante> volantes = new ArrayList<>();
        busca(volantes, new int[quantidade], 0, numeros - quantidade, 0);
        return volantes;
    }

    private static void busca(List<Volante> volantes, int[] resultado, int inicio, int fim, int profundidade) {
        for (int x = inicio; x <= fim; x++) {
            resultado[profundidade] = x + 1;
            if (profundidade + 1 >= resultado.length) {
                volantes.add(new Volante(resultado));
            } else {
                busca(volantes, resultado, x + 1, fim + 1, profundidade + 1);
            }
        }
    }  

    private static List<Volante> limitarSimilaridade(List<Volante> volantes, int dissimilaridadeMinima) {
    	List<Volante> dissimilares = new ArrayList<>(volantes.size());

        externo:
        for (Volante volante : volantes) {
            for (Volante dejaVu : dissimilares) {
                if (volante.dissimilaridade(dejaVu) < dissimilaridadeMinima) continue externo;
            }
            dissimilares.add(volante);
        }
        return dissimilares;
    }

    public static void main(String[] args) { 
        List<Volante> volantes = busca(6, 10);
        System.out.println(volantes.toString().replace("], ", "]\n"));
        System.out.println("Total de combinacoes: " + volantes.size());

        List<Volante> filtrados = limitarSimilaridade(volantes, 2);
        System.out.println("Tamanho final: " + filtrados.size());
        System.out.println("Resultado final");
        System.out.println(filtrados.toString().replace("], ", "]\n"));
    }  
}