"""BTVN, Python3: duyệt tìm kiếm; dữ liệu điểm giả định, chỉ số từ 0.

python3 g11-cs-duyet-tim-kiem.py bang-diem
python3 g11-cs-duyet-tim-kiem.py uoc 20
python3 g11-cs-duyet-tim-kiem.py hoan-hao 30
python3 g11-cs-duyet-tim-kiem.py bo-ba "2 3 4 3 2 7 8 9"
Các hàm điểm nhận bốn dãy cùng độ dài, mỗi chỉ số ứng với cùng bản ghi.
Hàm all_at_least_nine cần dãy điểm Toán B không giảm.
"""
import argparse

NAMES = ['Mẫu A', 'Mẫu B', 'Mẫu C', 'Mẫu D', 'Mẫu E', 'Mẫu F']
MATH = [8.0, 8.5, 8.8, 9.0, 9.2, 9.7]
PHYSICS = [8.3, 8.1, 9.0, 9.1, 8.9, 9.3]
CHEMISTRY = [7.6, 8.7, 8.5, 9.0, 9.4, 9.2]


def first_math_above_physics(names, B, C, D):
    for i in range(len(names)):
        if B[i] > C[i]:
            return names[i]
    return None


def all_physics_above_chemistry(names, B, C, D):
    result = []
    for i in range(len(names)):
        if C[i] > D[i]:
            result.append(names[i])
    return result


def all_at_least_nine(names, B, C, D):
    result = []
    for i in range(len(names) - 1, -1, -1):
        if B[i] < 9:
            break
        if C[i] >= 9 and D[i] >= 9:
            result.append(names[i])
    return result


def first_math_equal(names, B, C, D, target):
    for i in range(len(names)):
        if B[i] == target:
            return names[i]
    return None


def all_total_above(names, B, C, D, threshold):
    result = []
    for i in range(len(names)):
        if B[i] + C[i] + D[i] > threshold:
            result.append(names[i])
    return result


def minimum_total(names, B, C, D):
    if not names:
        return None, None
    best_name = names[0]
    best_score = B[0] + C[0] + D[0]
    for i in range(1, len(names)):
        score = B[i] + C[i] + D[i]
        if score < best_score:
            best_name, best_score = names[i], score
    return best_name, best_score


def top_three(names, B, C, D):
    # Sắp xếp chọn giảm dần trên bản ghi riêng, không đổi bốn dãy gốc.
    records = [(names[i], B[i], C[i], D[i], B[i] + C[i] + D[i])
               for i in range(len(names))]
    for i in range(len(records) - 1):
        best = i
        for j in range(i + 1, len(records)):
            if records[j][4] > records[best][4]:
                best = j
        records[i], records[best] = records[best], records[i]
    return records[:3]


def divisor_count(value):
    count = 0
    for d in range(1, value + 1):
        if value % d == 0:
            count += 1
    return count


def most_divisors_below(N):
    best, best_count = None, 0
    for value in range(1, N):
        count = divisor_count(value)
        if count > best_count:
            best, best_count = value, count
    return best, best_count


def perfect_number(value):
    total = 0
    for d in range(1, value):
        if value % d == 0:
            total += d
    return value > 0 and total == value


def perfect_below(N):
    result = []
    for value in range(1, N):
        if perfect_number(value):
            result.append(value)
    return result


def consecutive_triples(A):
    result = []
    for i in range(len(A) - 2):
        up = A[i + 1] == A[i] + 1 and A[i + 2] == A[i + 1] + 1
        down = A[i + 1] == A[i] - 1 and A[i + 2] == A[i + 1] - 1
        if up or down:
            result.append((i, (A[i], A[i + 1], A[i + 2])))
    return result


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    modes = parser.add_subparsers(dest='mode', required=True)
    modes.add_parser('bang-diem')
    for mode in ['uoc', 'hoan-hao']:
        sub = modes.add_parser(mode)
        sub.add_argument('N', type=int)
    triples = modes.add_parser('bo-ba')
    triples.add_argument('array')
    args = parser.parse_args()
    try:
        if args.mode == 'bang-diem':
            data = (NAMES, MATH, PHYSICS, CHEMISTRY)
            print('Một mẫu có Toán > Vật lí:', first_math_above_physics(*data))
            print('Tất cả mẫu có Vật lí > Hoá học:', all_physics_above_chemistry(*data))
            print('Tất cả mẫu có ba điểm >= 9:', all_at_least_nine(*data))
            print('Một mẫu có Toán = 8.8:', first_math_equal(*data, 8.8))
            print('Tất cả mẫu có tổng > 26.5:', all_total_above(*data, 26.5))
            name, score = minimum_total(*data)
            print('Tổng nhỏ nhất:', (name, round(score, 1)))
            print('Ba tổng cao nhất:', [(x[0], round(x[4], 1)) for x in top_three(*data)])
        elif args.mode in ['uoc', 'hoan-hao']:
            if not 1 <= args.N <= 1000:
                raise ValueError('N từ 1 đến 1000 cho bản thực hành duyệt đơn giản.')
            if args.mode == 'uoc':
                value, count = most_divisors_below(args.N)
                print('Số và số ước:', (value, count))
            else:
                print('Các số hoàn hảo:', perfect_below(args.N))
        else:
            A = [int(x) for x in args.array.split()]
            result = consecutive_triples(A)
            print('Số bộ ba:', len(result))
            print('Chỉ số đầu và bộ ba:', result)
    except ValueError as error:
        parser.exit(2, f'Dữ liệu không phù hợp: {error}\n')


if __name__ == '__main__':
    main()
