'''Тема урока: функции с возвратом значения
Функции с возвратом значения
Решение задач
Аннотация. Функции могут не только принимать и не принимать параметры, как в примерах предыдущих уроков, но и
возвращать значения. Рассмотрим этот особый тип функций - с возвратом значения.

Функция с возвратом значения
Функция с возвратом значения похожа на функцию без возврата значения тем, что:

это набор инструкций, выполняющий определенную задачу;
когда нужно выполнить функцию, ее вызывают.
Однако когда функция с возвратом значения завершается, она возвращает значение в ту часть программы, которая ее
вызвала. Возвращаемое из функции значение используется как любое другое: оно может быть присвоено переменной,
 выведено на экран, использовано в математическом выражении (если это число) и т. д.

    Функция с возвратом значения возвращает значение обратно в ту часть программы, которая ее вызвала.

Мы уже сталкивались со многими функциями с возвратом значений:

функция int() – преобразует строку к целому числу и возвращает его;
функция float() – преобразует строку к вещественному числу и возвращает его;
функция range() – возвращает последовательность целых чисел 0, 1, 2, ...;
функция abs() – возвращает абсолютное значение числа (модуль числа);
функция len() – возвращает длину строки или списка.
Функцию с возвратом значения пишут точно так же, как и без, но она должна иметь инструкцию return.

Вот общий формат определения функции с возвратом значения в Python:

def название_функции():
    блок кода
    return выражение
В функции должна быть инструкция return, принимающая форму:

return выражение
Значение выражения, которое следует за ключевым словом return, будет отправлено в ту часть программы, которая
вызвала функцию. Это может быть переменная либо выражение, к примеру, математическое.

  Функция с возвратом значения имеет инструкцию return, возвращающую значение в ту часть программы,  которая ее вызвала.

При изучении вещественных чисел мы решали задачу о переводе градусов по шкале Фаренгейта в градусы по шкале Цельсия по
 формуле C = \dfrac{5}{9}\left(F - 32\right)C=
9
5
​
 (F− 32).

Напишем функцию, которая осуществляет перевод:

def convert_to_celsius(temp):
    result = (5 / 9) * (temp - 32)
    return result
Задача этой функции — принять одно число temp в качестве аргумента – количество градусов по шкале Фаренгейта, и
вернуть другое — количество градусов по шкале Цельсия.

Рассмотрим ее работу. Первая инструкция в блоке функции присваивает значение (5 / 9) * (temp - 32) переменной
result. Затем исполняется инструкция return, которая приводит к завершению исполнения функции и отправляет значение
из переменной result, назад в ту часть программы, которая вызвала эту функцию.

# функция перевода градусов Фаренгейта в градусы Цельсия
def convert_to_celsius(temp):
    result = (5 / 9) * (temp - 32)
    return result

# основная программа
temp = float(input('Bвeдитe количество градусов по Фаренгейту: '))
celsius = convert_to_celsius(temp)
print(celsius)  # градусы Цельсия
Основная программа получает от пользователя одно число – значение в градусах Фаренгейта, и вызывает функцию,
 передавая значение переменной temp в качестве аргумента. Значение, которое возвращается из функции
 convert_to_celsius, присваивается переменной celsius.





Использование инструкции return по максимуму
Взглянем еще раз на функцию convert_to_celsius():

def convert_to_celsius(temp):
    result = (5 / 9) * (temp - 32)
    return result
Обратите внимание, что внутри этой функции происходят две вещи: во-первых, переменной result присваивается
 значение выражения (5 / 9) * (temp - 32), и во-вторых, значение переменной result возвращается из функции.
 Эта функция хорошо справляется с поставленной перед ней задачей, но ее можно упростить. Поскольку инструкция
  return возвращает значение выражения, переменную result устраняем и переписываем функцию так:

def convert_to_celsius(temp):
    return (5 / 9) * (temp - 32)
Эта версия функции не сохраняет значение (5 / 9) * (temp - 32) в отдельной переменной, а сразу возвращает
значение выражения с помощью инструкции return. Делает то же, что и предыдущая версия, но за один шаг.

Использование нескольких return
В одной функции может быть сколько угодно инструкций return. Рассмотрим функцию convert_grade(), которая переводит
стобалльную оценку в пятибалльную:

def convert_grade(grade):
    if grade >= 90:
        return 5
    elif grade >= 80:
        return 4
    elif grade >= 70:
        return 3
    elif grade >= 60:
        return 2
    else:
        return 1

# основная программа
grade = int(input('Введите вашу отметку по 100-балльной системе: '))
print(convert_grade(grade))
В функции convert_grade() используется 5 инструкций return. Каждая из них возвращает соответствующее значение и
завершает работу функции.

Функцию convert_grade() можно переписать с помощью одной инструкции return:

def convert_grade(grade):
    result = -1
    if grade >= 90:
        result = 5
    elif grade >= 80:
        result = 4
    elif grade >= 70:
        result = 3
    elif grade >= 60:
        result = 2
    else:
        result = 1

    return result
Примечания
Примечание 1. Функции с возвратом значения предоставляют те же преимущества, что функции без возврата значения:

упрощают программный код;
уменьшают дублирование кода;
упрощают тестирование кода;
увеличивают скорость разработки;
способствуют работе в команде.
Примечание 2. Графическая интерпретация работы функции с возвратом значения:



Примечание 3. result – хорошее название для переменной, значение которой возвращается из функции.
'''

# функция перевода градусов Фаренгейта в градусы Цельсия
# def convert_to_celsius(temp):
#     result = (5 / 9) * (temp - 32)
#     return result
#
# # основная программа
# temp = float(input('Bвeдитe количество градусов по Фаренгейту: '))
# celsius = convert_to_celsius(temp)
# print(celsius)  # градусы Цельсия


'''Решение задач
Задача 1. Напишите функцию, которая возвращает длину гипотенузы прямоугольного треугольника по известным значениям 
его катетов.

Решение. Для нахождения длины гипотенузы, нам нужно применить теорему Пифагора: квадрат гипотенузы прямоугольного 
треугольника, равен сумме квадратов его катетов. Другими словами, если a, ba,b – длины катетов, а cc – длина 
гипотенузы, то имеет место равенство:
c^2 = a^2 + b^2 c = sqrt{a^2+b^2}.

Функция, вычисляющая длину гипотенузы, может иметь вид:

def compute_hypotenuse(a, b):
    c = (a ** 2 + b ** 2) ** 0.5
    return c
 Для извлечения квадратного корня мы использовали оператор возведения в степень. Напомним, что результатом обоих 
 выражений: math.sqrt(c) и c ** 0.5 является одно число sqrt{c} 

Следующий программный код:

print(compute_hypotenuse(3, 4))
print(compute_hypotenuse(5, 12))
print(compute_hypotenuse(1, 1))
выведет:

5.0                   # длина гипотенузы треугольника с катетами 3 и 4
13.0                  # длина гипотенузы треугольника с катетами 5 и 12
1.4142135623730951    # длина гипотенузы треугольника с катетами 1 и 1
Если нужно передать программе числа, считанные с клавиатуры, то мы пишем следующий код:

x = int(input())
y = int(input())

hypotenuse = compute_hypotenuse(x, y)

print(hypotenuse)
В модуле math имеется встроенная функция hypot(x, у) которая возвращает длину гипотенузы прямоугольного треугольника 
с катетами x и y.

Одним из основных преимуществ функций является возможность их повторного использования для решения похожих задач. 
Рассмотрим задачу нахождения расстояния между двумя точками.

Задача 2. Напишите функцию get_distance(x1, y1, x2, y2), вычисляющую расстояние между точками (x_1;  y_1)(x_2;  y_2)(
Решение. Расстояние между двумя точками (x_{1}; y_{1}) определяется по формуле
\rho = \sqrt{(x_1-x_2)^2 + (y_1-y_2)^2}



Несложно заметить, что искомое расстояние – это длина гипотенузы прямоугольного треугольника с катетами равными 
|x_1 - x_2|∣x 

Функция, вычисляющая расстояние между точками, может иметь вид:

def get_distance(x1, y1, x2, y2):
    return compute_hypotenuse(x1 - x2, y1 - y2)
Для подсчета искомого расстояния мы используем уже созданную нами функцию compute_hypotenuse передавая ей в качестве 
аргументов числа x1 - x2 и y1 - y2.

Основная программа имеет вид:

x1, y1 = float(input()), float(input())  # считываем координаты первой точки
x2, y2 = float(input()), float(input())  # считываем координаты второй точки

print(get_distance(x1, y1, x2, y2))      # вычисляем и выводим расстояние между точками
Задача 3. Напишите функцию sum_digits(n), принимающую в качестве аргумента натуральное число и возвращающую сумму 
его цифр.

Решение. Функция sum_digits(n) может иметь вид:

def sum_digits(n):
    result = 0
    while n > 0:
        result += n % 10
        n //= 10
    return result
Основная программа имеет вид:

n = int(input())
print(sum_digits(n))      # вычисляем и выводим сумму цифр считанного числа
Задача 4. Напишите функцию compute_average(numbers), принимающую в качестве аргумента список чисел и возвращающую 
среднее значение элементов списка.

Решение. Для подсчета среднего значения элементов списка нужно вычислить сумму всех элементов и их количество, то есть 
использовать функции sum() и len(). Функция compute_average(numbers) может иметь вид:

def compute_average(numbers):
    return sum(numbers) / len(numbers)
Основная программа имеет вид:

numbers = [1, 3, 5, 1, 6, 8, 10, 2]
print(compute_average(numbers))      # вычисляем и выводим среднее значение элементов списка
Результатом работы такой программы будет число 4.5, которое и является средним значением.'''

# def do_something(number):
#     return number * 2
#
# print(do_something(10))
#
# def do_something(numbers):
#     result = 1
#     for i in numbers:
#         result *= i
#     return result
# print(do_something([2, 2, 2, 2]))

# def get_sum(x, y, z):
#     return x + y + z
#     print('Сумма равна', x + y + z)
# print(get_sum(1, 2, 3))

'''Конвертер километров
Напишите функцию convert_to_miles(km), которая принимает в качестве аргумента расстояние в километрах и возвращает расстояние в милях. Формула для преобразования: мили = километры * 0.6214.

Примечание. Следующий программный код:

print(convert_to_miles(1))
print(convert_to_miles(5))
print(convert_to_miles(10))
должен выводить:

0.6214
3.107
6.214'''
# объявление функции
# def convert_to_miles(km):
#     km = num * 0.6214
#     return km
# # считываем данные
# num = int(input())
#
# # вызываем функцию
# print(convert_to_miles(num))

'''Количество дней
Напишите функцию get_days(month), которая принимает в качестве аргумента номер месяца и возвращает количество дней 
в данном месяце.

Примечание 1. Гаранитируется, что передаваемый аргумент находится в диапазоне от 1 до 12.

Примечание 2. Считайте, что год является невисокосным.

Примечание 3. Следующий программный код:

print(get_days(1))
print(get_days(2))
print(get_days(9))
должен выводить:

31
28
30
'''

# # объявление функции
# def get_days(month):
#     if num == 2:
#         return 28
#     elif (num == 4) or (num == 6) or (num == 9) or (num == 11):
#         return 30
#     elif (num == 1) or (num == 3) or (num == 5) or (num == 7) or (num == 8) or (num == 10) or (num == 12):
#         return 31
#
#
# # считываем данные
# num = int(input())
#
# # вызываем функцию
# print(get_days(num))


'''Делители 1
Напишите функцию get_factors(num), принимающую в качестве аргумента натуральное число и возвращающую список всех 
делителей данного числа.

Примечание. Следующий программный код:

print(get_factors(1))
print(get_factors(5))
print(get_factors(10))
должен выводить:

[1]
[1, 5]
[1, 2, 5, 10]'''

# # объявление функции
# def get_factors(num):
#     num = []
#     for i in range(1, n + 1):
#         if n % i == 0:
#             num.append(i)
#     return num
#
# # считываем данные
# n = int(input())
#
# # вызываем функцию
# print(get_factors(n))
'''Делители 2
Напишите функцию number_of_factors(num), принимающую в качестве аргумента число и возвращающую количество делителей
 данного числа.

Примечание 1. Используйте уже реализованную функцию get_factors(num) из предыдущей задачи.

Примечание 2. Следующий программный код:

print(number_of_factors(1))
print(number_of_factors(5))
print(number_of_factors(10))
должен выводить:

1
2
4'''

# # объявление функции
# def get_factors(num):
#     num = []
#     count = 0
#     for i in range(1, n + 1):
#         if n % i == 0:
#             num.append(i)
#             count += 1
#     return count
#
#
# # считываем данные
# n = int(input())
#
# # вызываем функцию
# print(get_factors(n))


'''Найти всех
Напомним, что строковый метод find('a') возвращает местоположение первого вхождения символа a в строке. Проблема 
заключается в том, что данный метод не находит местоположение всех символов а.

Напишите функцию с именем find_all(target, symbol), которая принимает два аргумента: строку target и символ symbol и 
возвращает список, содержащий все местоположения этого символа в строке.

Примечание 1. Если указанный символ не встречается в строке, то следует вернуть пустой список.

Примечание 2. Следующий программный код:

print(find_all('abcdabcaaa', 'a'))
print(find_all('abcadbcaaa', 'e'))
print(find_all('abcadbcaaa', 'd'))
должен выводить:

[0, 4, 7, 8, 9]
[]
[4]'''

'''Найти всех
Напомним, что строковый метод find('a') возвращает местоположение первого вхождения символа a в строке. Проблема 
заключается в том, что данный метод не находит местоположение всех символов а.

Напишите функцию с именем find_all(target, symbol), которая принимает два аргумента: строку target и символ symbol и
 возвращает список, содержащий все местоположения этого символа в строке.

Примечание 1. Если указанный символ не встречается в строке, то следует вернуть пустой список.

Примечание 2. Следующий программный код:

print(find_all('abcdabcaaa', 'a'))
print(find_all('abcadbcaaa', 'e'))
print(find_all('abcadbcaaa', 'd'))
должен выводить:

[0, 4, 7, 8, 9]
[]
[4]'''
# def find_all(target, symbol):
#     num = []
#     for i in range(len(s)):
#         if target[i] == symbol:
#             num.append(i)
#     return num
#
#
# s = input()
# char = input()
#
# # вызываем функцию
#
# print(find_all(s, char))


'''Merge lists 1
Напишите функцию merge(list1, list2), которая принимает в качестве аргументов два отсортированных по возрастанию 
списка, состоящих из целых чисел, и объединяет их в один отсортированный список.

Примечание 1. Списки list1 и list2 могут иметь разную длину.

Примечание 2. Можно использовать списочный метод sort(), а можно обойтись и без него 😎.

Примечание 3. Следующий программный код:

print(merge([1, 2, 3], [5, 6, 7, 8]))
print(merge([1, 7, 10, 16], [5, 6, 13, 20]))
должен выводить:

[1, 2, 3, 5, 6, 7, 8]
[1, 5, 6, 7, 10, 13, 16, 20]'''

# объявление функции
# def merge(list1, list2):
#     i, j = 0, 0
#     res = []
#     while i < len(list1) and j < len(list2):
#         if list1[i] < list2[j]:
#             res.append(list1[i])
#             i += 1
#         else:
#             res.append(list2[j])
#             j += 1
#     res += list1[i:]
#     res += list2[j:]
#     # один из list1[i:] и list2[j:] будет уже пустой, поэтому добавится только нужный остаток
#     return res
#
# # считываем данные
# numbers1 = [int(c) for c in input().split()]
# numbers2 = [int(c) for c in input().split()]
#
# # вызываем функцию
# print(merge(numbers1, numbers2))
#
'''Слияние двух отсортированных списков
Слияние двух отсортированных списков в один — важная задача в информатике. Она естественно возникает при сортировке
 списков c использованием сортировки слиянием.

Пусть даны два отсортированных по возрастанию списка чисел list1 и list2:

list1 = [3, 10, 11, 12, 47, 57, 58, 63, 77, 79, 80, 95]
list2 = [0, 11, 12, 20, 24, 26, 47, 48, 53, 65, 70, 81, 84, 84, 90]
Простейшее решение задачи слияния списков использует списочный метод sort():

def merge(list1, list2):
    result = list1 + list2   # создаем результирующий список
    result.sort()            # сортируем список встроенным методом sort()
    return result            # возвращаем отсортированный список

list1 = [3, 10, 11, 12, 47, 57, 58, 63, 77, 79, 80, 95]
list2 = [0, 11, 12, 20, 24, 26, 47, 48, 53, 65, 70, 81, 84, 84, 90]
list3 = merge(list1, list2)  # вызываем функцию слияния двух отсортированных списков
print(list3)
Результатом работы такого кода будет список:

[0, 3, 10, 11, 11, 12, 12, 20, 24, 26, 47, 47, 48, 53, 57, 58, 63, 65, 70, 77, 79, 80, 81, 84, 84, 90, 95]
И хотя функция merge() полностью справляется с своей задачей, она абсолютно не учитывает то, что два списка list1 и
 list2 уже отсортированы.

Быстрое слияние двух отсортированных списков в один
Пусть мы имеем два уже отсортированных по возрастанию списка list1 и list2.

Алгоритм быстрого слияния следующий:

Создаем численные указатели p1 = 0 и p2 = 0 на начала обоих списков list1 и list2 соответственно;
На каждом шаге берем меньший из двух элементов list1[p1] и list2[p2];
Записываем его в результирующий список; 
Увеличиваем указатель на первый элемент списка (p1 или p2) из которого был взят элемент на 11;
Когда один из начальных списков закончился, добавляем все оставшиеся элементы второго списка в результирующий список.
def quick_merge(list1, list2):
    result = []

    p1 = 0  # указатель на первый элемент списка list1
    p2 = 0  # указатель на первый элемент списка list2

    while p1 < len(list1) and p2 < len(list2):  # пока не закончился хотя бы один список
        if list1[p1] <= list2[p2]:
            result.append(list1[p1])
            p1 += 1
        else:
            result.append(list2[p2])
            p2 += 1

    if p1 < len(list1):   # прицепление остатка
        result += list1[p1:]
    if p2 < len(list2):
        result += list2[p2:]
    
    return result
Следующий программный код:

list1 = [3, 10, 11, 12, 47, 57, 58, 63, 77, 79, 80, 95]
list2 = [0, 11, 12, 20, 24, 26, 47, 48, 53, 65, 70, 81, 84, 84, 90]
list3 = quick_merge(list1, list2)
print(list3)
выведет:

[0, 3, 10, 11, 11, 12, 12, 20, 24, 26, 47, 47, 48, 53, 57, 58, 63, 65, 70, 77, 79, 80, 81, 84, 84, 90, 95]'''

'''Merge lists 2
На вход программе подается число nn, а затем nn строк, содержащих целые числа в порядке возрастания. Из данных строк
 формируются списки чисел. Напишите программу, которая объединяет указанные списки в один отсортированный список с 
 помощью функции quick_merge(), а затем выводит его.

Формат входных данных
На вход программе подается натуральное число nn, а затем nn строк, содержащих целые числа в порядке возрастания,
 разделенные символом пробела.

Формат выходных данных
Программа должна вывести текст в соответствии с условием задачи.

Sample Input 1:

3
1 2 3 4
5 6 7
10 11 17
Sample Output 1:

1 2 3 4 5 6 7 10 11 17
Sample Input 2:

4
10 20
1 15
5 17
8 13 19
Sample Output 2:

1 5 8 10 13 15 17 19 20'''


def merge(*iters):
    for it in iters:
        yield from it


n = int(input())
arr = []
for i in range(n):
    arr.append([int(j) for j in input().split()])

print(*sorted(list(merge(*arr))))
