# Finding Best Candidates for the Job
import random

required = [8, 7, 9, 6]

candidates = [
    [7, 8, 8, 6],
    [9, 6, 7, 5],
    [8, 7, 9, 6],
    [6, 5, 8, 7],
    [9, 9, 8, 6]
]

size = 30
generations = 100
mutation = 0.1

def fitness(x):
    return sum(10-abs(x[i]-required[i]) for i in range(4))

def create():
    return [random.choice(candidates).copy() for _ in range(size)]

def select(pop):
    return max(random.sample(pop,3), key=fitness)

def crossover(a,b):
    p = random.randint(1,3)
    return a[:p]+b[p:]

def mutate(x):
    i = random.randint(0,3)
    x[i] = random.randint(1,10)
    return x

pop = create()

for gen in range(generations):
    pop.sort(key=fitness, reverse=True)
    best = pop[0]

    new = [best]
    while len(new) < size:
        child = crossover(select(pop),select(pop))
        if random.random() < mutation:
            child = mutate(child)
        new.append(child)

    pop = new

best = max(pop, key=fitness)

print("Best Candidate Skills:", best)
print("Required Skills:", required)
print("Fitness Score:", fitness(best))
