import math
import random
import time


############################################################
# generating all combinations
############################################################


# pre-lecture code
def make_subset(items):
    # base case
    if len(items) == 0:
        return ...  # TODO

    # recursive case
    first, rest = items[0], items[1:]
    if random.random() < 0.5:
        return make_subset(rest)
    else:
        return {first} | make_subset(rest)


def test_make_subset():
    sequence = [1, 2, 3, 4]
    for _ in range(10):
        print(make_subset(sequence))


# print()
# test_make_subset()


def powerset(items):
    # base case
    if len(items) == 0:
        return [set()]

    # recursive decomposition
    first, rest = items[0], items[1:]

    # all subsets without first
    combos_without = powerset(rest)

    # all subsets with first
    combos_with = []
    for combo in powerset(rest):
        combos_with.append({first} | combo)

    return combos_without + combos_with


def test_powerset():
    max_size = 4
    for k in range(1, max_size + 1):
        sequence = list(range(1, k + 1))
        print(powerset(sequence))


# print()
# test_powerset()


def subsets_with_size(items, size):
    return [combo for combo in powerset(items) if len(combo) == size]


def test_subset_size():
    max_size = 5
    subset_size = 2
    for k in range(1, max_size + 1):
        print(f"generating subsets from {k} items")
        sequence = list(range(1, k + 1))
        print(subsets_with_size(sequence, subset_size))


# print()
# test_subset_size()


############################################################
# pruning in decision trees
############################################################


def subsets_with_size(items, size):
    # base case
    if len(items) == 0:
        if size == 0:
            return [ [] ]
        else:
            return []

    # pruning
    ...  # TODO

    # recursive decomposition
    first, rest = items[0], items[1:]

    # all subsets without first
    combos_without = subsets_with_size(rest, size)

    # all subsets with first
    combos_with = [[first] + combo for combo in subsets_with_size(rest, size - 1)]

    return combos_without + combos_with


def test_subset_size():
    max_size = 5
    subset_size = 2
    for k in range(1, max_size + 1):
        print(f"generating subsets from {k} items")
        sequence = list(range(1, k + 1))
        print(subsets_with_size(sequence, subset_size))


# print()
# test_subset_size()
