text: from itertools import takewhile
  def groupby(ls):
      d = {}
      ls = [ y[0] for y in rules ]
      initial = list(set(ls))
      for y in initial:
          for i in rules:
              if i.startswith(y):
                  if y not in d:
                      d[y] = []
                  d[y].append(i)
      return d
  
  def prefix(x):
      return len(set(x)) == 1
  
  
  starting=""
  rules=[]
  common=[]
  alphabetset=["A'","B'","C'","D'","E'","F'","G'","H'","I'","J'","K'","L'","M'","N'","O'","P'","Q'","R'","S'","T'","U'","V'","W'","X'","Y'","Z'"]
  
  
  s= "S->iEtS|iEtSeS|a"
  while(True):
      rules=[]
      common=[]
      split=s.split("->")
      starting=split[0]
      for i in split[1].split("|"):
          rules.append(i)
  
  #logic for taking commons out
      for k, l in groupby(rules).items():
          r = [l[0] for l in takewhile(prefix, zip(*l))]
          common.append(''.join(r))
  #end of taking commons
      for i in common:
          newalphabet=alphabetset.pop()
          print(starting+"->"+i+newalphabet)
          index=[]
          for k in rules:
              if(k.startswith(i)):
                  index.append(k)
          print(newalphabet+"->",end="")
          for j in index[:-1]:
              stringtoprint=j.replace(i,"", 1)+"|"
              if stringtoprint=="|":
                  print("\u03B5","|",end="")
              else:
                  print(j.replace(i,"", 1)+"|",end="")
          stringtoprint=index[-1].replace(i,"", 1)+"|"
          if stringtoprint=="|":
              print("\u03B5","",end="")
          else:
              print(index[-1].replace(i,"", 1)+"",end="")
          print("")
      break
  