code: def hoist_mutation(self, random_state):
          
          # Get a subtree to replace
          start, end = self.get_subtree(random_state)
          subtree = self.program[start:end]
          # Get a subtree of the subtree to hoist
          sub_start, sub_end = self.get_subtree(random_state, subtree)
          hoist = subtree[sub_start:sub_end]
          # Determine which nodes were removed for plotting
          removed = list(set(range(start, end)) -
                         set(range(start + sub_start, start + sub_end)))
          return self.program[:start] + hoist + self.program[end:], removed
docs: Perform the hoist mutation operation on the program.
  
          Hoist mutation selects a random subtree from the embedded program to
          be replaced. A random subtree of that subtree is then selected and this
          is 'hoisted' into the original subtrees location to form an offspring.
          This method helps to control bloat.
  
          Parameters
          ----------
          random_state : RandomState instance
              The random number generator.
  
          Returns
          -------
          program : list
              The flattened tree representation of the program.