#coding: cp852
#######################################
# Krtka implementacja merge sort z pokazem stabilnoci.
#######################################

def merge(L,R):
  '''czy listy L i R z zachowaniem porzdku.'''
  (i,j)=[0]*2							# Ustawia pocztkowe pooenia obu wskanikw dla lewej i prawej listy. [0]*2=> [0,0] i dalej (i,j)=[0,0] jest rwnowane do i=0  oraz j=0. Oba wskazuj na pierwsze elementy list.
  LL=len(L)							# Ustala dugo lewej czci.
  LR=len(R)                                                     # Ustala dugo prawej czci.
  RES=[]     							# pusty pojemnik na wyniki.
  while i<LL and j<LR:						# Dopki wskaniki s przed ko=cami list. Jeli cho jedna lista jest pusta - koczy.
    if L[i][0]<=R[j][0]:					# Jeli pocztkowy element lewej listy ma zasadnicz warto nie wiksz od pierwszego prawej.
      RES+=[L[i]]						# Do wyniku dodaje pierwszy element lewej listy.
      i+=1							# Wskanik idze do kolejnego elementu.
    else:							# jeli jest wiekszy.
      RES+=[R[j]]						# To samo z praw list.
      j+=1
  RES+=L[i:]+R[j:]						# Do wyniku dodaje nie zakoczon list.
  return RES                 					# Zwraca wynik.


def merge_sort(T):
  '''Sortuje list t przez czenie.'''
  L=len(T)							# Ustala dugo listy.
  if L<=1:							# Jeli nie ma wicej ni 1 element - jest pusta lub jednoelementowa - jest uporzdkowana.
    return T							# Zwraca j.
  i=L//2                    					# Ustala rodek listy.
  return merge(merge_sort(T[:i]),merge_sort(T[i:]))		# czy posortowane merge_sort-em lew i praw powk.



L1=[(5,0),(4,0),(6,0),(2,0),(33,0),(5,1),(22,0),(28,0),(55,0),(5,2),(37,0),(39,0),(49,0),(57,0)]
print(f'Przed sortowaniem {L1=}')
L2=merge_sort(L1)
print(f'Po sortowaniu {L2=}')

