
"""
Сформувати функцію для обчислення індексу максимального елемента масиву n*n, де 1<=n<=5.

Виконав Іваненко Андрій Вадимович
"""

import numpy as np

""" У даному випадку для визначення функції доцільніше використати ітерації ніж рекурсію, оскільки
алгоритм функції визнеченої через рекурсію набагато складніший за алгоритм функції визнеченої через ітерації,
також він виконується за набагато більший час та займає більше пам'яті. """


def max_num_index1(a):  # Функція знаходження індексу максимального елементу заданого масиву (через ітерації)
    index = [0, 0]  # index - номер максимального елементу
    for i in range(len(a)):  # Цикли проходять по кожному елементу заданого масиву
        for j in range(len(a)):
            """ Якщо елемент з номером index менший за поточний елемент, 
            то змінюється значення індексу максимального елементу. """
            if a[index[0], index[1]] < a[i, j]:
                index = [i, j]
    return index


def max_num_index2(a):  # Функція знаходження індексу максимального елементу заданого масиву (через рекурсію)
    """ При першому проходженні функції виконається ділянка коду під if-ом, який розглядає багатовимірні масиви
    (об'єкти, які мають довжину більшу за одиницю та елементи яких також є масивами). В if-і знаходиться значення
    функції max_num_index від першого рядка масиву. Так як цей рядок є одновимірним масивом, то виконується код під
    першим elif-ом. В результаті його виконання відбувається порівняння першого елементу рядка зі значенням функції
    від зрізу [1:] цього рядка. Так як зріз масиву також є масивом, навіть якщо він складається з одного елементу, то
    при виклику зрізу з останнього елементу рядка виконується другий elif, який викликає функції вже від самого
    елемента, а не від зрізу. Значення else використовується для визначення індексів елементів Таким чином відбувається
    порівняння всіх елементів рядка та знаходиться індекс максимального елемента рядка. Алгоритм повертається до
    першого виклику функції. Далі відбувається виклик функції для зрізу [1:] початкового масиву. Оскільки такий зріз
    також буде масивом, то виконається ділянка коду під if-ом, якщо він складається з декількох рядків, або під другим
    elif-ом, якщо він містить у собі тільки один елемент, що є лінійним масивом. Таким чином знайдяться індекси
    максимальних елементів всіх рядків масиву, які будуть порівнюватись між собою, для знайдення максимального
    елементу масиву. """
    if len(a) > 1 and type(a[0]) == np.ndarray:
        i = [0, max_num_index2(a[0])[1]]
        j = [max_num_index2(a[1:])[0] + 1, max_num_index2(a[1:])[1]]
        return i if a[i[0], i[1]] > a[j[0], j[1]] else j
    elif len(a) > 1:
        j = [0, max_num_index2(a[1:])[1] + 1]
        return [0, 0] if a[0] > a[j[1]] else j
    elif type(a[0]) == np.ndarray:
        return max_num_index2(a[0])
    else:
        return [0, 0]


answer = '1'
while answer == '1':

    while True:  # Введення числа n, що стане розмірністю масиву з випадкових чисел
        try:
            n = int(input("Введіть розмірність масиву (від 1 до 5):"))
            if 1 <= n <= 5:
                break
            else:
                print("Вводьте правильні дані!")
        except ValueError:
            print("Вводьте правильні дані!")

    array = np.random.randint(0, 50, (n, n))  # array - масив розмірності n з випадкових чисел від 0 до 50

    print(f"Масив з випадкових чисел розмірності {n}*{n} дорівнює:\n{array}\n"
          f"Індекс максимального елемента масиву (визначений через ітерації) дорівнює: {max_num_index1(array)}.\n"
          f"Індекс максимального елемента масиву (визначений через рекурсію) дорівнює: {max_num_index2(array)}.")

    answer = input("Введіть '1' для повторення:")
