input: Write a python function to implement a genetic algorithm with elitism. 
  assert genetic_algorithm(lambda x: x**2, 10, 5, 0.2) <= 10000
  assert genetic_algorithm(lambda x: -x, 20, 10, 0.3) <= 0
  assert genetic_algorithm(lambda x: x, 15, 8, 0.1) <= 100
output: import random
  
  def genetic_algorithm(fitness_func, population_size, num_generations, mutation_rate):
      def initialize_population():
          return [random.uniform(-100, 100) for _ in range(population_size)]
      
      def select_parents(population):
          sorted_population = sorted(population, key=fitness_func, reverse=True)
          return sorted_population[:population_size//2]
      
      def crossover(parents):
          offspring = []
          while len(offspring) < population_size:
              parent1, parent2 = random.sample(parents, 2)
              cross_point = random.randint(1, len(str(parent1))-1)
              child = float(str(parent1)[:cross_point] + str(parent2)[cross_point:])
              offspring.append(child)
          return offspring
      
      def mutate(individual):
          if random.random() < mutation_rate:
              mutation_value = random.uniform(-1, 1)
              individual += mutation_value
          return individual
      
      population = initialize_population()
      
      for _ in range(num_generations):
          parents = select_parents(population)
          offspring = crossover(parents)
          population = [mutate(individual) for individual in offspring]
      
      best_individual = max(population, key=fitness_func)
      return best_individual